authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-17 12:54:44-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-10-17 12:54:44-07:00
log8504e1f550ba697f29fd72f181d9009ebad09501
tree1a90c3da1ff4afdb23dc5415370874efe5778f23
parent816dfca0b579440604eb871c6a76a3edd250240f
parent6302a90cbf9978766757e11808e7764d5c4611b1
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21610 from alexrp/riscv-abis

Fix some RISC-V ABI issues and add ILP32/LP64 (soft float) to module tests

4 files changed, 44 insertions(+), 39 deletions(-)

lib/compiler_rt/common.zig+1-1
...@@ -103,7 +103,7 @@ pub fn F16T(comptime OtherType: type) type {...@@ -103,7 +103,7 @@ pub fn F16T(comptime OtherType: type) type {
103 else103 else
104 u16,104 u16,
105 .aarch64, .aarch64_be => f16,105 .aarch64, .aarch64_be => f16,
106 .riscv64 => if (builtin.zig_backend == .stage1) u16 else f16,106 .riscv32, .riscv64 => f16,
107 .x86, .x86_64 => if (builtin.target.isDarwin()) switch (OtherType) {107 .x86, .x86_64 => if (builtin.target.isDarwin()) switch (OtherType) {
108 // Starting with LLVM 16, Darwin uses different abi for f16108 // Starting with LLVM 16, Darwin uses different abi for f16
109 // depending on the type of the other return/argument..???109 // depending on the type of the other return/argument..???
src/codegen/llvm.zig+6-26
...@@ -1688,12 +1688,6 @@ pub const Object = struct {...@@ -1688,12 +1688,6 @@ pub const Object = struct {
1688 else1688 else
1689 try wip.load(.normal, param_llvm_ty, arg_ptr, param_alignment, ""));1689 try wip.load(.normal, param_llvm_ty, arg_ptr, param_alignment, ""));
1690 },1690 },
1691 .as_u16 => {
1692 assert(!it.byval_attr);
1693 const param = wip.arg(llvm_arg_i);
1694 llvm_arg_i += 1;
1695 args.appendAssumeCapacity(try wip.cast(.bitcast, param, .half, ""));
1696 },
1697 .float_array => {1691 .float_array => {
1698 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);1692 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1699 const param_llvm_ty = try o.lowerType(param_ty);1693 const param_llvm_ty = try o.lowerType(param_ty);
...@@ -3096,7 +3090,6 @@ pub const Object = struct {...@@ -3096,7 +3090,6 @@ pub const Object = struct {
3096 .no_bits,3090 .no_bits,
3097 .abi_sized_int,3091 .abi_sized_int,
3098 .multiple_llvm_types,3092 .multiple_llvm_types,
3099 .as_u16,
3100 .float_array,3093 .float_array,
3101 .i32_array,3094 .i32_array,
3102 .i64_array,3095 .i64_array,
...@@ -3771,9 +3764,6 @@ pub const Object = struct {...@@ -3771,9 +3764,6 @@ pub const Object = struct {
3771 .multiple_llvm_types => {3764 .multiple_llvm_types => {
3772 try llvm_params.appendSlice(o.gpa, it.types_buffer[0..it.types_len]);3765 try llvm_params.appendSlice(o.gpa, it.types_buffer[0..it.types_len]);
3773 },3766 },
3774 .as_u16 => {
3775 try llvm_params.append(o.gpa, .i16);
3776 },
3777 .float_array => |count| {3767 .float_array => |count| {
3778 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);3768 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
3779 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, zcu).?);3769 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, zcu).?);
...@@ -5588,12 +5578,6 @@ pub const FuncGen = struct {...@@ -5588,12 +5578,6 @@ pub const FuncGen = struct {
5588 llvm_args.appendAssumeCapacity(loaded);5578 llvm_args.appendAssumeCapacity(loaded);
5589 }5579 }
5590 },5580 },
5591 .as_u16 => {
5592 const arg = args[it.zig_index - 1];
5593 const llvm_arg = try self.resolveInst(arg);
5594 const casted = try self.wip.cast(.bitcast, llvm_arg, .i16, "");
5595 try llvm_args.append(casted);
5596 },
5597 .float_array => |count| {5581 .float_array => |count| {
5598 const arg = args[it.zig_index - 1];5582 const arg = args[it.zig_index - 1];
5599 const arg_ty = self.typeOf(arg);5583 const arg_ty = self.typeOf(arg);
...@@ -5655,7 +5639,6 @@ pub const FuncGen = struct {...@@ -5655,7 +5639,6 @@ pub const FuncGen = struct {
5655 .no_bits,5639 .no_bits,
5656 .abi_sized_int,5640 .abi_sized_int,
5657 .multiple_llvm_types,5641 .multiple_llvm_types,
5658 .as_u16,
5659 .float_array,5642 .float_array,
5660 .i32_array,5643 .i32_array,
5661 .i64_array,5644 .i64_array,
...@@ -11969,7 +11952,6 @@ const ParamTypeIterator = struct {...@@ -11969,7 +11952,6 @@ const ParamTypeIterator = struct {
11969 abi_sized_int,11952 abi_sized_int,
11970 multiple_llvm_types,11953 multiple_llvm_types,
11971 slice,11954 slice,
11972 as_u16,
11973 float_array: u8,11955 float_array: u8,
11974 i32_array: u8,11956 i32_array: u8,
11975 i64_array: u8,11957 i64_array: u8,
...@@ -12091,8 +12073,6 @@ const ParamTypeIterator = struct {...@@ -12091,8 +12073,6 @@ const ParamTypeIterator = struct {
12091 .riscv32, .riscv64 => {12073 .riscv32, .riscv64 => {
12092 it.zig_index += 1;12074 it.zig_index += 1;
12093 it.llvm_index += 1;12075 it.llvm_index += 1;
12094 if (ty.toIntern() == .f16_type and
12095 !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16;
12096 switch (riscv_c_abi.classifyType(ty, zcu)) {12076 switch (riscv_c_abi.classifyType(ty, zcu)) {
12097 .memory => return .byref_mut,12077 .memory => return .byref_mut,
12098 .byval => return .byval,12078 .byval => return .byval,
...@@ -12440,7 +12420,8 @@ fn isScalar(zcu: *Zcu, ty: Type) bool {...@@ -12440,7 +12420,8 @@ fn isScalar(zcu: *Zcu, ty: Type) bool {
12440}12420}
1244112421
12442/// This function returns true if we expect LLVM to lower x86_fp80 correctly12422/// This function returns true if we expect LLVM to lower x86_fp80 correctly
12443/// and false if we expect LLVM to crash if it counters an x86_fp80 type.12423/// and false if we expect LLVM to crash if it encounters an x86_fp80 type,
12424/// or if it produces miscompilations.
12444fn backendSupportsF80(target: std.Target) bool {12425fn backendSupportsF80(target: std.Target) bool {
12445 return switch (target.cpu.arch) {12426 return switch (target.cpu.arch) {
12446 .x86_64, .x86 => !std.Target.x86.featureSetHas(target.cpu.features, .soft_float),12427 .x86_64, .x86 => !std.Target.x86.featureSetHas(target.cpu.features, .soft_float),
...@@ -12449,8 +12430,8 @@ fn backendSupportsF80(target: std.Target) bool {...@@ -12449,8 +12430,8 @@ fn backendSupportsF80(target: std.Target) bool {
12449}12430}
1245012431
12451/// This function returns true if we expect LLVM to lower f16 correctly12432/// This function returns true if we expect LLVM to lower f16 correctly
12452/// and false if we expect LLVM to crash if it counters an f16 type or12433/// and false if we expect LLVM to crash if it encounters an f16 type,
12453/// if it produces miscompilations.12434/// or if it produces miscompilations.
12454fn backendSupportsF16(target: std.Target) bool {12435fn backendSupportsF16(target: std.Target) bool {
12455 return switch (target.cpu.arch) {12436 return switch (target.cpu.arch) {
12456 // LoongArch can be removed from this list with LLVM 20.12437 // LoongArch can be removed from this list with LLVM 20.
...@@ -12467,7 +12448,6 @@ fn backendSupportsF16(target: std.Target) bool {...@@ -12467,7 +12448,6 @@ fn backendSupportsF16(target: std.Target) bool {
12467 .mipsel,12448 .mipsel,
12468 .mips64,12449 .mips64,
12469 .mips64el,12450 .mips64el,
12470 .riscv32,
12471 .s390x,12451 .s390x,
12472 => false,12452 => false,
12473 .arm,12453 .arm,
...@@ -12483,7 +12463,7 @@ fn backendSupportsF16(target: std.Target) bool {...@@ -12483,7 +12463,7 @@ fn backendSupportsF16(target: std.Target) bool {
12483}12463}
1248412464
12485/// This function returns true if we expect LLVM to lower f128 correctly,12465/// This function returns true if we expect LLVM to lower f128 correctly,
12486/// and false if we expect LLVm to crash if it encounters and f128 type12466/// and false if we expect LLVM to crash if it encounters an f128 type,
12487/// or if it produces miscompilations.12467/// or if it produces miscompilations.
12488fn backendSupportsF128(target: std.Target) bool {12468fn backendSupportsF128(target: std.Target) bool {
12489 return switch (target.cpu.arch) {12469 return switch (target.cpu.arch) {
...@@ -12510,7 +12490,7 @@ fn backendSupportsF128(target: std.Target) bool {...@@ -12510,7 +12490,7 @@ fn backendSupportsF128(target: std.Target) bool {
12510}12490}
1251112491
12512/// LLVM does not support all relevant intrinsics for all targets, so we12492/// LLVM does not support all relevant intrinsics for all targets, so we
12513/// may need to manually generate a libc call12493/// may need to manually generate a compiler-rt call.
12514fn intrinsicsAllowed(scalar_ty: Type, target: std.Target) bool {12494fn intrinsicsAllowed(scalar_ty: Type, target: std.Target) bool {
12515 return switch (scalar_ty.toIntern()) {12495 return switch (scalar_ty.toIntern()) {
12516 .f16_type => backendSupportsF16(target),12496 .f16_type => backendSupportsF16(target),
src/target.zig+8-11
...@@ -427,17 +427,14 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {...@@ -427,17 +427,14 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
427 // Once our self-hosted linker can handle both ABIs, this hack should go away.427 // Once our self-hosted linker can handle both ABIs, this hack should go away.
428 if (target.cpu.arch == .powerpc64) return "elfv2";428 if (target.cpu.arch == .powerpc64) return "elfv2";
429429
430 const have_float = switch (target.abi) {
431 .gnueabihf, .musleabihf, .eabihf => true,
432 else => false,
433 };
434
435 switch (target.cpu.arch) {430 switch (target.cpu.arch) {
436 .riscv64 => {431 .riscv64 => {
437 const featureSetHas = std.Target.riscv.featureSetHas;432 const featureSetHas = std.Target.riscv.featureSetHas;
438 if (featureSetHas(target.cpu.features, .d)) {433 if (featureSetHas(target.cpu.features, .e)) {
434 return "lp64e";
435 } else if (featureSetHas(target.cpu.features, .d)) {
439 return "lp64d";436 return "lp64d";
440 } else if (have_float) {437 } else if (featureSetHas(target.cpu.features, .f)) {
441 return "lp64f";438 return "lp64f";
442 } else {439 } else {
443 return "lp64";440 return "lp64";
...@@ -445,12 +442,12 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {...@@ -445,12 +442,12 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
445 },442 },
446 .riscv32 => {443 .riscv32 => {
447 const featureSetHas = std.Target.riscv.featureSetHas;444 const featureSetHas = std.Target.riscv.featureSetHas;
448 if (featureSetHas(target.cpu.features, .d)) {445 if (featureSetHas(target.cpu.features, .e)) {
446 return "ilp32e";
447 } else if (featureSetHas(target.cpu.features, .d)) {
449 return "ilp32d";448 return "ilp32d";
450 } else if (have_float) {449 } else if (featureSetHas(target.cpu.features, .f)) {
451 return "ilp32f";450 return "ilp32f";
452 } else if (featureSetHas(target.cpu.features, .e)) {
453 return "ilp32e";
454 } else {451 } else {
455 return "ilp32";452 return "ilp32";
456 }453 }
test/tests.zig+29-1
...@@ -579,6 +579,20 @@ const test_targets = blk: {...@@ -579,6 +579,20 @@ const test_targets = blk: {
579 .link_libc = true,579 .link_libc = true,
580 },580 },
581581
582 .{
583 .target = std.Target.Query.parse(.{
584 .arch_os_abi = "riscv32-linux-none",
585 .cpu_features = "baseline-d-f",
586 }) catch unreachable,
587 },
588 .{
589 .target = std.Target.Query.parse(.{
590 .arch_os_abi = "riscv32-linux-musl",
591 .cpu_features = "baseline-d-f",
592 }) catch unreachable,
593 .link_libc = true,
594 },
595
582 .{596 .{
583 .target = .{597 .target = .{
584 .cpu_arch = .riscv32,598 .cpu_arch = .riscv32,
...@@ -603,6 +617,20 @@ const test_targets = blk: {...@@ -603,6 +617,20 @@ const test_targets = blk: {
603 .link_libc = true,617 .link_libc = true,
604 },618 },
605619
620 .{
621 .target = std.Target.Query.parse(.{
622 .arch_os_abi = "riscv64-linux-none",
623 .cpu_features = "baseline-d-f",
624 }) catch unreachable,
625 },
626 .{
627 .target = std.Target.Query.parse(.{
628 .arch_os_abi = "riscv64-linux-musl",
629 .cpu_features = "baseline-d-f",
630 }) catch unreachable,
631 .link_libc = true,
632 },
633
606 .{634 .{
607 .target = .{635 .target = .{
608 .cpu_arch = .riscv64,636 .cpu_arch = .riscv64,
...@@ -631,7 +659,7 @@ const test_targets = blk: {...@@ -631,7 +659,7 @@ const test_targets = blk: {
631 .target = std.Target.Query.parse(.{659 .target = std.Target.Query.parse(.{
632 .arch_os_abi = "riscv64-linux-musl",660 .arch_os_abi = "riscv64-linux-musl",
633 .cpu_features = "baseline+v+zbb",661 .cpu_features = "baseline+v+zbb",
634 }) catch @panic("OOM"),662 }) catch unreachable,
635 .use_llvm = false,663 .use_llvm = false,
636 .use_lld = false,664 .use_lld = false,
637 },665 },