Added some explicit casts. Added sret at call site.

This commit is contained in:
Christoffer Lerno
2021-07-29 16:42:20 +02:00
parent efe4f8c745
commit ec612eea67
11 changed files with 94 additions and 11 deletions

View File

@@ -572,7 +572,7 @@ ArchOsTarget arch_os_target_from_string(const char *target)
{
if (strcasecmp(arch_os_target[i], target) == 0)
{
return i;
return (ArchOsTarget)i;
}
}
return ARCH_OS_TARGET_DEFAULT;

View File

@@ -1752,8 +1752,8 @@ static inline TokenData *tokendata_from_token(Token token) { return tokdataptr(t
#define TOKREAL(T) TOKDATA(T)->value
static inline TokenType tokenid_type(TokenId token) { return toktypeptr(token.index)[0]; }
static inline TokenType token_type(Token token) { return toktypeptr(token.id.index)[0]; }
static inline TokenType tokenid_type(TokenId token) { return (TokenType)toktypeptr(token.index)[0]; }
static inline TokenType token_type(Token token) { return (TokenType)toktypeptr(token.id.index)[0]; }
#define TOKTYPE(T) _Generic((T), TokenId: tokenid_type, Token: token_type)(T)
#define TOKLEN(T) TOKLOC(T)->length

View File

@@ -271,7 +271,7 @@ static void skip_whitespace(Lexer *lexer, LexMode lex_type)
// we split identifiers into 2 types + find keywords.
static inline bool scan_ident(Lexer *lexer, TokenType normal, TokenType const_token, TokenType type_token, char prefix)
{
TokenType type = 0;
TokenType type = (TokenType)0;
uint32_t hash = FNV1_SEED;
if (prefix)
{
@@ -414,7 +414,6 @@ static inline bool scan_hex(Lexer *lexer)
char c = peek(lexer);
if (c == 'p' || c == 'P')
{
is_float = true;
is_float = true;
if (!scan_exponent(lexer)) return false;
}

View File

@@ -1039,6 +1039,12 @@ void llvm_attribute_add(GenContext *context, LLVMValueRef value_to_add_attribute
llvm_attribute_add_int(context, value_to_add_attribute_to, attribute_id, 0, index);
}
void llvm_attribute_add_call(GenContext *context, LLVMValueRef call, unsigned attribute_id, int index, int64_t value)
{
LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(context->context, attribute_id, value);
LLVMAddCallSiteAttribute(call, index, llvm_attr);
}
void llvm_attribute_add_range(GenContext *context, LLVMValueRef value_to_add_attribute_to, unsigned attribute_id, int index_start, int index_end)
{
for (int i = index_start; i <= index_end; i++)

View File

@@ -2712,6 +2712,7 @@ static void llvm_emit_unpacked_variadic_arg(GenContext *c, Expr *expr, BEValue *
UNREACHABLE
}
}
void llvm_emit_call_expr(GenContext *c, BEValue *be_value, Expr *expr)
{
Expr *function = expr->call_expr.function;
@@ -2791,7 +2792,7 @@ void llvm_emit_call_expr(GenContext *c, BEValue *be_value, Expr *expr)
{
case ABI_ARG_INDIRECT:
// 6a. We can use the stored error var if there is no redirect.
if (signature->failable && c->error_var && ret_info->attributes.realign)
if (signature->failable && c->error_var && !ret_info->attributes.realign)
{
error_var = c->error_var;
vec_add(values, error_var);
@@ -2931,7 +2932,8 @@ void llvm_emit_call_expr(GenContext *c, BEValue *be_value, Expr *expr)
*be_value = (BEValue) { .type = type_void, .kind = BE_VALUE };
return;
case ABI_ARG_INDIRECT:
llvm_attribute_add_call(c, call_value, attribute_sret, 1, 0);
llvm_attribute_add_call(c, call_value, attribute_align, 1, ret_info->indirect.alignment);
// 13. Indirect, that is passing the result through an out parameter.
// 13a. In the case of an already present error_var, we don't need to do a load here.

View File

@@ -203,6 +203,7 @@ unsigned llvm_abi_size(GenContext *c, LLVMTypeRef type);
AlignSize llvm_abi_alignment(GenContext *c, LLVMTypeRef type);
void llvm_attribute_add_range(GenContext *c, LLVMValueRef value_to_add_attribute_to, unsigned attribute_id, int index_start, int index_end);
void llvm_attribute_add(GenContext *c, LLVMValueRef value_to_add_attribute_to, unsigned attribute_id, int index);
void llvm_attribute_add_call(GenContext *context, LLVMValueRef call, unsigned attribute_id, int index, int64_t value);
void llvm_attribute_add_string(GenContext *c, LLVMValueRef value_to_add_attribute_to, const char *attribute, const char *value, int index);
void llvm_attribute_add_int(GenContext *c, LLVMValueRef value_to_add_attribute_to, unsigned attribute_id, uint64_t val, int index);
LLVMBasicBlockRef llvm_basic_block_new(GenContext *c, const char *name);

View File

@@ -337,7 +337,6 @@ Type *type_by_expr_range(ExprConst *expr)
return type_double;
}
assert(expr->kind == TYPE_IXX);
BigInt *b = &expr->i;
// 1. Does it fit in a C int? If so, that's the type.
Type *type = type_cint();
if (!expr_const_will_overflow(expr, type->type_kind)) return type;

View File

@@ -1260,7 +1260,7 @@ static bool sema_analyse_parameterized_define(Context *c, Decl *decl)
if (define_type->resolve_status == RESOLVE_DONE && type_is_user_defined(define_type->type))
{
SEMA_ERROR(define_type, "Expected a user defined type for parameterization.");
return poisoned_decl;
return decl_poison(decl);
}
decl_path = define_type->unresolved.path;
name = define_type->unresolved.name_loc;
@@ -1291,7 +1291,7 @@ static bool sema_analyse_parameterized_define(Context *c, Decl *decl)
VECEACH(decl->define_decl.generic_params, i)
{
TypeInfo *type_info = decl->define_decl.generic_params[i];
if (!sema_resolve_type_info(c, type_info)) return poisoned_decl;
if (!sema_resolve_type_info(c, type_info)) return decl_poison(decl);
if (i != 0) scratch_buffer_append_char('.');
const char *type_name = type_info->type->canonical->name;
scratch_buffer_append(type_name);

View File

@@ -547,7 +547,7 @@ static inline bool sema_expr_analyse_identifier(Context *context, Type *to, Expr
}
if (decl->resolve_status != RESOLVE_DONE)
{
if (!sema_analyse_decl(context, decl)) return poisoned_decl;
if (!sema_analyse_decl(context, decl)) return decl_poison(decl);
}
if (decl->decl_kind == DECL_VAR && decl->var.failable)
{

View File

@@ -0,0 +1,37 @@
// #target: aarch64_linux
module pass_large;
struct Large
{
void*[8] pointers;
}
extern func void pass_large(Large large);
func void example()
{
Large l = {};
pass_large(l);
pass_large(l);
}
// #expect: pass_large.ll
define void @pass_large.example()
entry:
%l = alloca %Large, align 8
%indirectarg = alloca %Large, align 8
%indirectarg1 = alloca %Large, align 8
%0 = bitcast %Large* %l to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 64, i1 false)
%1 = bitcast %Large* %indirectarg to i8*
%2 = bitcast %Large* %l to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %1, i8* align 8 %2, i32 64, i1 false)
call void @pass_large(%Large* %indirectarg)
%3 = bitcast %Large* %indirectarg1 to i8*
%4 = bitcast %Large* %l to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %3, i8* align 8 %4, i32 64, i1 false)
call void @pass_large(%Large* %indirectarg1)
ret void

View File

@@ -0,0 +1,39 @@
// #target: x64_darwin
struct Abc {
long a;
long b;
long c;
long d;
long e;
}
extern func Abc foo1();
extern func Abc foo2();
func void bar() {
Abc dummy1 = foo1();
Abc dummy2 = foo2();
}
// Cleanup for this result, since it's creating an unnecessary sret.
// #expect: test_sret.ll
declare void @foo1(%Abc* sret align 8)
declare void @foo2(%Abc* sret align 8)
%dummy1 = alloca %Abc, align 8
%sretparam = alloca %Abc, align 8
%dummy2 = alloca %Abc, align 8
%sretparam1 = alloca %Abc, align 8
call void @foo1(%Abc* sret align 8 %sretparam)
%0 = bitcast %Abc* %dummy1 to i8*
%1 = bitcast %Abc* %sretparam to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %0, i8* align 8 %1, i32 40, i1 false)
call void @foo2(%Abc* sret align 8 %sretparam1)
%2 = bitcast %Abc* %dummy2 to i8*
%3 = bitcast %Abc* %sretparam1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %2, i8* align 8 %3, i32 40, i1 false)
ret void