authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-25 13:17:25-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-01-25 13:17:25-08:00
log8fa47bb904c888dadf20af5eb72b9643eed2bfea
tree47fcc20146a7358b4216668d91c78d3bb712511d
parent015a5e198246f782415586235e0da7085867eb22
parentb60e39fe8f50783509e3cfe7a3888e1611b063c1
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22230 from alexrp/lto-stuff

Disable LTO by default + some LTO fixes

19 files changed, 129 insertions(+), 124 deletions(-)

lib/compiler_rt/arm.zig+24-12
...@@ -15,11 +15,11 @@ comptime {...@@ -15,11 +15,11 @@ comptime {
15 @export(&__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage, .visibility = common.visibility });15 @export(&__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage, .visibility = common.visibility });
16 @export(&__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage, .visibility = common.visibility });16 @export(&__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage, .visibility = common.visibility });
1717
18 @export(&__aeabi_ldivmod, .{ .name = if (target.isMinGW()) "__rt_sdiv64" else "__aeabi_ldivmod", .linkage = common.linkage, .visibility = common.visibility });18 @export(&__aeabi_ldivmod, .{ .name = if (common.want_windows_arm_abi) "__rt_sdiv64" else "__aeabi_ldivmod", .linkage = common.linkage, .visibility = common.visibility });
19 @export(&__aeabi_uldivmod, .{ .name = if (target.isMinGW()) "__rt_udiv64" else "__aeabi_uldivmod", .linkage = common.linkage, .visibility = common.visibility });19 @export(&__aeabi_uldivmod, .{ .name = if (common.want_windows_arm_abi) "__rt_udiv64" else "__aeabi_uldivmod", .linkage = common.linkage, .visibility = common.visibility });
2020
21 @export(&__aeabi_idivmod, .{ .name = if (target.isMinGW()) "__rt_sdiv" else "__aeabi_idivmod", .linkage = common.linkage, .visibility = common.visibility });21 @export(&__aeabi_idivmod, .{ .name = if (common.want_windows_arm_abi) "__rt_sdiv" else "__aeabi_idivmod", .linkage = common.linkage, .visibility = common.visibility });
22 @export(&__aeabi_uidivmod, .{ .name = if (target.isMinGW()) "__rt_udiv" else "__aeabi_uidivmod", .linkage = common.linkage, .visibility = common.visibility });22 @export(&__aeabi_uidivmod, .{ .name = if (common.want_windows_arm_abi) "__rt_udiv" else "__aeabi_uidivmod", .linkage = common.linkage, .visibility = common.visibility });
2323
24 @export(&__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = common.linkage, .visibility = common.visibility });24 @export(&__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = common.linkage, .visibility = common.visibility });
25 @export(&__aeabi_memcpy4, .{ .name = "__aeabi_memcpy4", .linkage = common.linkage, .visibility = common.visibility });25 @export(&__aeabi_memcpy4, .{ .name = "__aeabi_memcpy4", .linkage = common.linkage, .visibility = common.visibility });
...@@ -136,11 +136,14 @@ pub fn __aeabi_uidivmod() callconv(.Naked) void {...@@ -136,11 +136,14 @@ pub fn __aeabi_uidivmod() callconv(.Naked) void {
136 \\ push {lr}136 \\ push {lr}
137 \\ sub sp, #4137 \\ sub sp, #4
138 \\ mov r2, sp138 \\ mov r2, sp
139 \\ bl __udivmodsi4139 \\ bl %[__udivmodsi4]
140 \\ ldr r1, [sp]140 \\ ldr r1, [sp]
141 \\ add sp, #4141 \\ add sp, #4
142 \\ pop {pc}142 \\ pop {pc}
143 ::: "memory");143 :
144 : [__udivmodsi4] "X" (&__udivmodsi4),
145 : "memory"
146 );
144 unreachable;147 unreachable;
145}148}
146149
...@@ -152,12 +155,15 @@ pub fn __aeabi_uldivmod() callconv(.Naked) void {...@@ -152,12 +155,15 @@ pub fn __aeabi_uldivmod() callconv(.Naked) void {
152 \\ sub sp, #16155 \\ sub sp, #16
153 \\ add r4, sp, #8156 \\ add r4, sp, #8
154 \\ str r4, [sp]157 \\ str r4, [sp]
155 \\ bl __udivmoddi4158 \\ bl %[__udivmoddi4]
156 \\ ldr r2, [sp, #8]159 \\ ldr r2, [sp, #8]
157 \\ ldr r3, [sp, #12]160 \\ ldr r3, [sp, #12]
158 \\ add sp, #16161 \\ add sp, #16
159 \\ pop {r4, pc}162 \\ pop {r4, pc}
160 ::: "memory");163 :
164 : [__udivmoddi4] "X" (&__udivmoddi4),
165 : "memory"
166 );
161 unreachable;167 unreachable;
162}168}
163169
...@@ -168,11 +174,14 @@ pub fn __aeabi_idivmod() callconv(.Naked) void {...@@ -168,11 +174,14 @@ pub fn __aeabi_idivmod() callconv(.Naked) void {
168 \\ push {lr}174 \\ push {lr}
169 \\ sub sp, #4175 \\ sub sp, #4
170 \\ mov r2, sp176 \\ mov r2, sp
171 \\ bl __divmodsi4177 \\ bl %[__divmodsi4]
172 \\ ldr r1, [sp]178 \\ ldr r1, [sp]
173 \\ add sp, #4179 \\ add sp, #4
174 \\ pop {pc}180 \\ pop {pc}
175 ::: "memory");181 :
182 : [__divmodsi4] "X" (&__divmodsi4),
183 : "memory"
184 );
176 unreachable;185 unreachable;
177}186}
178187
...@@ -184,12 +193,15 @@ pub fn __aeabi_ldivmod() callconv(.Naked) void {...@@ -184,12 +193,15 @@ pub fn __aeabi_ldivmod() callconv(.Naked) void {
184 \\ sub sp, #16193 \\ sub sp, #16
185 \\ add r4, sp, #8194 \\ add r4, sp, #8
186 \\ str r4, [sp]195 \\ str r4, [sp]
187 \\ bl __divmoddi4196 \\ bl %[__divmoddi4]
188 \\ ldr r2, [sp, #8]197 \\ ldr r2, [sp, #8]
189 \\ ldr r3, [sp, #12]198 \\ ldr r3, [sp, #12]
190 \\ add sp, #16199 \\ add sp, #16
191 \\ pop {r4, pc}200 \\ pop {r4, pc}
192 ::: "memory");201 :
202 : [__divmoddi4] "X" (&__divmoddi4),
203 : "memory"
204 );
193 unreachable;205 unreachable;
194}206}
195207
lib/compiler_rt/aulldiv.zig+1-1
...@@ -8,7 +8,7 @@ const common = @import("common.zig");...@@ -8,7 +8,7 @@ const common = @import("common.zig");
8pub const panic = common.panic;8pub const panic = common.panic;
99
10comptime {10comptime {
11 if (arch == .x86 and os == .windows and (abi == .msvc or abi == .itanium) and builtin.zig_backend != .stage2_c) {11 if (arch == .x86 and os == .windows and (abi == .msvc or abi == .itanium) and !builtin.link_libc) {
12 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins12 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
13 @export(&_alldiv, .{ .name = "\x01__alldiv", .linkage = common.linkage, .visibility = common.visibility });13 @export(&_alldiv, .{ .name = "\x01__alldiv", .linkage = common.linkage, .visibility = common.visibility });
14 @export(&_aulldiv, .{ .name = "\x01__aulldiv", .linkage = common.linkage, .visibility = common.visibility });14 @export(&_aulldiv, .{ .name = "\x01__aulldiv", .linkage = common.linkage, .visibility = common.visibility });
lib/compiler_rt/aullrem.zig+1-1
...@@ -8,7 +8,7 @@ const common = @import("common.zig");...@@ -8,7 +8,7 @@ const common = @import("common.zig");
8pub const panic = common.panic;8pub const panic = common.panic;
99
10comptime {10comptime {
11 if (arch == .x86 and os == .windows and (abi == .msvc or abi == .itanium) and builtin.zig_backend != .stage2_c) {11 if (arch == .x86 and os == .windows and (abi == .msvc or abi == .itanium) and !builtin.link_libc) {
12 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins12 // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
13 @export(&_allrem, .{ .name = "\x01__allrem", .linkage = common.linkage, .visibility = common.visibility });13 @export(&_allrem, .{ .name = "\x01__allrem", .linkage = common.linkage, .visibility = common.visibility });
14 @export(&_aullrem, .{ .name = "\x01__aullrem", .linkage = common.linkage, .visibility = common.visibility });14 @export(&_aullrem, .{ .name = "\x01__aullrem", .linkage = common.linkage, .visibility = common.visibility });
lib/compiler_rt/common.zig+5-1
...@@ -9,11 +9,13 @@ else if (ofmt_c)...@@ -9,11 +9,13 @@ else if (ofmt_c)
9 .strong9 .strong
10else10else
11 .weak;11 .weak;
12
12/// Determines the symbol's visibility to other objects.13/// Determines the symbol's visibility to other objects.
13/// For WebAssembly this allows the symbol to be resolved to other modules, but will not14/// For WebAssembly this allows the symbol to be resolved to other modules, but will not
14/// export it to the host runtime.15/// export it to the host runtime.
15pub const visibility: std.builtin.SymbolVisibility =16pub const visibility: std.builtin.SymbolVisibility =
16 if (builtin.target.isWasm() and linkage != .internal) .hidden else .default;17 if (builtin.target.isWasm() and linkage != .internal) .hidden else .default;
18
17pub const want_aeabi = switch (builtin.abi) {19pub const want_aeabi = switch (builtin.abi) {
18 .eabi,20 .eabi,
19 .eabihf,21 .eabihf,
...@@ -29,7 +31,9 @@ pub const want_aeabi = switch (builtin.abi) {...@@ -29,7 +31,9 @@ pub const want_aeabi = switch (builtin.abi) {
29 },31 },
30 else => false,32 else => false,
31};33};
32pub const want_mingw_arm_abi = builtin.cpu.arch.isArm() and builtin.target.isMinGW();34
35/// These functions are provided by libc when targeting MSVC, but not MinGW.
36pub const want_windows_arm_abi = builtin.cpu.arch.isArm() and builtin.os.tag == .windows and (builtin.abi.isGnu() or !builtin.link_libc);
3337
34pub const want_ppc_abi = builtin.cpu.arch.isPowerPC();38pub const want_ppc_abi = builtin.cpu.arch.isPowerPC();
3539
lib/compiler_rt/fixdfdi.zig+1-5
...@@ -8,11 +8,7 @@ comptime {...@@ -8,11 +8,7 @@ comptime {
8 if (common.want_aeabi) {8 if (common.want_aeabi) {
9 @export(&__aeabi_d2lz, .{ .name = "__aeabi_d2lz", .linkage = common.linkage, .visibility = common.visibility });9 @export(&__aeabi_d2lz, .{ .name = "__aeabi_d2lz", .linkage = common.linkage, .visibility = common.visibility });
10 } else {10 } else {
11 @export(&__fixdfdi, .{ .name = "__fixdfdi", .linkage = common.linkage, .visibility = common.visibility });11 @export(&__fixdfdi, .{ .name = if (common.want_windows_arm_abi) "__dtoi64" else "__fixdfdi", .linkage = common.linkage, .visibility = common.visibility });
12
13 if (common.want_mingw_arm_abi) {
14 @export(&__fixdfdi, .{ .name = "__dtoi64", .linkage = common.linkage, .visibility = common.visibility });
15 }
16 }12 }
17}13}
1814
lib/compiler_rt/fixsfdi.zig+1-5
...@@ -8,11 +8,7 @@ comptime {...@@ -8,11 +8,7 @@ comptime {
8 if (common.want_aeabi) {8 if (common.want_aeabi) {
9 @export(&__aeabi_f2lz, .{ .name = "__aeabi_f2lz", .linkage = common.linkage, .visibility = common.visibility });9 @export(&__aeabi_f2lz, .{ .name = "__aeabi_f2lz", .linkage = common.linkage, .visibility = common.visibility });
10 } else {10 } else {
11 @export(&__fixsfdi, .{ .name = "__fixsfdi", .linkage = common.linkage, .visibility = common.visibility });11 @export(&__fixsfdi, .{ .name = if (common.want_windows_arm_abi) "__stoi64" else "__fixsfdi", .linkage = common.linkage, .visibility = common.visibility });
12
13 if (common.want_mingw_arm_abi) {
14 @export(&__fixsfdi, .{ .name = "__stoi64", .linkage = common.linkage, .visibility = common.visibility });
15 }
16 }12 }
17}13}
1814
lib/compiler_rt/fixunsdfdi.zig+1-5
...@@ -8,11 +8,7 @@ comptime {...@@ -8,11 +8,7 @@ comptime {
8 if (common.want_aeabi) {8 if (common.want_aeabi) {
9 @export(&__aeabi_d2ulz, .{ .name = "__aeabi_d2ulz", .linkage = common.linkage, .visibility = common.visibility });9 @export(&__aeabi_d2ulz, .{ .name = "__aeabi_d2ulz", .linkage = common.linkage, .visibility = common.visibility });
10 } else {10 } else {
11 @export(&__fixunsdfdi, .{ .name = "__fixunsdfdi", .linkage = common.linkage, .visibility = common.visibility });11 @export(&__fixunsdfdi, .{ .name = if (common.want_windows_arm_abi) "__dtou64" else "__fixunsdfdi", .linkage = common.linkage, .visibility = common.visibility });
12
13 if (common.want_mingw_arm_abi) {
14 @export(&__fixunsdfdi, .{ .name = "__dtou64", .linkage = common.linkage, .visibility = common.visibility });
15 }
16 }12 }
17}13}
1814
lib/compiler_rt/fixunssfdi.zig+1-5
...@@ -8,11 +8,7 @@ comptime {...@@ -8,11 +8,7 @@ comptime {
8 if (common.want_aeabi) {8 if (common.want_aeabi) {
9 @export(&__aeabi_f2ulz, .{ .name = "__aeabi_f2ulz", .linkage = common.linkage, .visibility = common.visibility });9 @export(&__aeabi_f2ulz, .{ .name = "__aeabi_f2ulz", .linkage = common.linkage, .visibility = common.visibility });
10 } else {10 } else {
11 @export(&__fixunssfdi, .{ .name = "__fixunssfdi", .linkage = common.linkage, .visibility = common.visibility });11 @export(&__fixunssfdi, .{ .name = if (common.want_windows_arm_abi) "__stou64" else "__fixunssfdi", .linkage = common.linkage, .visibility = common.visibility });
12
13 if (common.want_mingw_arm_abi) {
14 @export(&__fixunssfdi, .{ .name = "__stou64", .linkage = common.linkage, .visibility = common.visibility });
15 }
16 }12 }
17}13}
1814
lib/compiler_rt/floatdidf.zig+1-5
...@@ -8,11 +8,7 @@ comptime {...@@ -8,11 +8,7 @@ comptime {
8 if (common.want_aeabi) {8 if (common.want_aeabi) {
9 @export(&__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = common.linkage, .visibility = common.visibility });9 @export(&__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = common.linkage, .visibility = common.visibility });
10 } else {10 } else {
11 @export(&__floatdidf, .{ .name = "__floatdidf", .linkage = common.linkage, .visibility = common.visibility });11 @export(&__floatdidf, .{ .name = if (common.want_windows_arm_abi) "__i64tod" else "__floatdidf", .linkage = common.linkage, .visibility = common.visibility });
12
13 if (common.want_mingw_arm_abi) {
14 @export(&__floatdidf, .{ .name = "__i64tod", .linkage = common.linkage, .visibility = common.visibility });
15 }
16 }12 }
17}13}
1814
lib/compiler_rt/floatdisf.zig+1-5
...@@ -8,11 +8,7 @@ comptime {...@@ -8,11 +8,7 @@ comptime {
8 if (common.want_aeabi) {8 if (common.want_aeabi) {
9 @export(&__aeabi_l2f, .{ .name = "__aeabi_l2f", .linkage = common.linkage, .visibility = common.visibility });9 @export(&__aeabi_l2f, .{ .name = "__aeabi_l2f", .linkage = common.linkage, .visibility = common.visibility });
10 } else {10 } else {
11 @export(&__floatdisf, .{ .name = "__floatdisf", .linkage = common.linkage, .visibility = common.visibility });11 @export(&__floatdisf, .{ .name = if (common.want_windows_arm_abi) "__i64tos" else "__floatdisf", .linkage = common.linkage, .visibility = common.visibility });
12
13 if (common.want_mingw_arm_abi) {
14 @export(&__floatdisf, .{ .name = "__i64tos", .linkage = common.linkage, .visibility = common.visibility });
15 }
16 }12 }
17}13}
1814
lib/compiler_rt/floatundidf.zig+1-5
...@@ -8,11 +8,7 @@ comptime {...@@ -8,11 +8,7 @@ comptime {
8 if (common.want_aeabi) {8 if (common.want_aeabi) {
9 @export(&__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = common.linkage, .visibility = common.visibility });9 @export(&__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = common.linkage, .visibility = common.visibility });
10 } else {10 } else {
11 @export(&__floatundidf, .{ .name = "__floatundidf", .linkage = common.linkage, .visibility = common.visibility });11 @export(&__floatundidf, .{ .name = if (common.want_windows_arm_abi) "__u64tod" else "__floatundidf", .linkage = common.linkage, .visibility = common.visibility });
12
13 if (common.want_mingw_arm_abi) {
14 @export(&__floatundidf, .{ .name = "__u64tod", .linkage = common.linkage, .visibility = common.visibility });
15 }
16 }12 }
17}13}
1814
lib/compiler_rt/floatundisf.zig+1-5
...@@ -8,11 +8,7 @@ comptime {...@@ -8,11 +8,7 @@ comptime {
8 if (common.want_aeabi) {8 if (common.want_aeabi) {
9 @export(&__aeabi_ul2f, .{ .name = "__aeabi_ul2f", .linkage = common.linkage, .visibility = common.visibility });9 @export(&__aeabi_ul2f, .{ .name = "__aeabi_ul2f", .linkage = common.linkage, .visibility = common.visibility });
10 } else {10 } else {
11 @export(&__floatundisf, .{ .name = "__floatundisf", .linkage = common.linkage, .visibility = common.visibility });11 @export(&__floatundisf, .{ .name = if (common.want_windows_arm_abi) "__u64tos" else "__floatundisf", .linkage = common.linkage, .visibility = common.visibility });
12
13 if (common.want_mingw_arm_abi) {
14 @export(&__floatundisf, .{ .name = "__u64tos", .linkage = common.linkage, .visibility = common.visibility });
15 }
16 }12 }
17}13}
1814
src/Compilation.zig+15-16
...@@ -1881,18 +1881,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1881,18 +1881,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1881 comp.remaining_prelink_tasks += 1;1881 comp.remaining_prelink_tasks += 1;
1882 }1882 }
18831883
1884 if (target.isMinGW() and comp.config.any_non_single_threaded) {
1885 // LLD might drop some symbols as unused during LTO and GCing, therefore,
1886 // we force mark them for resolution here.
1887
1888 const tls_index_sym = switch (target.cpu.arch) {
1889 .x86 => "__tls_index",
1890 else => "_tls_index",
1891 };
1892
1893 try comp.force_undefined_symbols.put(comp.gpa, tls_index_sym, {});
1894 }
1895
1896 if (comp.include_compiler_rt and capable_of_building_compiler_rt) {1884 if (comp.include_compiler_rt and capable_of_building_compiler_rt) {
1897 if (is_exe_or_dyn_lib) {1885 if (is_exe_or_dyn_lib) {
1898 log.debug("queuing a job to build compiler_rt_lib", .{});1886 log.debug("queuing a job to build compiler_rt_lib", .{});
...@@ -3695,15 +3683,19 @@ fn performAllTheWorkInner(...@@ -3695,15 +3683,19 @@ fn performAllTheWorkInner(
3695 // In case it failed last time, try again. `clearMiscFailures` was already3683 // In case it failed last time, try again. `clearMiscFailures` was already
3696 // called at the start of `update`.3684 // called at the start of `update`.
3697 if (comp.queued_jobs.compiler_rt_lib and comp.compiler_rt_lib == null) {3685 if (comp.queued_jobs.compiler_rt_lib and comp.compiler_rt_lib == null) {
3698 comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Lib, &comp.compiler_rt_lib, main_progress_node });3686 // LLVM disables LTO for its compiler-rt and we've had various issues with LTO of our
3687 // compiler-rt due to LLD bugs as well, e.g.:
3688 //
3689 // https://github.com/llvm/llvm-project/issues/43698#issuecomment-2542660611
3690 comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Lib, false, &comp.compiler_rt_lib, main_progress_node });
3699 }3691 }
37003692
3701 if (comp.queued_jobs.compiler_rt_obj and comp.compiler_rt_obj == null) {3693 if (comp.queued_jobs.compiler_rt_obj and comp.compiler_rt_obj == null) {
3702 comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Obj, &comp.compiler_rt_obj, main_progress_node });3694 comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Obj, false, &comp.compiler_rt_obj, main_progress_node });
3703 }3695 }
37043696
3705 if (comp.queued_jobs.fuzzer_lib and comp.fuzzer_lib == null) {3697 if (comp.queued_jobs.fuzzer_lib and comp.fuzzer_lib == null) {
3706 comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "fuzzer.zig", .libfuzzer, .Lib, &comp.fuzzer_lib, main_progress_node });3698 comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "fuzzer.zig", .libfuzzer, .Lib, true, &comp.fuzzer_lib, main_progress_node });
3707 }3699 }
37083700
3709 if (comp.queued_jobs.glibc_shared_objects) {3701 if (comp.queued_jobs.glibc_shared_objects) {
...@@ -4635,12 +4627,14 @@ fn buildRt(...@@ -4635,12 +4627,14 @@ fn buildRt(
4635 root_source_name: []const u8,4627 root_source_name: []const u8,
4636 misc_task: MiscTask,4628 misc_task: MiscTask,
4637 output_mode: std.builtin.OutputMode,4629 output_mode: std.builtin.OutputMode,
4630 allow_lto: bool,
4638 out: *?CrtFile,4631 out: *?CrtFile,
4639 prog_node: std.Progress.Node,4632 prog_node: std.Progress.Node,
4640) void {4633) void {
4641 comp.buildOutputFromZig(4634 comp.buildOutputFromZig(
4642 root_source_name,4635 root_source_name,
4643 output_mode,4636 output_mode,
4637 allow_lto,
4644 out,4638 out,
4645 misc_task,4639 misc_task,
4646 prog_node,4640 prog_node,
...@@ -4748,6 +4742,7 @@ fn buildZigLibc(comp: *Compilation, prog_node: std.Progress.Node) void {...@@ -4748,6 +4742,7 @@ fn buildZigLibc(comp: *Compilation, prog_node: std.Progress.Node) void {
4748 comp.buildOutputFromZig(4742 comp.buildOutputFromZig(
4749 "c.zig",4743 "c.zig",
4750 .Lib,4744 .Lib,
4745 true,
4751 &comp.libc_static_lib,4746 &comp.libc_static_lib,
4752 .zig_libc,4747 .zig_libc,
4753 prog_node,4748 prog_node,
...@@ -6453,6 +6448,7 @@ fn buildOutputFromZig(...@@ -6453,6 +6448,7 @@ fn buildOutputFromZig(
6453 comp: *Compilation,6448 comp: *Compilation,
6454 src_basename: []const u8,6449 src_basename: []const u8,
6455 output_mode: std.builtin.OutputMode,6450 output_mode: std.builtin.OutputMode,
6451 allow_lto: bool,
6456 out: *?CrtFile,6452 out: *?CrtFile,
6457 misc_task_tag: MiscTask,6453 misc_task_tag: MiscTask,
6458 prog_node: std.Progress.Node,6454 prog_node: std.Progress.Node,
...@@ -6481,6 +6477,7 @@ fn buildOutputFromZig(...@@ -6481,6 +6477,7 @@ fn buildOutputFromZig(
6481 .root_strip = strip,6477 .root_strip = strip,
6482 .link_libc = comp.config.link_libc,6478 .link_libc = comp.config.link_libc,
6483 .any_unwind_tables = comp.root_mod.unwind_tables != .none,6479 .any_unwind_tables = comp.root_mod.unwind_tables != .none,
6480 .lto = if (allow_lto) comp.config.lto else .none,
6484 });6481 });
64856482
6486 const root_mod = try Package.Module.create(arena, .{6483 const root_mod = try Package.Module.create(arena, .{
...@@ -6581,6 +6578,8 @@ pub const CrtFileOptions = struct {...@@ -6581,6 +6578,8 @@ pub const CrtFileOptions = struct {
6581 unwind_tables: ?std.builtin.UnwindTables = null,6578 unwind_tables: ?std.builtin.UnwindTables = null,
6582 pic: ?bool = null,6579 pic: ?bool = null,
6583 no_builtin: ?bool = null,6580 no_builtin: ?bool = null,
6581
6582 allow_lto: bool = true,
6584};6583};
65856584
6586pub fn build_crt_file(6585pub fn build_crt_file(
...@@ -6619,7 +6618,7 @@ pub fn build_crt_file(...@@ -6619,7 +6618,7 @@ pub fn build_crt_file(
6619 .link_libc = false,6618 .link_libc = false,
6620 .any_unwind_tables = options.unwind_tables != .none,6619 .any_unwind_tables = options.unwind_tables != .none,
6621 .lto = switch (output_mode) {6620 .lto = switch (output_mode) {
6622 .Lib => comp.config.lto,6621 .Lib => if (options.allow_lto) comp.config.lto else .none,
6623 .Obj, .Exe => .none,6622 .Obj, .Exe => .none,
6624 },6623 },
6625 });6624 });
src/Compilation/Config.zig+1-20
...@@ -295,27 +295,8 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -295,27 +295,8 @@ pub fn resolve(options: Options) ResolveError!Config {
295 }295 }
296296
297 if (options.lto) |x| break :b x;297 if (options.lto) |x| break :b x;
298 if (!options.any_c_source_files) break :b .none;
299
300 // https://github.com/llvm/llvm-project/pull/116537
301 switch (target.abi) {
302 .gnuabin32,
303 .gnuilp32,
304 .gnux32,
305 .ilp32,
306 .muslabin32,
307 .muslx32,
308 => break :b .none,
309 else => {},
310 }
311298
312 break :b switch (options.output_mode) {299 break :b .none;
313 .Lib, .Obj => .none,
314 .Exe => switch (root_optimize_mode) {
315 .Debug => .none,
316 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => .full,
317 },
318 };
319 };300 };
320301
321 const link_libcpp = b: {302 const link_libcpp = b: {
src/libtsan.zig+6
...@@ -53,6 +53,8 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -53,6 +53,8 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
53 const optimize_mode = comp.compilerRtOptMode();53 const optimize_mode = comp.compilerRtOptMode();
54 const strip = comp.compilerRtStrip();54 const strip = comp.compilerRtStrip();
55 const link_libcpp = target.isDarwin();55 const link_libcpp = target.isDarwin();
56 const unwind_tables: std.builtin.UnwindTables =
57 if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .@"async";
5658
57 const config = Compilation.Config.resolve(.{59 const config = Compilation.Config.resolve(.{
58 .output_mode = output_mode,60 .output_mode = output_mode,
...@@ -65,6 +67,9 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -65,6 +67,9 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
65 .root_strip = strip,67 .root_strip = strip,
66 .link_libc = true,68 .link_libc = true,
67 .link_libcpp = link_libcpp,69 .link_libcpp = link_libcpp,
70 .any_unwind_tables = unwind_tables != .none,
71 // LLVM disables LTO for its libtsan.
72 .lto = .none,
68 }) catch |err| {73 }) catch |err| {
69 comp.setMiscFailure(74 comp.setMiscFailure(
70 .libtsan,75 .libtsan,
...@@ -95,6 +100,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -95,6 +100,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
95 .red_zone = comp.root_mod.red_zone,100 .red_zone = comp.root_mod.red_zone,
96 .omit_frame_pointer = optimize_mode != .Debug and !target.os.tag.isDarwin(),101 .omit_frame_pointer = optimize_mode != .Debug and !target.os.tag.isDarwin(),
97 .valgrind = false,102 .valgrind = false,
103 .unwind_tables = unwind_tables,
98 .optimize_mode = optimize_mode,104 .optimize_mode = optimize_mode,
99 .structured_cfg = comp.root_mod.structured_cfg,105 .structured_cfg = comp.root_mod.structured_cfg,
100 .pic = true,106 .pic = true,
src/link/Coff.zig+7
...@@ -1876,6 +1876,13 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:...@@ -1876,6 +1876,13 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
1876 if (comp.version) |version| {1876 if (comp.version) |version| {
1877 try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor }));1877 try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor }));
1878 }1878 }
1879
1880 if (target_util.llvmMachineAbi(target)) |mabi| {
1881 try argv.append(try allocPrint(arena, "-MLLVM:-target-abi={s}", .{mabi}));
1882 }
1883
1884 try argv.append(try allocPrint(arena, "-MLLVM:-float-abi={s}", .{if (target.abi.floatAbi() == .hard) "hard" else "soft"}));
1885
1879 if (comp.config.lto != .none) {1886 if (comp.config.lto != .none) {
1880 switch (optimize_mode) {1887 switch (optimize_mode) {
1881 .Debug => {},1888 .Debug => {},
src/link/Elf.zig+12
...@@ -1700,6 +1700,18 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s...@@ -1700,6 +1700,18 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
1700 try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));1700 try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));
1701 }1701 }
17021702
1703 if (target_util.llvmMachineAbi(target)) |mabi| {
1704 try argv.appendSlice(&.{
1705 "-mllvm",
1706 try std.fmt.allocPrint(arena, "-target-abi={s}", .{mabi}),
1707 });
1708 }
1709
1710 try argv.appendSlice(&.{
1711 "-mllvm",
1712 try std.fmt.allocPrint(arena, "-float-abi={s}", .{if (target.abi.floatAbi() == .hard) "hard" else "soft"}),
1713 });
1714
1703 if (comp.config.lto != .none) {1715 if (comp.config.lto != .none) {
1704 switch (comp.root_mod.optimize_mode) {1716 switch (comp.root_mod.optimize_mode) {
1705 .Debug => {},1717 .Debug => {},
src/mingw.zig+2
...@@ -175,6 +175,8 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -175,6 +175,8 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
175175
176 return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items, .{176 return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items, .{
177 .unwind_tables = unwind_tables,177 .unwind_tables = unwind_tables,
178 // https://github.com/llvm/llvm-project/issues/43698#issuecomment-2542660611
179 .allow_lto = false,
178 });180 });
179 },181 },
180 }182 }
src/target.zig+47-33
...@@ -482,16 +482,6 @@ pub fn arePointersLogical(target: std.Target, as: AddressSpace) bool {...@@ -482,16 +482,6 @@ pub fn arePointersLogical(target: std.Target, as: AddressSpace) bool {
482}482}
483483
484pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {484pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
485 // This special-casing should be removed with LLVM 20.
486 switch (target.cpu.arch) {
487 .mips, .mipsel => return "o32",
488 .mips64, .mips64el => return switch (target.abi) {
489 .gnuabin32, .muslabin32 => "n32",
490 else => "n64",
491 },
492 else => {},
493 }
494
495 // LLD does not support ELFv1. Rather than having LLVM produce ELFv1 code and then linking it485 // LLD does not support ELFv1. Rather than having LLVM produce ELFv1 code and then linking it
496 // into a broken ELFv2 binary, just force LLVM to use ELFv2 as well. This will break when glibc486 // into a broken ELFv2 binary, just force LLVM to use ELFv2 as well. This will break when glibc
497 // is linked as glibc only supports ELFv2 for little endian, but there's nothing we can do about487 // is linked as glibc only supports ELFv2 for little endian, but there's nothing we can do about
...@@ -500,33 +490,57 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {...@@ -500,33 +490,57 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
500 // Once our self-hosted linker can handle both ABIs, this hack should go away.490 // Once our self-hosted linker can handle both ABIs, this hack should go away.
501 if (target.cpu.arch == .powerpc64) return "elfv2";491 if (target.cpu.arch == .powerpc64) return "elfv2";
502492
503 switch (target.cpu.arch) {493 return switch (target.cpu.arch) {
504 .riscv64 => {494 .arm, .armeb, .thumb, .thumbeb => "aapcs",
495 // TODO: `muslsf` and `muslf32` in LLVM 20.
496 .loongarch64 => switch (target.abi) {
497 .gnusf => "lp64s",
498 .gnuf32 => "lp64f",
499 else => "lp64d",
500 },
501 .loongarch32 => switch (target.abi) {
502 .gnusf => "ilp32s",
503 .gnuf32 => "ilp32f",
504 else => "ilp32d",
505 },
506 .mips, .mipsel => "o32",
507 .mips64, .mips64el => switch (target.abi) {
508 .gnuabin32, .muslabin32 => "n32",
509 else => "n64",
510 },
511 .powerpc64 => switch (target.os.tag) {
512 .freebsd => if (target.os.version_range.semver.isAtLeast(.{ .major = 13, .minor = 0, .patch = 0 }) orelse false)
513 "elfv2"
514 else
515 "elfv1",
516 .openbsd => "elfv2",
517 else => if (target.abi.isMusl()) "elfv2" else "elfv1",
518 },
519 .powerpc64le => "elfv2",
520 .riscv64 => b: {
505 const featureSetHas = std.Target.riscv.featureSetHas;521 const featureSetHas = std.Target.riscv.featureSetHas;
506 if (featureSetHas(target.cpu.features, .e)) {522 break :b if (featureSetHas(target.cpu.features, .e))
507 return "lp64e";523 "lp64e"
508 } else if (featureSetHas(target.cpu.features, .d)) {524 else if (featureSetHas(target.cpu.features, .d))
509 return "lp64d";525 "lp64d"
510 } else if (featureSetHas(target.cpu.features, .f)) {526 else if (featureSetHas(target.cpu.features, .f))
511 return "lp64f";527 "lp64f"
512 } else {528 else
513 return "lp64";529 "lp64";
514 }
515 },530 },
516 .riscv32 => {531 .riscv32 => b: {
517 const featureSetHas = std.Target.riscv.featureSetHas;532 const featureSetHas = std.Target.riscv.featureSetHas;
518 if (featureSetHas(target.cpu.features, .e)) {533 break :b if (featureSetHas(target.cpu.features, .e))
519 return "ilp32e";534 "ilp32e"
520 } else if (featureSetHas(target.cpu.features, .d)) {535 else if (featureSetHas(target.cpu.features, .d))
521 return "ilp32d";536 "ilp32d"
522 } else if (featureSetHas(target.cpu.features, .f)) {537 else if (featureSetHas(target.cpu.features, .f))
523 return "ilp32f";538 "ilp32f"
524 } else {539 else
525 return "ilp32";540 "ilp32";
526 }
527 },541 },
528 else => return null,542 else => null,
529 }543 };
530}544}
531545
532/// This function returns 1 if function alignment is not observable or settable. Note that this546/// This function returns 1 if function alignment is not observable or settable. Note that this