llvm: fix x86_64 sysV ABI of big vectors on avx512 enabled CPUs

Closes #13629
This commit is contained in:
Veikka Tuominen 2022-11-22 23:44:12 +02:00
parent 3a616f51c0
commit fc5209c139
2 changed files with 17 additions and 9 deletions

View File

@ -60,7 +60,7 @@ pub fn classifyWindows(ty: Type, target: Target) Class {
}
}
pub const Context = enum { ret, arg };
pub const Context = enum { ret, arg, other };
/// There are a maximum of 8 possible return slots. Returned values are in
/// the beginning of the array; unused slots are filled with .none.
@ -138,7 +138,18 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
const elem_ty = ty.childType();
if (ctx == .arg) {
const bit_size = ty.bitSize(target);
if (bit_size > 128) return memory_class;
if (bit_size > 128) {
const has_avx512 = target.cpu.features.isEnabled(@enumToInt(std.Target.x86.Feature.avx512f));
if (has_avx512 and bit_size <= 512) return .{
.integer, .integer, .integer, .integer,
.integer, .integer, .integer, .integer,
};
if (has_avx512 and bit_size <= 256) return .{
.integer, .integer, .integer, .integer,
.none, .none, .none, .none,
};
return memory_class;
}
if (bit_size > 80) return .{
.integer, .integer, .none, .none,
.none, .none, .none, .none,
@ -181,7 +192,8 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
.sse, .sseup, .sseup, .sseup,
.sseup, .sseup, .sseup, .none,
};
if (bits <= 512) return .{
// LLVM always returns vectors byval
if (bits <= 512 or ctx == .ret) return .{
.sse, .sseup, .sseup, .sseup,
.sseup, .sseup, .sseup, .sseup,
};
@ -219,7 +231,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
}
}
const field_size = field.ty.abiSize(target);
const field_class_array = classifySystemV(field.ty, target, .arg);
const field_class_array = classifySystemV(field.ty, target, .other);
const field_class = std.mem.sliceTo(&field_class_array, .none);
if (byte_i + field_size <= 8) {
// Combine this field with the previous one.
@ -333,7 +345,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
}
}
// Combine this field with the previous one.
const field_class = classifySystemV(field.ty, target, .arg);
const field_class = classifySystemV(field.ty, target, .other);
for (result) |*result_item, i| {
const field_item = field_class[i];
// "If both classes are equal, this is the resulting class."

View File

@ -808,10 +808,6 @@ extern fn c_ret_big_vec() BigVec;
test "big simd vector" {
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
if (true) {
// https://github.com/ziglang/zig/issues/13629
return error.SkipZigTest;
}
c_big_vec(.{ 1, 2, 3, 4, 5, 6, 7, 8 });