aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-04-26 13:40:42 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-05-08 19:37:28 -0700
commit65bea9ac079e8d580f710b62f3c8cfcb3821d2cb (patch)
treec0dc0933f6a0ca691f4a1e7055cb04fdae1b02b1 /src/codegen
parent21f1e76efeb2a1c1c9df32628b81713f9876d5ab (diff)
downloadzig-65bea9ac079e8d580f710b62f3c8cfcb3821d2cb.tar.gz
zig-65bea9ac079e8d580f710b62f3c8cfcb3821d2cb.zip
LLVM 18 update: avoid passing vectors sometimes
LLVM now refuses to lower arguments and return values on x86 targets when the total vector bit size is >= 512. This code detects such a situation and uses byref instead of byval.
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/llvm.zig27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 4142ad0a19..458c187fec 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -10990,12 +10990,27 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ
};
}
+fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool {
+ if (isByRef(ty, zcu)) {
+ return true;
+ } else if (target.cpu.arch.isX86() and
+ !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and
+ ty.totalVectorBits(zcu) >= 512)
+ {
+ // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns
+ // "512-bit vector arguments require 'evex512' for AVX512"
+ return true;
+ } else {
+ return false;
+ }
+}
+
fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Target) bool {
const return_type = Type.fromInterned(fn_info.return_type);
if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false;
return switch (fn_info.cc) {
- .Unspecified, .Inline => isByRef(return_type, zcu),
+ .Unspecified, .Inline => returnTypeByRef(zcu, target, return_type),
.C => switch (target.cpu.arch) {
.mips, .mipsel => false,
.x86 => isByRef(return_type, zcu),
@@ -11043,7 +11058,8 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
switch (fn_info.cc) {
.Unspecified,
.Inline,
- => return if (isByRef(return_type, mod)) .void else o.lowerType(return_type),
+ => return if (returnTypeByRef(mod, target, return_type)) .void else o.lowerType(return_type),
+
.C => {
switch (target.cpu.arch) {
.mips, .mipsel => return o.lowerType(return_type),
@@ -11266,6 +11282,13 @@ const ParamTypeIterator = struct {
return .slice;
} else if (isByRef(ty, zcu)) {
return .byref;
+ } else if (target.cpu.arch.isX86() and
+ !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and
+ ty.totalVectorBits(zcu) >= 512)
+ {
+ // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns
+ // "512-bit vector arguments require 'evex512' for AVX512"
+ return .byref;
} else {
return .byval;
}