authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-02-15 20:22:01+07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-17 14:46:04+02:00
log755d116ecf2d221e2ad8b572c58a7d4f99163ff9
tree91cd4f2689e323750c0f539bfb60777afcd3e3c4
parent02902cc099d9736d589ac4f0e0ff671d7dfa9557

stage1: use u16 for __truncxfhf2/__extendhfxf2 on non-Arm CPUs

Non-Arm CPUs use u16 as the parameter to __extendhfxf2 and the return value of __truncxfhf2, so insert appropriate bitcasts in gen_soft_f80_widen_or_shorten. Otherwise, LLVM might crash because the functions are called in a different way than its compiler-rt definition. This fixes stage1 build on SPARCv9, and possibly other non-x86, non-Arm CPUs.

1 files changed, 28 insertions(+), 4 deletions(-)

src/stage1/codegen.cpp+28-4
......@@ -1620,13 +1620,23 @@ static LLVMValueRef gen_soft_f80_widen_or_shorten(CodeGen *g, ZigType *actual_ty
16201620 LLVMTypeRef return_type;
16211621 const char *func_name;
16221622
1623 LLVMValueRef result;
1624 bool castTruncatedToF16 = false;
1625
16231626 if (actual_bits == wanted_bits) {
16241627 return expr_val;
16251628 } else if (actual_bits == 80) {
16261629 param_type = g->builtin_types.entry_f80->llvm_type;
16271630 switch (wanted_bits) {
16281631 case 16:
1629 return_type = g->builtin_types.entry_f16->llvm_type;
1632 // Only Arm has a native f16 type, other platforms soft-implement it
1633 // using u16 instead.
1634 if (target_is_arm(g->zig_target)) {
1635 return_type = g->builtin_types.entry_f16->llvm_type;
1636 } else {
1637 return_type = g->builtin_types.entry_u16->llvm_type;
1638 castTruncatedToF16 = true;
1639 }
16301640 func_name = "__truncxfhf2";
16311641 break;
16321642 case 32:
......@@ -1648,7 +1658,14 @@ static LLVMValueRef gen_soft_f80_widen_or_shorten(CodeGen *g, ZigType *actual_ty
16481658 return_type = g->builtin_types.entry_f80->llvm_type;
16491659 switch (actual_bits) {
16501660 case 16:
1651 param_type = g->builtin_types.entry_f16->llvm_type;
1661 // Only Arm has a native f16 type, other platforms soft-implement it
1662 // using u16 instead.
1663 if (target_is_arm(g->zig_target)) {
1664 param_type = g->builtin_types.entry_f16->llvm_type;
1665 } else {
1666 param_type = g->builtin_types.entry_u16->llvm_type;
1667 expr_val = LLVMBuildBitCast(g->builder, expr_val, param_type, "");
1668 }
16521669 func_name = "__extendhfxf2";
16531670 break;
16541671 case 32:
......@@ -1676,7 +1693,14 @@ static LLVMValueRef gen_soft_f80_widen_or_shorten(CodeGen *g, ZigType *actual_ty
16761693 func_ref = LLVMAddFunction(g->module, func_name, fn_type);
16771694 }
16781695
1679 return LLVMBuildCall(g->builder, func_ref, &expr_val, 1, "");
1696 result = LLVMBuildCall(g->builder, func_ref, &expr_val, 1, "");
1697
1698 // On non-Arm platforms we need to bitcast __truncxfhf2 result back to f16
1699 if (castTruncatedToF16) {
1700 result = LLVMBuildBitCast(g->builder, result, g->builtin_types.entry_f16->llvm_type, "");
1701 }
1702
1703 return result;
16801704}
16811705
16821706static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, ZigType *actual_type,
......@@ -10475,7 +10499,7 @@ void codegen_build_object(CodeGen *g) {
1047510499
1047610500 codegen_add_time_event(g, "Done");
1047710501 codegen_switch_sub_prog_node(g, nullptr);
10478
10502
1047910503 // append all export symbols to stage2 so we can provide them to the linker
1048010504 if (target_is_wasm(g->zig_target)){
1048110505 Error err;