From b5cc658ab4113b4db4f709dbec258910696990bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 6 Jul 2025 22:19:08 +0200 Subject: [PATCH] llvm: Use emulated TLS when appropriate for the target Closes #24236. --- src/codegen/llvm.zig | 1 + src/codegen/llvm/bindings.zig | 1 + src/main.zig | 2 +- src/target.zig | 13 +++++++++++++ src/zig_llvm.cpp | 6 +++++- src/zig_llvm.h | 2 +- 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 27092a1de8..db628eab5d 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1047,6 +1047,7 @@ pub const Object = struct { comp.data_sections, float_abi, if (target_util.llvmMachineAbi(&comp.root_mod.resolved_target.result)) |s| s.ptr else null, + target_util.useEmulatedTls(&comp.root_mod.resolved_target.result), ); errdefer target_machine.dispose(); diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index 5d2d4c2a99..7fa2a7da43 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -79,6 +79,7 @@ pub const TargetMachine = opaque { data_sections: bool, float_abi: FloatABI, abi_name: ?[*:0]const u8, + emulated_tls: bool, ) *TargetMachine; pub const dispose = LLVMDisposeTargetMachine; diff --git a/src/main.zig b/src/main.zig index 7b7d5be59a..aa20b8fae1 100644 --- a/src/main.zig +++ b/src/main.zig @@ -6324,7 +6324,7 @@ fn cmdDumpLlvmInts( if (llvm.Target.getFromTriple(triple, &target, &error_message) != .False) @panic("bad"); break :t target; }; - const tm = llvm.TargetMachine.create(target, triple, null, null, .None, .Default, .Default, false, false, .Default, null); + const tm = llvm.TargetMachine.create(target, triple, null, null, .None, .Default, .Default, false, false, .Default, null, false); const dl = tm.createTargetDataLayout(); const context = llvm.Context.create(); diff --git a/src/target.zig b/src/target.zig index 28cdf3e3aa..7852dda7a4 100644 --- a/src/target.zig +++ b/src/target.zig @@ -85,6 +85,19 @@ pub fn defaultSingleThreaded(target: *const std.Target) bool { return false; } +pub fn useEmulatedTls(target: *const std.Target) bool { + if (target.abi.isAndroid()) { + if (target.os.version_range.linux.android < 29) return true; + return false; + } + if (target.abi.isOpenHarmony()) return true; + return switch (target.os.tag) { + .openbsd => true, + .windows => target.abi == .cygnus, + else => false, + }; +} + pub fn hasValgrindSupport(target: *const std.Target, backend: std.builtin.CompilerBackend) bool { // We can't currently output the necessary Valgrind client request assembly when using the C // backend and compiling with an MSVC-like compiler. diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index fe4e421dc3..c9a30bb167 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -83,7 +83,7 @@ static const bool assertions_on = false; LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, LLVMCodeModel CodeModel, bool function_sections, bool data_sections, ZigLLVMFloatABI float_abi, - const char *abi_name) + const char *abi_name, bool emulated_tls) { std::optional RM; switch (Reloc){ @@ -149,6 +149,10 @@ LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Tri opt.MCOptions.ABIName = abi_name; } + if (emulated_tls) { + opt.EmulatedTLS = true; + } + TargetMachine *TM = reinterpret_cast(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM, OL, JIT); return reinterpret_cast(TM); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index e2dba338c3..db331512bd 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -105,7 +105,7 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, LLVMCodeModel CodeModel, bool function_sections, bool data_sections, ZigLLVMFloatABI float_abi, - const char *abi_name); + const char *abi_name, bool emulated_tls); ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit);