From 1c5a3c4d382353e582ecf4913e338599028e267f Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 24 Sep 2020 14:56:19 -0700 Subject: [PATCH] [WebAssembly] Make SjLj lowering globals thread-local Emscripten's longjump and exception mechanism depends on two global variables, `__THREW__` and `__threwValue`, which are changed to be defined as thread-local in https://github.com/emscripten-core/emscripten/pull/12056. This patch updates the corresponding code in the WebAssembly backend to properly declare these globals as thread-local as well. Differential Revision: https://reviews.llvm.org/D88262 --- .../Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp | 9 ++++++--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp | 12 ++++++------ llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll | 4 ++-- llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp index 5fce4a6..cfea7c8c 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -315,9 +315,12 @@ static bool canThrow(const Value *V) { // which will generate an import and asssumes that it will exist at link time. static GlobalVariable *getGlobalVariableI32(Module &M, IRBuilder<> &IRB, const char *Name) { - - auto *GV = - dyn_cast(M.getOrInsertGlobal(Name, IRB.getInt32Ty())); + auto Int32Ty = IRB.getInt32Ty(); + auto *GV = dyn_cast(M.getOrInsertGlobal(Name, Int32Ty, [&]() { + return new GlobalVariable(M, Int32Ty, false, + GlobalVariable::ExternalLinkage, nullptr, Name, + nullptr, GlobalValue::LocalExecTLSModel); + })); if (!GV) report_fatal_error(Twine("unable to create global: ") + Name); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 6e88530..60a7dee 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -348,12 +348,6 @@ FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) { //===----------------------------------------------------------------------===// void WebAssemblyPassConfig::addIRPasses() { - // Runs LowerAtomicPass if necessary - addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine())); - - // This is a no-op if atomics are not used in the module - addPass(createAtomicExpandPass()); - // Add signatures to prototype-less function declarations addPass(createWebAssemblyAddMissingPrototypes()); @@ -389,6 +383,12 @@ void WebAssemblyPassConfig::addIRPasses() { // Expand indirectbr instructions to switches. addPass(createIndirectBrExpandPass()); + // Lower atomics and TLS if necessary + addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine())); + + // This is a no-op if atomics are not used in the module + addPass(createAtomicExpandPass()); + TargetPassConfig::addIRPasses(); } diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll index 1f98310..fa55117 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll @@ -5,8 +5,8 @@ target triple = "wasm32-unknown-unknown" @_ZTIi = external constant i8* @_ZTIc = external constant i8* -; CHECK-DAG: __THREW__ = external global i32 -; CHECK-DAG: __threwValue = external global i32 +; CHECK-DAG: __THREW__ = external thread_local(localexec) global i32 +; CHECK-DAG: __threwValue = external thread_local(localexec) global i32 ; Test invoke instruction with clauses (try-catch block) define void @clause() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll index 2a6d92e..89910e721 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll @@ -6,8 +6,8 @@ target triple = "wasm32-unknown-unknown" %struct.__jmp_buf_tag = type { [6 x i32], i32, [32 x i32] } @global_var = global i32 0, align 4 -; CHECK-DAG: __THREW__ = external global i32 -; CHECK-DAG: __threwValue = external global i32 +; CHECK-DAG: __THREW__ = external thread_local(localexec) global i32 +; CHECK-DAG: __threwValue = external thread_local(localexec) global i32 ; Test a simple setjmp - longjmp sequence define void @setjmp_longjmp() { -- 2.7.4