diff --git a/llvm/lib/CodeGen/WasmEHPrepare.cpp b/llvm/lib/CodeGen/WasmEHPrepare.cpp index c04a7b28eff9de..6b7df758e45799 100644 --- a/llvm/lib/CodeGen/WasmEHPrepare.cpp +++ b/llvm/lib/CodeGen/WasmEHPrepare.cpp @@ -212,9 +212,21 @@ bool WasmEHPrepare::prepareEHPads(Function &F) { assert(F.hasPersonalityFn() && "Personality function not found"); - // __wasm_lpad_context global variable + // __wasm_lpad_context global variable. + // If the target supports TLS, make this thread-local. We can't just + // unconditionally make it thread-local and depend on + // CoalesceFeaturesAndStripAtomics to downgrade it, because stripping TLS has + // the side effect of disallowing the object from being linked into a + // shared-memory module, which we don't want to be responsible for. LPadContextGV = cast( M.getOrInsertGlobal("__wasm_lpad_context", LPadContextTy)); + Attribute FSAttr = F.getFnAttribute("target-features"); + if (FSAttr.isValid()) { + StringRef FS = FSAttr.getValueAsString(); + if (FS.contains("+atomics") && FS.contains("+bulk-memory")) + LPadContextGV->setThreadLocalMode(GlobalValue::GeneralDynamicTLSModel); + } + LPadIndexField = IRB.CreateConstGEP2_32(LPadContextTy, LPadContextGV, 0, 0, "lpad_index_gep"); LSDAField = diff --git a/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll b/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll index 63bdf2c6bea086..081a9776fa9aae 100644 --- a/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll +++ b/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll @@ -1,9 +1,11 @@ -; RUN: opt < %s -winehprepare -demote-catchswitch-only -wasmehprepare -S | FileCheck %s +; RUN: opt < %s -winehprepare -demote-catchswitch-only -wasmehprepare -S | FileCheck %s --check-prefixes=CHECK,NO-TLS +; RUN: opt < %s -winehprepare -demote-catchswitch-only -wasmehprepare -S --mattr=+atomics,+bulk-memory | FileCheck %s --check-prefixes=CHECK,TLS target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" -; CHECK: @__wasm_lpad_context = external global { i32, i8*, i32 } +; NO-TLS: @__wasm_lpad_context = external global { i32, i8*, i32 } +; TLS: @__wasm_lpad_context = external thread_local global { i32, i8*, i32 } @_ZTIi = external constant i8* %struct.Temp = type { i8 }