Browse Source

"Fix" LLVM boolean bug (more like a bodge)

gingerBill 7 years ago
parent
commit
860a5c3e86
5 changed files with 71 additions and 45 deletions
  1. 4 0
      src/check_type.cpp
  2. 1 1
      src/checker.cpp
  3. 48 20
      src/ir.cpp
  4. 14 24
      src/ir_print.cpp
  5. 4 0
      src/types.cpp

+ 4 - 0
src/check_type.cpp

@@ -1455,6 +1455,10 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) {
 Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
 Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
 	Type *new_type = original_type;
 	Type *new_type = original_type;
 
 
+	if (is_type_boolean(original_type)) {
+		return t_llvm_bool;
+	}
+
 	if (build_context.ODIN_ARCH == "x86") {
 	if (build_context.ODIN_ARCH == "x86") {
 		return new_type;
 		return new_type;
 	}
 	}

+ 1 - 1
src/checker.cpp

@@ -3412,7 +3412,7 @@ void check_parsed_files(Checker *c) {
 	// Add "Basic" type information
 	// Add "Basic" type information
 	for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
 	for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
 		Type *t = &basic_types[i];
 		Type *t = &basic_types[i];
-		if (t->Basic.size > 0) {
+		if (t->Basic.size > 0 && t->Basic.kind != Basic_llvm_bool)  {
 			add_type_info_type(c, t);
 			add_type_info_type(c, t);
 		}
 		}
 	}
 	}

+ 48 - 20
src/ir.cpp

@@ -854,6 +854,8 @@ irValue *ir_value_param(gbAllocator a, irProcedure *parent, Entity *e, Type *abi
 			}
 			}
 		} else if (is_type_integer(abi_type)) {
 		} else if (is_type_integer(abi_type)) {
 			v->Param.kind = irParamPass_Integer;
 			v->Param.kind = irParamPass_Integer;
+		} else if (abi_type == t_llvm_bool) {
+			v->Param.kind = irParamPass_Value;
 		} else {
 		} else {
 			GB_PANIC("Invalid abi type pass kind");
 			GB_PANIC("Invalid abi type pass kind");
 		}
 		}
@@ -911,6 +913,12 @@ irValue *ir_instr_local(irProcedure *p, Entity *e, bool zero_initialized) {
 	return v;
 	return v;
 }
 }
 
 
+irValue *ir_instr_zero_init(irProcedure *p, irValue *address) {
+	irValue *v = ir_alloc_instr(p, irInstr_ZeroInit);
+	irInstr *i = &v->Instr;
+	i->ZeroInit.address = address;
+	return v;
+}
 
 
 irValue *ir_instr_store(irProcedure *p, irValue *address, irValue *value, bool atomic) {
 irValue *ir_instr_store(irProcedure *p, irValue *address, irValue *value, bool atomic) {
 	irValue *v = ir_alloc_instr(p, irInstr_Store);
 	irValue *v = ir_alloc_instr(p, irInstr_Store);
@@ -921,13 +929,6 @@ irValue *ir_instr_store(irProcedure *p, irValue *address, irValue *value, bool a
 	return v;
 	return v;
 }
 }
 
 
-irValue *ir_instr_zero_init(irProcedure *p, irValue *address) {
-	irValue *v = ir_alloc_instr(p, irInstr_ZeroInit);
-	irInstr *i = &v->Instr;
-	i->ZeroInit.address = address;
-	return v;
-}
-
 irValue *ir_instr_load(irProcedure *p, irValue *address) {
 irValue *ir_instr_load(irProcedure *p, irValue *address) {
 	irValue *v = ir_alloc_instr(p, irInstr_Load);
 	irValue *v = ir_alloc_instr(p, irInstr_Load);
 	irInstr *i = &v->Instr;
 	irInstr *i = &v->Instr;
@@ -1040,7 +1041,7 @@ irValue *ir_instr_jump(irProcedure *p, irBlock *block) {
 irValue *ir_instr_if(irProcedure *p, irValue *cond, irBlock *true_block, irBlock *false_block) {
 irValue *ir_instr_if(irProcedure *p, irValue *cond, irBlock *true_block, irBlock *false_block) {
 	irValue *v = ir_alloc_instr(p, irInstr_If);
 	irValue *v = ir_alloc_instr(p, irInstr_If);
 	irInstr *i = &v->Instr;
 	irInstr *i = &v->Instr;
-	i->If.cond = cond;
+	i->If.cond = ir_emit_conv(p, cond, t_llvm_bool);
 	i->If.true_block = true_block;
 	i->If.true_block = true_block;
 	i->If.false_block = false_block;
 	i->If.false_block = false_block;
 	return v;
 	return v;
@@ -1447,8 +1448,12 @@ irValue *ir_add_param(irProcedure *proc, Entity *e, AstNode *expr, Type *abi_typ
 	switch (p->kind) {
 	switch (p->kind) {
 	case irParamPass_Value: {
 	case irParamPass_Value: {
 		irValue *l = ir_add_local(proc, e, expr, false);
 		irValue *l = ir_add_local(proc, e, expr, false);
-		ir_emit_store(proc, l, v);
-		return v;
+		irValue *x = v;
+		if (abi_type == t_llvm_bool) {
+			x = ir_emit_conv(proc, x, t_bool);
+		}
+		ir_emit_store(proc, l, x);
+		return x;
 	}
 	}
 	case irParamPass_Pointer:
 	case irParamPass_Pointer:
 		ir_module_add_value(proc->module, e, v);
 		ir_module_add_value(proc->module, e, v);
@@ -1534,29 +1539,41 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
 //
 //
 ////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////
 
 
-
+irValue *ir_emit_global_call(irProcedure *proc, char const *name_, irValue **args, isize arg_count);
 
 
 irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
 irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
-#if 1
 	// NOTE(bill): Sanity check
 	// NOTE(bill): Sanity check
 	Type *a = type_deref(ir_type(address));
 	Type *a = type_deref(ir_type(address));
 	Type *b = ir_type(value);
 	Type *b = ir_type(value);
 	if (!is_type_untyped(b)) {
 	if (!is_type_untyped(b)) {
 		GB_ASSERT_MSG(are_types_identical(core_type(a), core_type(b)), "%s %s", type_to_string(a), type_to_string(b));
 		GB_ASSERT_MSG(are_types_identical(core_type(a), core_type(b)), "%s %s", type_to_string(a), type_to_string(b));
 	}
 	}
-#endif
+
+	// if (is_type_boolean(a)) {
+		// return ir_emit(p, ir_instr_store_bool(p, address, value, false));
+	// }
 	return ir_emit(p, ir_instr_store(p, address, value, false));
 	return ir_emit(p, ir_instr_store(p, address, value, false));
 }
 }
 irValue *ir_emit_load(irProcedure *p, irValue *address) {
 irValue *ir_emit_load(irProcedure *p, irValue *address) {
 	GB_ASSERT(address != nullptr);
 	GB_ASSERT(address != nullptr);
+	Type *t = type_deref(ir_type(address));
+	// if (is_type_boolean(t)) {
+		// return ir_emit(p, ir_instr_load_bool(p, address));
+	// }
 	return ir_emit(p, ir_instr_load(p, address));
 	return ir_emit(p, ir_instr_load(p, address));
 }
 }
 irValue *ir_emit_select(irProcedure *p, irValue *cond, irValue *t, irValue *f) {
 irValue *ir_emit_select(irProcedure *p, irValue *cond, irValue *t, irValue *f) {
 	return ir_emit(p, ir_instr_select(p, cond, t, f));
 	return ir_emit(p, ir_instr_select(p, cond, t, f));
 }
 }
 
 
-irValue *ir_emit_zero_init(irProcedure *p, irValue *address)  {
-	return ir_emit(p, ir_instr_zero_init(p, address));
+irValue *ir_emit_zero_init(irProcedure *p, irValue *address) {
+	gbAllocator a = p->module->allocator;
+	Type *t = type_deref(ir_type(address));
+	irValue **args = gb_alloc_array(a, irValue *, 2);
+	args[0] = ir_emit_conv(p, address, t_rawptr);
+	args[1] = ir_const_int(a, type_size_of(a, t));
+	return ir_emit_global_call(p, "__mem_zero", args, 2);
+	// return ir_emit(p, ir_instr_zero_init(p, address));
 }
 }
 
 
 irValue *ir_emit_comment(irProcedure *p, String text) {
 irValue *ir_emit_comment(irProcedure *p, String text) {
@@ -1626,6 +1643,8 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, irValue **args, isize arg_
 				}
 				}
 			} else if (is_type_integer(new_type)) {
 			} else if (is_type_integer(new_type)) {
 				args[i] = ir_emit_transmute(p, args[i], new_type);
 				args[i] = ir_emit_transmute(p, args[i], new_type);
+			} else if (new_type == t_llvm_bool) {
+				args[i] = ir_emit_conv(p, args[i], new_type);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -2446,7 +2465,6 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
 		}
 		}
 	}
 	}
 
 
-	Type *result = t_bool;
 	if (is_type_array(a)) {
 	if (is_type_array(a)) {
 		ir_emit_comment(proc, str_lit("array.comp.begin"));
 		ir_emit_comment(proc, str_lit("array.comp.begin"));
 		defer (ir_emit_comment(proc, str_lit("array.comp.end")));
 		defer (ir_emit_comment(proc, str_lit("array.comp.end")));
@@ -2468,10 +2486,10 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
 			irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i));
 			irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i));
 			irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i));
 			irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i));
 			irValue *cmp = ir_emit_comp(proc, op_kind, x, y);
 			irValue *cmp = ir_emit_comp(proc, op_kind, x, y);
-			res = ir_emit_arith(proc, cmp_op, res, cmp, result);
+			res = ir_emit_arith(proc, cmp_op, res, cmp, t_bool);
 		}
 		}
 
 
-		return ir_emit_conv(proc, res, result);
+		return ir_emit_conv(proc, res, t_bool);
 	}
 	}
 
 
 	if (is_type_string(a)) {
 	if (is_type_string(a)) {
@@ -2518,7 +2536,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
 	}
 	}
 
 
 
 
-	return ir_emit(proc, ir_instr_binary_op(proc, op_kind, left, right, result));
+	return ir_emit(proc, ir_instr_binary_op(proc, op_kind, left, right, t_llvm_bool));
 }
 }
 
 
 irValue *ir_emit_array_ep(irProcedure *proc, irValue *s, irValue *index) {
 irValue *ir_emit_array_ep(irProcedure *proc, irValue *s, irValue *index) {
@@ -3036,6 +3054,14 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
 		return ir_emit(proc, ir_instr_conv(proc, kind, value, src_type, t));
 		return ir_emit(proc, ir_instr_conv(proc, kind, value, src_type, t));
 	}
 	}
 
 
+	// bool <-> llvm bool
+	if (is_type_boolean(src) && dst == t_llvm_bool) {
+		return ir_emit(proc, ir_instr_conv(proc, irConv_trunc, value, src_type, t));
+	}
+	if (src == t_llvm_bool && is_type_boolean(dst)) {
+		return ir_emit(proc, ir_instr_conv(proc, irConv_zext, value, src_type, t));
+	}
+
 	// boolean -> integer
 	// boolean -> integer
 	if (is_type_boolean(src) && is_type_integer(dst)) {
 	if (is_type_boolean(src) && is_type_integer(dst)) {
 		return ir_emit(proc, ir_instr_conv(proc, irConv_zext, value, src_type, t));
 		return ir_emit(proc, ir_instr_conv(proc, irConv_zext, value, src_type, t));
@@ -8195,7 +8221,9 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
 			irValue *ptr = ir_emit_union_tag_ptr(proc, variant_ptr);
 			irValue *ptr = ir_emit_union_tag_ptr(proc, variant_ptr);
 			ir_emit_store(proc, ptr, tag);
 			ir_emit_store(proc, ptr, tag);
 		} else {
 		} else {
-			GB_PANIC("Unhandled Type_Info variant: %s", type_to_string(t));
+			if (t != t_llvm_bool) {
+				GB_PANIC("Unhandled Type_Info variant: %s", type_to_string(t));
+			}
 		}
 		}
 	}
 	}
 }
 }

+ 14 - 24
src/ir_print.cpp

@@ -193,7 +193,7 @@ void ir_print_encoded_global(irFileBuffer *f, String name, bool remove_prefix) {
 	ir_print_escape_string(f, name, true, !remove_prefix);
 	ir_print_escape_string(f, name, true, !remove_prefix);
 }
 }
 
 
-void ir_print_type(irFileBuffer *f, irModule *m, Type *t);
+void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct = false);
 void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hint);
 void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hint);
 
 
 
 
@@ -260,7 +260,7 @@ void ir_print_proc_type_without_pointer(irFileBuffer *f, irModule *m, Type *t) {
 	ir_write_byte(f, ')');
 	ir_write_byte(f, ')');
 }
 }
 
 
-void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
+void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
 	i64 word_bits = 8*build_context.word_size;
 	i64 word_bits = 8*build_context.word_size;
 	GB_ASSERT_NOT_NULL(t);
 	GB_ASSERT_NOT_NULL(t);
 	t = default_type(t);
 	t = default_type(t);
@@ -269,7 +269,9 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 	switch (t->kind) {
 	switch (t->kind) {
 	case Type_Basic:
 	case Type_Basic:
 		switch (t->Basic.kind) {
 		switch (t->Basic.kind) {
-		case Basic_bool:   ir_write_string(f, "i1");                   return;
+		case Basic_bool:      ir_write_string(f, "i8"); return;
+		case Basic_llvm_bool: ir_write_string(f, "i1"); return;
+
 		case Basic_i8:     ir_write_string(f, "i8");                   return;
 		case Basic_i8:     ir_write_string(f, "i8");                   return;
 		case Basic_u8:     ir_write_string(f, "i8");                   return;
 		case Basic_u8:     ir_write_string(f, "i8");                   return;
 		case Basic_i16:    ir_write_string(f, "i16");                  return;
 		case Basic_i16:    ir_write_string(f, "i16");                  return;
@@ -370,7 +372,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 				if (i > 0) {
 				if (i > 0) {
 					ir_write_string(f, str_lit(", "));
 					ir_write_string(f, str_lit(", "));
 				}
 				}
-				ir_print_type(f, m, t->Struct.fields[i]->type);
+				ir_print_type(f, m, t->Struct.fields[i]->type, true);
 			}
 			}
 			ir_write_byte(f, '}');
 			ir_write_byte(f, '}');
 			if (t->Struct.is_packed) {
 			if (t->Struct.is_packed) {
@@ -487,9 +489,9 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
 	switch (value.kind) {
 	switch (value.kind) {
 	case ExactValue_Bool:
 	case ExactValue_Bool:
 		if (value.value_bool) {
 		if (value.value_bool) {
-			ir_write_string(f, "true");
+			ir_write_string(f, type == t_llvm_bool ? "true" : "1");
 		} else {
 		} else {
-			ir_write_string(f, "false");
+			ir_write_string(f, type == t_llvm_bool ? "false" : "0");
 		}
 		}
 		break;
 		break;
 	case ExactValue_String: {
 	case ExactValue_String: {
@@ -975,7 +977,6 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 		ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type));
 		ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type));
 		break;
 		break;
 	}
 	}
-
 	case irInstr_ArrayElementPtr: {
 	case irInstr_ArrayElementPtr: {
 		Type *et = ir_type(instr->ArrayElementPtr.address);
 		Type *et = ir_type(instr->ArrayElementPtr.address);
 		ir_fprintf(f, "%%%d = getelementptr inbounds ", value->index);
 		ir_fprintf(f, "%%%d = getelementptr inbounds ", value->index);
@@ -1108,13 +1109,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 		ir_print_type(f, m, t_int);
 		ir_print_type(f, m, t_int);
 		ir_write_string(f, " 0, ");
 		ir_write_string(f, " 0, ");
 		ir_print_type(f, m, t_i32);
 		ir_print_type(f, m, t_i32);
-	#if 1
-		ir_fprintf(f, " 2");
-	#else
-		ir_fprintf(f, " %d", 2);
-	#endif
-		ir_write_string(f, " ; UnionTagPtr");
-		ir_write_byte(f, '\n');
+		ir_fprintf(f, " 2 ; UnionTagPtr\n");
 		break;
 		break;
 	}
 	}
 
 
@@ -1127,14 +1122,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 		ir_print_type(f, m, et);
 		ir_print_type(f, m, et);
 		ir_write_byte(f, ' ');
 		ir_write_byte(f, ' ');
 		ir_print_value(f, m, instr->UnionTagValue.address, et);
 		ir_print_value(f, m, instr->UnionTagValue.address, et);
-		ir_write_byte(f, ',');
-	#if 1
-		ir_fprintf(f, " 2");
-	#else
-		ir_fprintf(f, " %d", 2);
-	#endif
-		ir_write_string(f, " ; UnionTagValue");
-		ir_write_byte(f, '\n');
+		ir_fprintf(f, ", 2 ; UnionTagValue\n");
 		break;
 		break;
 	}
 	}
 
 
@@ -1146,8 +1134,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 	}
 	}
 
 
 	case irInstr_If: {;
 	case irInstr_If: {;
-		ir_write_string(f, "br ");
-		ir_print_type(f, m, t_bool);
+		ir_write_string(f, "br i1");
 		ir_write_byte(f, ' ');
 		ir_write_byte(f, ' ');
 		ir_print_value(f, m, instr->If.cond, t_bool);
 		ir_print_value(f, m, instr->If.cond, t_bool);
 		ir_write_string(f, ", ");
 		ir_write_string(f, ", ");
@@ -1381,6 +1368,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
 					}
 					}
 					ir_write_byte(f, ' ');
 					ir_write_byte(f, ' ');
 					irValue *arg = call->args[i];
 					irValue *arg = call->args[i];
+					if (is_type_boolean(t)) {
+
+					}
 					ir_print_value(f, m, arg, t);
 					ir_print_value(f, m, arg, t);
 					param_index++;
 					param_index++;
 				}
 				}

+ 4 - 0
src/types.cpp

@@ -4,6 +4,7 @@ struct AstNode;
 enum BasicKind {
 enum BasicKind {
 	Basic_Invalid,
 	Basic_Invalid,
 
 
+	Basic_llvm_bool,
 	Basic_bool,
 	Basic_bool,
 	Basic_i8,
 	Basic_i8,
 	Basic_u8,
 	Basic_u8,
@@ -236,6 +237,8 @@ void selection_add_index(Selection *s, isize index) {
 gb_global Type basic_types[] = {
 gb_global Type basic_types[] = {
 	{Type_Basic, {Basic_Invalid,           0,                                          0, STR_LIT("invalid type")}},
 	{Type_Basic, {Basic_Invalid,           0,                                          0, STR_LIT("invalid type")}},
 
 
+	{Type_Basic, {Basic_llvm_bool,         BasicFlag_Boolean,                          1, STR_LIT("llvm bool")}},
+
 	{Type_Basic, {Basic_bool,              BasicFlag_Boolean,                          1, STR_LIT("bool")}},
 	{Type_Basic, {Basic_bool,              BasicFlag_Boolean,                          1, STR_LIT("bool")}},
 
 
 	{Type_Basic, {Basic_i8,                BasicFlag_Integer,                          1, STR_LIT("i8")}},
 	{Type_Basic, {Basic_i8,                BasicFlag_Integer,                          1, STR_LIT("i8")}},
@@ -283,6 +286,7 @@ gb_global Type basic_types[] = {
 // };
 // };
 
 
 gb_global Type *t_invalid         = &basic_types[Basic_Invalid];
 gb_global Type *t_invalid         = &basic_types[Basic_Invalid];
+gb_global Type *t_llvm_bool       = &basic_types[Basic_llvm_bool];
 gb_global Type *t_bool            = &basic_types[Basic_bool];
 gb_global Type *t_bool            = &basic_types[Basic_bool];
 gb_global Type *t_i8              = &basic_types[Basic_i8];
 gb_global Type *t_i8              = &basic_types[Basic_i8];
 gb_global Type *t_u8              = &basic_types[Basic_u8];
 gb_global Type *t_u8              = &basic_types[Basic_u8];