authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-22 23:44:12+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 14:38:35-07:00
log7d812dc1c797652a77c25dbc9d9546dbb57c2aaf
tree34a18d9dd6100aeac0e0706aea1e05b80059b9c5
parent6b1f99dd338ffc39accc32349cbe9d46c92d064c

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

Closes #13629

2 files changed, 17 insertions(+), 9 deletions(-)

src/arch/x86_64/abi.zig+17-5
......@@ -60,7 +60,7 @@ pub fn classifyWindows(ty: Type, target: Target) Class {
6060 }
6161}
6262
63pub const Context = enum { ret, arg };
63pub const Context = enum { ret, arg, other };
6464
6565/// There are a maximum of 8 possible return slots. Returned values are in
6666/// 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 {
138138 const elem_ty = ty.childType();
139139 if (ctx == .arg) {
140140 const bit_size = ty.bitSize(target);
141 if (bit_size > 128) return memory_class;
141 if (bit_size > 128) {
142 const has_avx512 = target.cpu.features.isEnabled(@enumToInt(std.Target.x86.Feature.avx512f));
143 if (has_avx512 and bit_size <= 512) return .{
144 .integer, .integer, .integer, .integer,
145 .integer, .integer, .integer, .integer,
146 };
147 if (has_avx512 and bit_size <= 256) return .{
148 .integer, .integer, .integer, .integer,
149 .none, .none, .none, .none,
150 };
151 return memory_class;
152 }
142153 if (bit_size > 80) return .{
143154 .integer, .integer, .none, .none,
144155 .none, .none, .none, .none,
......@@ -181,7 +192,8 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
181192 .sse, .sseup, .sseup, .sseup,
182193 .sseup, .sseup, .sseup, .none,
183194 };
184 if (bits <= 512) return .{
195 // LLVM always returns vectors byval
196 if (bits <= 512 or ctx == .ret) return .{
185197 .sse, .sseup, .sseup, .sseup,
186198 .sseup, .sseup, .sseup, .sseup,
187199 };
......@@ -219,7 +231,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
219231 }
220232 }
221233 const field_size = field.ty.abiSize(target);
222 const field_class_array = classifySystemV(field.ty, target, .arg);
234 const field_class_array = classifySystemV(field.ty, target, .other);
223235 const field_class = std.mem.sliceTo(&field_class_array, .none);
224236 if (byte_i + field_size <= 8) {
225237 // Combine this field with the previous one.
......@@ -333,7 +345,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
333345 }
334346 }
335347 // Combine this field with the previous one.
336 const field_class = classifySystemV(field.ty, target, .arg);
348 const field_class = classifySystemV(field.ty, target, .other);
337349 for (result) |*result_item, i| {
338350 const field_item = field_class[i];
339351 // "If both classes are equal, this is the resulting class."
test/c_abi/main.zig-4
......@@ -808,10 +808,6 @@ extern fn c_ret_big_vec() BigVec;
808808
809809test "big simd vector" {
810810 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
811 if (true) {
812 // https://github.com/ziglang/zig/issues/13629
813 return error.SkipZigTest;
814 }
815811
816812 c_big_vec(.{ 1, 2, 3, 4, 5, 6, 7, 8 });
817813