Merge pull request #21610 from alexrp/riscv-abis

Fix some RISC-V ABI issues and add ILP32/LP64 (soft float) to module tests
This commit is contained in:
Andrew Kelley 2024-10-17 12:54:44 -07:00 committed by GitHub
commit 8504e1f550
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 40 deletions

View File

@ -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..???

View File

@ -1688,12 +1688,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);
@ -3096,7 +3090,6 @@ pub const Object = struct {
.no_bits,
.abi_sized_int,
.multiple_llvm_types,
.as_u16,
.float_array,
.i32_array,
.i64_array,
@ -3771,9 +3764,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).?);
@ -5588,12 +5578,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);
@ -5655,7 +5639,6 @@ pub const FuncGen = struct {
.no_bits,
.abi_sized_int,
.multiple_llvm_types,
.as_u16,
.float_array,
.i32_array,
.i64_array,
@ -11969,7 +11952,6 @@ const ParamTypeIterator = struct {
abi_sized_int,
multiple_llvm_types,
slice,
as_u16,
float_array: u8,
i32_array: u8,
i64_array: u8,
@ -12091,8 +12073,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,
@ -12440,7 +12420,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),
@ -12449,8 +12430,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) {
// LoongArch can be removed from this list with LLVM 20.
@ -12467,7 +12448,6 @@ fn backendSupportsF16(target: std.Target) bool {
.mipsel,
.mips64,
.mips64el,
.riscv32,
.s390x,
=> false,
.arm,
@ -12483,7 +12463,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) {
@ -12510,7 +12490,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),

View File

@ -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";
}

View File

@ -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,
},