authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-10 23:51:09-07:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-12 11:18:23+01:00
logb92e1ab8ccf4e450467dfd5ee8ff9ea87c148c26
tree6e27ee72e9bd0746c41dfd1e1e92a54974c329ad
parentd72f832b1ebab0db106e64bc9f59eba90c414311

stage1: override f80 alignment for i386-windows

Comment reproduced here: Note the following u64 alignments: x86-linux: 4 x86-windows: 8 LLVM makes x86_fp80 have the following alignment and sizes regardless of operating system: x86_64: size=16, align=16 x86: size=12, align=4 However in Zig we override x86-windows to have size=16, align=16 in order for the property to hold that u80 and f80 have the same ABI size. Fixes "error: destination type 'f80' has size 12 but source type 'u80' has size 16" when trying to bitcast between f80 and u80 on i386-windows.

1 files changed, 29 insertions(+), 18 deletions(-)

src/stage1/codegen.cpp+29-18
...@@ -9432,29 +9432,40 @@ static void define_builtin_types(CodeGen *g) {...@@ -9432,29 +9432,40 @@ static void define_builtin_types(CodeGen *g) {
9432 buf_init_from_str(&entry->name, "f80");9432 buf_init_from_str(&entry->name, "f80");
9433 entry->data.floating.bit_count = 80;9433 entry->data.floating.bit_count = 80;
94349434
9435 switch (g->zig_target->arch) {9435 if (target_has_f80(g->zig_target)) {
9436 case ZigLLVM_x86_64:9436 entry->llvm_type = LLVMX86FP80Type();
9437 entry->llvm_type = LLVMX86FP80Type();9437
9438 // Note the following u64 alignments:
9439 // x86-linux: 4
9440 // x86-windows: 8
9441 // LLVM makes x86_fp80 have the following alignment and sizes regardless
9442 // of operating system:
9443 // x86_64: size=16, align=16
9444 // x86: size=12, align=4
9445 // However in Zig we override x86-windows to have size=16, align=16
9446 // in order for the property to hold that u80 and f80 have the same ABI size.
9447 unsigned u64_alignment = LLVMABIAlignmentOfType(g->target_data_ref, LLVMInt64Type());
9448
9449 if (u64_alignment >= 8) {
9438 entry->abi_size = 16;9450 entry->abi_size = 16;
9439 entry->abi_align = 16;9451 entry->abi_align = 16;
9440 break;9452 } else if (u64_alignment >= 4) {
9441 case ZigLLVM_x86:
9442 entry->llvm_type = LLVMX86FP80Type();
9443 entry->abi_size = 12;9453 entry->abi_size = 12;
9444 entry->abi_align = 4;9454 entry->abi_align = 4;
9445 break;9455 } else {
9446 default: {9456 entry->abi_size = 10;
9447 // We use an int here instead of x86_fp80 because on targets such as arm,9457 entry->abi_align = u64_alignment;
9448 // LLVM will give "ERROR: Cannot select" for any instructions involving
9449 // the x86_fp80 type.
9450 ZigType *u80_ty = get_int_type(g, false, 80);
9451 assert(!target_has_f80(g->zig_target));
9452 assert(u80_ty->size_in_bits == entry->size_in_bits);
9453 entry->llvm_type = get_llvm_type(g, u80_ty);
9454 entry->abi_size = u80_ty->abi_size;
9455 entry->abi_align = u80_ty->abi_align;
9456 break;
9457 }9458 }
9459 } else {
9460 // We use an int here instead of x86_fp80 because on targets such as arm,
9461 // LLVM will give "ERROR: Cannot select" for any instructions involving
9462 // the x86_fp80 type.
9463 ZigType *u80_ty = get_int_type(g, false, 80);
9464 assert(!target_has_f80(g->zig_target));
9465 assert(u80_ty->size_in_bits == entry->size_in_bits);
9466 entry->llvm_type = get_llvm_type(g, u80_ty);
9467 entry->abi_size = u80_ty->abi_size;
9468 entry->abi_align = u80_ty->abi_align;
9458 }9469 }
94599470
9460 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),9471 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),