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 {...@@ -60,7 +60,7 @@ pub fn classifyWindows(ty: Type, target: Target) Class {
60 }60 }
61}61}
6262
63pub const Context = enum { ret, arg };63pub const Context = enum { ret, arg, other };
6464
65/// There are a maximum of 8 possible return slots. Returned values are in65/// There are a maximum of 8 possible return slots. Returned values are in
66/// the beginning of the array; unused slots are filled with .none.66/// 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 {...@@ -138,7 +138,18 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
138 const elem_ty = ty.childType();138 const elem_ty = ty.childType();
139 if (ctx == .arg) {139 if (ctx == .arg) {
140 const bit_size = ty.bitSize(target);140 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 }
142 if (bit_size > 80) return .{153 if (bit_size > 80) return .{
143 .integer, .integer, .none, .none,154 .integer, .integer, .none, .none,
144 .none, .none, .none, .none,155 .none, .none, .none, .none,
...@@ -181,7 +192,8 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -181,7 +192,8 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
181 .sse, .sseup, .sseup, .sseup,192 .sse, .sseup, .sseup, .sseup,
182 .sseup, .sseup, .sseup, .none,193 .sseup, .sseup, .sseup, .none,
183 };194 };
184 if (bits <= 512) return .{195 // LLVM always returns vectors byval
196 if (bits <= 512 or ctx == .ret) return .{
185 .sse, .sseup, .sseup, .sseup,197 .sse, .sseup, .sseup, .sseup,
186 .sseup, .sseup, .sseup, .sseup,198 .sseup, .sseup, .sseup, .sseup,
187 };199 };
...@@ -219,7 +231,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -219,7 +231,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
219 }231 }
220 }232 }
221 const field_size = field.ty.abiSize(target);233 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);
223 const field_class = std.mem.sliceTo(&field_class_array, .none);235 const field_class = std.mem.sliceTo(&field_class_array, .none);
224 if (byte_i + field_size <= 8) {236 if (byte_i + field_size <= 8) {
225 // Combine this field with the previous one.237 // Combine this field with the previous one.
...@@ -333,7 +345,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {...@@ -333,7 +345,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
333 }345 }
334 }346 }
335 // Combine this field with the previous one.347 // 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);
337 for (result) |*result_item, i| {349 for (result) |*result_item, i| {
338 const field_item = field_class[i];350 const field_item = field_class[i];
339 // "If both classes are equal, this is the resulting class."351 // "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;...@@ -808,10 +808,6 @@ extern fn c_ret_big_vec() BigVec;
808808
809test "big simd vector" {809test "big simd vector" {
810 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;810 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
816 c_big_vec(.{ 1, 2, 3, 4, 5, 6, 7, 8 });812 c_big_vec(.{ 1, 2, 3, 4, 5, 6, 7, 8 });
817813