diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-04-26 13:40:42 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-05-08 19:37:28 -0700 |
| commit | 65bea9ac079e8d580f710b62f3c8cfcb3821d2cb (patch) | |
| tree | c0dc0933f6a0ca691f4a1e7055cb04fdae1b02b1 /src/codegen/llvm.zig | |
| parent | 21f1e76efeb2a1c1c9df32628b81713f9876d5ab (diff) | |
| download | zig-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/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 27 |
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; } |
