diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-05-09 01:52:26 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-05-09 01:52:26 -0700 |
| commit | bcb534c295d5cc6fd63caa570cc08e6b148a507c (patch) | |
| tree | 0b17cb1e632d894f50f25e550d5113f232b0e877 /src/codegen/llvm.zig | |
| parent | d9b00ee4ba48717ff6b306a6f9419e7b604ac04b (diff) | |
| parent | 74f52954b9cb40d59d80b839b45bb859146731a7 (diff) | |
| download | zig-bcb534c295d5cc6fd63caa570cc08e6b148a507c.tar.gz zig-bcb534c295d5cc6fd63caa570cc08e6b148a507c.zip | |
Merge branch 'llvm18'
Upgrades the LLVM, Clang, and LLD dependencies to LLVM 18.x
Related to #16270
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 155 |
1 files changed, 117 insertions, 38 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 3529e9f411..71481e859b 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -92,6 +92,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { .hsail64 => "hsail64", .spir => "spir", .spir64 => "spir64", + .spirv => "spirv", .spirv32 => "spirv32", .spirv64 => "spirv64", .kalimba => "kalimba", @@ -109,8 +110,6 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { const llvm_os = switch (target.os.tag) { .freestanding => "unknown", - .ananas => "ananas", - .cloudabi => "cloudabi", .dragonfly => "dragonfly", .freebsd => "freebsd", .fuchsia => "fuchsia", @@ -123,7 +122,6 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { .windows => "windows", .zos => "zos", .haiku => "haiku", - .minix => "minix", .rtems => "rtems", .nacl => "nacl", .aix => "aix", @@ -134,7 +132,6 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { .ps5 => "ps5", .elfiamcu => "elfiamcu", .mesa3d => "mesa3d", - .contiki => "contiki", .amdpal => "amdpal", .hermit => "hermit", .hurd => "hurd", @@ -148,10 +145,17 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { .driverkit => "driverkit", .shadermodel => "shadermodel", .liteos => "liteos", + .xros => "xros", + .serenity => "serenity", + .vulkan => "vulkan", + .opencl, .glsl450, - .vulkan, .plan9, + .ananas, + .cloudabi, + .minix, + .contiki, .other, => "unknown", }; @@ -216,10 +220,18 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType { return switch (os_tag) { - .freestanding, .other, .opencl, .glsl450, .vulkan, .plan9 => .UnknownOS, + .freestanding, + .other, + .opencl, + .glsl450, + .plan9, + .ananas, + .cloudabi, + .minix, + .contiki, + => .UnknownOS, + .windows, .uefi => .Win32, - .ananas => .Ananas, - .cloudabi => .CloudABI, .dragonfly => .DragonFly, .freebsd => .FreeBSD, .fuchsia => .Fuchsia, @@ -233,7 +245,6 @@ pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType { .solaris, .illumos => .Solaris, .zos => .ZOS, .haiku => .Haiku, - .minix => .Minix, .rtems => .RTEMS, .nacl => .NaCl, .aix => .AIX, @@ -245,8 +256,8 @@ pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType { .elfiamcu => .ELFIAMCU, .tvos => .TvOS, .watchos => .WatchOS, + .xros => .XROS, .mesa3d => .Mesa3D, - .contiki => .Contiki, .amdpal => .AMDPAL, .hermit => .HermitCore, .hurd => .Hurd, @@ -255,6 +266,8 @@ pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType { .driverkit => .DriverKit, .shadermodel => .ShaderModel, .liteos => .LiteOS, + .vulkan => .Vulkan, + .serenity => .Serenity, }; } @@ -310,6 +323,9 @@ pub fn targetArch(arch_tag: std.Target.Cpu.Arch) llvm.ArchType { .hsail64 => .hsail64, .spir => .spir, .spir64 => .spir64, + .spirv => .spirv, + .spirv32 => .spirv32, + .spirv64 => .spirv64, .kalimba => .kalimba, .shave => .shave, .lanai => .lanai, @@ -318,7 +334,7 @@ pub fn targetArch(arch_tag: std.Target.Cpu.Arch) llvm.ArchType { .renderscript32 => .renderscript32, .renderscript64 => .renderscript64, .ve => .ve, - .spu_2, .spirv32, .spirv64 => .UnknownArch, + .spu_2 => .UnknownArch, }; } @@ -593,7 +609,7 @@ const DataLayoutBuilder = struct { switch (kind) { .integer => { if (self.target.ptrBitWidth() <= 16 and size >= 128) return; - abi = @min(abi, self.target.maxIntAlignment() * 8); + abi = @min(abi, Type.maxIntAlignment(self.target, true) * 8); switch (self.target.cpu.arch) { .aarch64, .aarch64_be, @@ -655,6 +671,20 @@ const DataLayoutBuilder = struct { abi = size; force_abi = size == 64; }, + .x86 => switch (size) { + 128 => { + abi = size; + pref = size; + }, + else => {}, + }, + .x86_64 => switch (size) { + 64, 128 => { + abi = size; + pref = size; + }, + else => {}, + }, else => {}, } }, @@ -10974,12 +11004,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), @@ -11027,7 +11072,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), @@ -11135,10 +11181,18 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E types_buffer[types_index] = .i64; types_index += 1; }, - .sse, .sseup => { + .sse => { types_buffer[types_index] = .double; types_index += 1; }, + .sseup => { + if (types_buffer[types_index - 1] == .double) { + types_buffer[types_index - 1] = .fp128; + } else { + types_buffer[types_index] = .double; + types_index += 1; + } + }, .float => { types_buffer[types_index] = .float; types_index += 1; @@ -11250,6 +11304,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; } @@ -11415,10 +11476,18 @@ const ParamTypeIterator = struct { types_buffer[types_index] = .i64; types_index += 1; }, - .sse, .sseup => { + .sse => { types_buffer[types_index] = .double; types_index += 1; }, + .sseup => { + if (types_buffer[types_index - 1] == .double) { + types_buffer[types_index - 1] = .fp128; + } else { + types_buffer[types_index] = .double; + types_index += 1; + } + }, .float => { types_buffer[types_index] = .float; types_index += 1; @@ -11508,28 +11577,37 @@ fn ccAbiPromoteInt( .Int, .Enum, .ErrorSet => ty.intInfo(mod), else => return null, }; - if (int_info.bits <= 16) return int_info.signedness; - switch (target.cpu.arch) { - .riscv64 => { - if (int_info.bits == 32) { - // LLVM always signextends 32 bit ints, unsure if bug. - return .signed; - } - if (int_info.bits < 64) { - return int_info.signedness; - } + return switch (target.os.tag) { + .macos => switch (int_info.bits) { + 0...16 => int_info.signedness, + else => null, }, - .sparc64, - .powerpc64, - .powerpc64le, - => { - if (int_info.bits < 64) { - return int_info.signedness; - } + else => switch (target.cpu.arch) { + .riscv64 => switch (int_info.bits) { + 0...16 => int_info.signedness, + 32 => .signed, // LLVM always signextends 32 bit ints, unsure if bug. + 17...31, 33...63 => int_info.signedness, + else => null, + }, + + .sparc64, + .powerpc64, + .powerpc64le, + => switch (int_info.bits) { + 0...63 => int_info.signedness, + else => null, + }, + + .aarch64, + .aarch64_be, + => null, + + else => switch (int_info.bits) { + 0...16 => int_info.signedness, + else => null, + }, }, - else => {}, - } - return null; + }; } /// This is the one source of truth for whether a type is passed around as an LLVM pointer, @@ -11969,6 +12047,9 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void { .shave, .spir, .spir64, + .spirv, + .spirv32, + .spirv64, .kalimba, .renderscript32, .renderscript64, @@ -11978,7 +12059,5 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void { => {}, .spu_2 => unreachable, // LLVM does not support this backend - .spirv32 => unreachable, // LLVM does not support this backend - .spirv64 => unreachable, // LLVM does not support this backend } } |
