mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
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.
This commit is contained in:
parent
21f1e76efe
commit
65bea9ac07
@ -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;
|
||||
}
|
||||
|
||||
@ -2804,6 +2804,13 @@ pub const Type = struct {
|
||||
return ty.zigTypeTag(mod) == .Vector;
|
||||
}
|
||||
|
||||
/// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len.
|
||||
pub fn totalVectorBits(ty: Type, zcu: *Zcu) u64 {
|
||||
if (!ty.isVector(zcu)) return 0;
|
||||
const v = zcu.intern_pool.indexToKey(ty.toIntern()).vector_type;
|
||||
return v.len * Type.fromInterned(v.child).bitSize(zcu);
|
||||
}
|
||||
|
||||
pub fn isArrayOrVector(ty: Type, mod: *const Module) bool {
|
||||
return switch (ty.zigTypeTag(mod)) {
|
||||
.Array, .Vector => true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user