| ... | @@ -10990,12 +10990,27 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ | ... | @@ -10990,12 +10990,27 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ |
| 10990 | }; | 10990 | }; |
| 10991 | } | 10991 | } |
| 10992 | | 10992 | |
| | 10993 | fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool { |
| | 10994 | if (isByRef(ty, zcu)) { |
| | 10995 | return true; |
| | 10996 | } else if (target.cpu.arch.isX86() and |
| | 10997 | !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and |
| | 10998 | ty.totalVectorBits(zcu) >= 512) |
| | 10999 | { |
| | 11000 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns |
| | 11001 | // "512-bit vector arguments require 'evex512' for AVX512" |
| | 11002 | return true; |
| | 11003 | } else { |
| | 11004 | return false; |
| | 11005 | } |
| | 11006 | } |
| | 11007 | |
| 10993 | fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Target) bool { | 11008 | fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Target) bool { |
| 10994 | const return_type = Type.fromInterned(fn_info.return_type); | 11009 | const return_type = Type.fromInterned(fn_info.return_type); |
| 10995 | if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false; | 11010 | if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false; |
| 10996 | | 11011 | |
| 10997 | return switch (fn_info.cc) { | 11012 | return switch (fn_info.cc) { |
| 10998 | .Unspecified, .Inline => isByRef(return_type, zcu), | 11013 | .Unspecified, .Inline => returnTypeByRef(zcu, target, return_type), |
| 10999 | .C => switch (target.cpu.arch) { | 11014 | .C => switch (target.cpu.arch) { |
| 11000 | .mips, .mipsel => false, | 11015 | .mips, .mipsel => false, |
| 11001 | .x86 => isByRef(return_type, zcu), | 11016 | .x86 => isByRef(return_type, zcu), |
| ... | @@ -11043,7 +11058,8 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu | ... | @@ -11043,7 +11058,8 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu |
| 11043 | switch (fn_info.cc) { | 11058 | switch (fn_info.cc) { |
| 11044 | .Unspecified, | 11059 | .Unspecified, |
| 11045 | .Inline, | 11060 | .Inline, |
| 11046 | => return if (isByRef(return_type, mod)) .void else o.lowerType(return_type), | 11061 | => return if (returnTypeByRef(mod, target, return_type)) .void else o.lowerType(return_type), |
| | 11062 | |
| 11047 | .C => { | 11063 | .C => { |
| 11048 | switch (target.cpu.arch) { | 11064 | switch (target.cpu.arch) { |
| 11049 | .mips, .mipsel => return o.lowerType(return_type), | 11065 | .mips, .mipsel => return o.lowerType(return_type), |
| ... | @@ -11266,6 +11282,13 @@ const ParamTypeIterator = struct { | ... | @@ -11266,6 +11282,13 @@ const ParamTypeIterator = struct { |
| 11266 | return .slice; | 11282 | return .slice; |
| 11267 | } else if (isByRef(ty, zcu)) { | 11283 | } else if (isByRef(ty, zcu)) { |
| 11268 | return .byref; | 11284 | return .byref; |
| | 11285 | } else if (target.cpu.arch.isX86() and |
| | 11286 | !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and |
| | 11287 | ty.totalVectorBits(zcu) >= 512) |
| | 11288 | { |
| | 11289 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns |
| | 11290 | // "512-bit vector arguments require 'evex512' for AVX512" |
| | 11291 | return .byref; |
| 11269 | } else { | 11292 | } else { |
| 11270 | return .byval; | 11293 | return .byval; |
| 11271 | } | 11294 | } |