Fix LLVM code gen bug

This commit is contained in:
gingerBill
2020-06-22 16:57:21 +01:00
parent 0db1ebb4e5
commit 2b27300387
5 changed files with 40 additions and 20 deletions
+1 -1
View File
@@ -426,7 +426,7 @@ typeid_base_without_enum :: typeid_core;
@(default_calling_convention = "c")
@(default_calling_convention = "none")
foreign {
@(link_name="llvm.assume")
assume :: proc(cond: bool) ---;
+2 -2
View File
@@ -58,7 +58,7 @@ ExprKind check_expr_base (CheckerContext *c, Operand *operand, As
void check_expr_with_type_hint (CheckerContext *c, Operand *o, Ast *e, Type *t);
Type * check_type (CheckerContext *c, Ast *expression);
Type * check_type_expr (CheckerContext *c, Ast *expression, Type *named_type);
Type * make_optional_ok_type (Type *value);
Type * make_optional_ok_type (Type *value, bool typed=true);
void check_type_decl (CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint);
Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name);
@@ -5532,7 +5532,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
check_assignment(c, &y, elem, builtin_name);
operand->mode = Addressing_Value;
operand->type = make_optional_ok_type(elem);
operand->type = make_optional_ok_type(elem, /*typed*/false);
break;
}
break;
+1 -2
View File
@@ -2683,10 +2683,9 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) {
return 0;
}
Type *make_optional_ok_type(Type *value) {
Type *make_optional_ok_type(Type *value, bool typed) {
// LEAK TODO(bill): probably don't reallocate everything here and reuse the same one for the same type if possible
gbAllocator a = heap_allocator();
bool typed = true;
Type *t = alloc_type_tuple();
array_init(&t->Tuple.variables, a, 0, 2);
array_add (&t->Tuple.variables, alloc_entity_field(nullptr, blank_token, value, false, 0));
+17 -7
View File
@@ -976,9 +976,14 @@ irValue *ir_value_param(irProcedure *parent, Entity *e, Type *abi_type, i32 inde
if (e != nullptr && abi_type != e->type) {
if (is_type_pointer(abi_type)) {
GB_ASSERT(e->kind == Entity_Variable);
v->Param.kind = irParamPass_Pointer;
if (e->flags&EntityFlag_Value) {
v->Param.kind = irParamPass_ConstRef;
Type *av = type_deref(abi_type);
if (are_types_identical(abi_type, e->type)) {
v->Param.kind = irParamPass_Pointer;
if (e->flags&EntityFlag_Value) {
v->Param.kind = irParamPass_ConstRef;
}
} else {
v->Param.kind = irParamPass_BitCast;
}
} else if (is_type_integer(abi_type)) {
v->Param.kind = irParamPass_Integer;
@@ -3241,10 +3246,15 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array<irValue *> const &ar
array_add(&processed_args, args[i]);
} else if (!are_types_identical(original_type, new_type)) {
if (is_type_pointer(new_type) && !is_type_pointer(original_type)) {
if (e->flags&EntityFlag_ImplicitReference) {
array_add(&processed_args, ir_address_from_load_or_generate_local(p, args[i]));
} else if (!is_type_pointer(arg_type)) {
array_add(&processed_args, ir_copy_value_to_ptr(p, args[i], original_type, 16));
Type *av = type_deref(new_type);
if (are_types_identical(av, original_type)) {
if (e->flags&EntityFlag_ImplicitReference) {
array_add(&processed_args, ir_address_from_load_or_generate_local(p, args[i]));
} else if (!is_type_pointer(arg_type)) {
array_add(&processed_args, ir_copy_value_to_ptr(p, args[i], original_type, 16));
}
} else {
array_add(&processed_args, ir_emit_transmute(p, args[i], new_type));
}
} else if (is_type_integer(new_type) || is_type_float(new_type)) {
array_add(&processed_args, ir_emit_transmute(p, args[i], new_type));
+19 -8
View File
@@ -2270,12 +2270,17 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type
lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
lbParamPasskind kind = lbParamPass_Value;
if (e != nullptr && abi_type != e->type) {
if (e != nullptr && !are_types_identical(abi_type, e->type)) {
if (is_type_pointer(abi_type)) {
GB_ASSERT(e->kind == Entity_Variable);
kind = lbParamPass_Pointer;
if (e->flags&EntityFlag_Value) {
kind = lbParamPass_ConstRef;
Type *av = type_deref(abi_type);
if (are_types_identical(av, e->type)) {
kind = lbParamPass_Pointer;
if (e->flags&EntityFlag_Value) {
kind = lbParamPass_ConstRef;
}
} else {
kind = lbParamPass_BitCast;
}
} else if (is_type_integer(abi_type)) {
kind = lbParamPass_Integer;
@@ -2364,6 +2369,7 @@ lbValue lb_add_param(lbProcedure *p, Entity *e, Ast *expr, Type *abi_type, i32 i
}
GB_PANIC("Unreachable");
return {};
}
@@ -7035,10 +7041,15 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args,
array_add(&processed_args, args[i]);
} else if (!are_types_identical(original_type, new_type)) {
if (is_type_pointer(new_type) && !is_type_pointer(original_type)) {
if (e->flags&EntityFlag_ImplicitReference) {
array_add(&processed_args, lb_address_from_load_or_generate_local(p, args[i]));
} else if (!is_type_pointer(arg_type)) {
array_add(&processed_args, lb_copy_value_to_ptr(p, args[i], original_type, 16));
Type *av = type_deref(new_type);
if (are_types_identical(av, arg_type)) {
if (e->flags&EntityFlag_ImplicitReference) {
array_add(&processed_args, lb_address_from_load_or_generate_local(p, args[i]));
} else if (!is_type_pointer(arg_type)) {
array_add(&processed_args, lb_copy_value_to_ptr(p, args[i], original_type, 16));
}
} else {
array_add(&processed_args, lb_emit_transmute(p, args[i], new_type));
}
} else if (new_type == t_llvm_bool) {
array_add(&processed_args, lb_emit_conv(p, args[i], new_type));