From d289dba125c128bf03309957fee948fba32b8852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 6 Oct 2024 10:30:40 +0200 Subject: [PATCH 1/5] llvm: Fix ilp32e/lp64e and ilp32f/lp64f ABI selection for riscv. --- src/target.zig | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/target.zig b/src/target.zig index 95c9798f65..aeef764a8d 100644 --- a/src/target.zig +++ b/src/target.zig @@ -427,17 +427,14 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 { // Once our self-hosted linker can handle both ABIs, this hack should go away. if (target.cpu.arch == .powerpc64) return "elfv2"; - const have_float = switch (target.abi) { - .gnueabihf, .musleabihf, .eabihf => true, - else => false, - }; - switch (target.cpu.arch) { .riscv64 => { const featureSetHas = std.Target.riscv.featureSetHas; - if (featureSetHas(target.cpu.features, .d)) { + if (featureSetHas(target.cpu.features, .e)) { + return "lp64e"; + } else if (featureSetHas(target.cpu.features, .d)) { return "lp64d"; - } else if (have_float) { + } else if (featureSetHas(target.cpu.features, .f)) { return "lp64f"; } else { return "lp64"; @@ -445,12 +442,12 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 { }, .riscv32 => { const featureSetHas = std.Target.riscv.featureSetHas; - if (featureSetHas(target.cpu.features, .d)) { - return "ilp32d"; - } else if (have_float) { - return "ilp32f"; - } else if (featureSetHas(target.cpu.features, .e)) { + if (featureSetHas(target.cpu.features, .e)) { return "ilp32e"; + } else if (featureSetHas(target.cpu.features, .d)) { + return "ilp32d"; + } else if (featureSetHas(target.cpu.features, .f)) { + return "ilp32f"; } else { return "ilp32"; } From 3550cacd73b40cea5cfe3d9613bb4f80b5d42417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 6 Oct 2024 11:47:35 +0200 Subject: [PATCH 2/5] llvm: Fix compiler crash when lowering f16 for riscv32 ilp32. --- src/codegen/llvm.zig | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index bd59cef569..7cb7d6f61f 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1687,12 +1687,6 @@ pub const Object = struct { else try wip.load(.normal, param_llvm_ty, arg_ptr, param_alignment, "")); }, - .as_u16 => { - assert(!it.byval_attr); - const param = wip.arg(llvm_arg_i); - llvm_arg_i += 1; - args.appendAssumeCapacity(try wip.cast(.bitcast, param, .half, "")); - }, .float_array => { const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); const param_llvm_ty = try o.lowerType(param_ty); @@ -3095,7 +3089,6 @@ pub const Object = struct { .no_bits, .abi_sized_int, .multiple_llvm_types, - .as_u16, .float_array, .i32_array, .i64_array, @@ -3770,9 +3763,6 @@ pub const Object = struct { .multiple_llvm_types => { try llvm_params.appendSlice(o.gpa, it.types_buffer[0..it.types_len]); }, - .as_u16 => { - try llvm_params.append(o.gpa, .i16); - }, .float_array => |count| { const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, zcu).?); @@ -5587,12 +5577,6 @@ pub const FuncGen = struct { llvm_args.appendAssumeCapacity(loaded); } }, - .as_u16 => { - const arg = args[it.zig_index - 1]; - const llvm_arg = try self.resolveInst(arg); - const casted = try self.wip.cast(.bitcast, llvm_arg, .i16, ""); - try llvm_args.append(casted); - }, .float_array => |count| { const arg = args[it.zig_index - 1]; const arg_ty = self.typeOf(arg); @@ -5654,7 +5638,6 @@ pub const FuncGen = struct { .no_bits, .abi_sized_int, .multiple_llvm_types, - .as_u16, .float_array, .i32_array, .i64_array, @@ -11968,7 +11951,6 @@ const ParamTypeIterator = struct { abi_sized_int, multiple_llvm_types, slice, - as_u16, float_array: u8, i32_array: u8, i64_array: u8, @@ -12090,8 +12072,6 @@ const ParamTypeIterator = struct { .riscv32, .riscv64 => { it.zig_index += 1; it.llvm_index += 1; - if (ty.toIntern() == .f16_type and - !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16; switch (riscv_c_abi.classifyType(ty, zcu)) { .memory => return .byref_mut, .byval => return .byval, From 958f57d65d6c612a391bc72a5cf090c9efc9917b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 6 Oct 2024 11:48:05 +0200 Subject: [PATCH 3/5] llvm: Enable native f16 lowering for riscv32. --- src/codegen/llvm.zig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 7cb7d6f61f..e9d5a1af02 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -12419,7 +12419,8 @@ fn isScalar(zcu: *Zcu, ty: Type) bool { } /// This function returns true if we expect LLVM to lower x86_fp80 correctly -/// and false if we expect LLVM to crash if it counters an x86_fp80 type. +/// and false if we expect LLVM to crash if it encounters an x86_fp80 type, +/// or if it produces miscompilations. fn backendSupportsF80(target: std.Target) bool { return switch (target.cpu.arch) { .x86_64, .x86 => !std.Target.x86.featureSetHas(target.cpu.features, .soft_float), @@ -12428,8 +12429,8 @@ fn backendSupportsF80(target: std.Target) bool { } /// This function returns true if we expect LLVM to lower f16 correctly -/// and false if we expect LLVM to crash if it counters an f16 type or -/// if it produces miscompilations. +/// and false if we expect LLVM to crash if it encounters an f16 type, +/// or if it produces miscompilations. fn backendSupportsF16(target: std.Target) bool { return switch (target.cpu.arch) { .hexagon, @@ -12443,7 +12444,6 @@ fn backendSupportsF16(target: std.Target) bool { .mipsel, .mips64, .mips64el, - .riscv32, .s390x, => false, .arm, @@ -12459,7 +12459,7 @@ fn backendSupportsF16(target: std.Target) bool { } /// This function returns true if we expect LLVM to lower f128 correctly, -/// and false if we expect LLVm to crash if it encounters and f128 type +/// and false if we expect LLVM to crash if it encounters an f128 type, /// or if it produces miscompilations. fn backendSupportsF128(target: std.Target) bool { return switch (target.cpu.arch) { @@ -12486,7 +12486,7 @@ fn backendSupportsF128(target: std.Target) bool { } /// LLVM does not support all relevant intrinsics for all targets, so we -/// may need to manually generate a libc call +/// may need to manually generate a compiler-rt call. fn intrinsicsAllowed(scalar_ty: Type, target: std.Target) bool { return switch (scalar_ty.toIntern()) { .f16_type => backendSupportsF16(target), From 0941364d70d14856c9f313f819458efd0add7c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 6 Oct 2024 11:55:44 +0200 Subject: [PATCH 4/5] compiler-rt: Always use f16 as the half type for riscv. --- lib/compiler_rt/common.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compiler_rt/common.zig b/lib/compiler_rt/common.zig index 786dc7303a..3b1f93f1c2 100644 --- a/lib/compiler_rt/common.zig +++ b/lib/compiler_rt/common.zig @@ -103,7 +103,7 @@ pub fn F16T(comptime OtherType: type) type { else u16, .aarch64, .aarch64_be => f16, - .riscv64 => if (builtin.zig_backend == .stage1) u16 else f16, + .riscv32, .riscv64 => f16, .x86, .x86_64 => if (builtin.target.isDarwin()) switch (OtherType) { // Starting with LLVM 16, Darwin uses different abi for f16 // depending on the type of the other return/argument..??? From 6302a90cbf9978766757e11808e7764d5c4611b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 6 Oct 2024 11:12:54 +0200 Subject: [PATCH 5/5] test: Add riscv(32,64)-linux-(none,musl) with soft float to module tests. --- test/tests.zig | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/test/tests.zig b/test/tests.zig index 017f9478a9..a9035560b3 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -579,6 +579,20 @@ const test_targets = blk: { .link_libc = true, }, + .{ + .target = std.Target.Query.parse(.{ + .arch_os_abi = "riscv32-linux-none", + .cpu_features = "baseline-d-f", + }) catch unreachable, + }, + .{ + .target = std.Target.Query.parse(.{ + .arch_os_abi = "riscv32-linux-musl", + .cpu_features = "baseline-d-f", + }) catch unreachable, + .link_libc = true, + }, + .{ .target = .{ .cpu_arch = .riscv32, @@ -603,6 +617,20 @@ const test_targets = blk: { .link_libc = true, }, + .{ + .target = std.Target.Query.parse(.{ + .arch_os_abi = "riscv64-linux-none", + .cpu_features = "baseline-d-f", + }) catch unreachable, + }, + .{ + .target = std.Target.Query.parse(.{ + .arch_os_abi = "riscv64-linux-musl", + .cpu_features = "baseline-d-f", + }) catch unreachable, + .link_libc = true, + }, + .{ .target = .{ .cpu_arch = .riscv64, @@ -631,7 +659,7 @@ const test_targets = blk: { .target = std.Target.Query.parse(.{ .arch_os_abi = "riscv64-linux-musl", .cpu_features = "baseline+v+zbb", - }) catch @panic("OOM"), + }) catch unreachable, .use_llvm = false, .use_lld = false, },