diff --git a/lld/test/wasm/relocation-bad-tls.s b/lld/test/wasm/relocation-bad-tls.s --- a/lld/test/wasm/relocation-bad-tls.s +++ b/lld/test/wasm/relocation-bad-tls.s @@ -6,6 +6,8 @@ .functype _start () -> () i32.const foo@TLSREL i32.const bar@TLSREL + i32.const baz@TLSREL + drop drop drop end_function @@ -24,3 +26,4 @@ # CHECK: relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against `foo` in non-TLS section: .data # CHECK: relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against `bar` in non-TLS section: .bss +# CHECK: relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against an undefined symbol `baz` diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp --- a/lld/wasm/Relocations.cpp +++ b/lld/wasm/Relocations.cpp @@ -112,6 +112,11 @@ break; case R_WASM_MEMORY_ADDR_TLS_SLEB: case R_WASM_MEMORY_ADDR_TLS_SLEB64: + if (!sym->isDefined()) { + error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) + + " cannot be used against an undefined symbol `" + toString(*sym) + + "`"); + } // In single-threaded builds TLS is lowered away and TLS data can be // merged with normal data and allowing TLS relocation in non-TLS // segments. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -422,7 +422,7 @@ // shared-memory module, which we don't want to be responsible for. auto *Subtarget = TM.getSubtargetImpl(); auto TLS = Subtarget->hasAtomics() && Subtarget->hasBulkMemory() - ? GlobalValue::LocalExecTLSModel + ? GlobalValue::GeneralDynamicTLSModel : GlobalValue::NotThreadLocal; GV->setThreadLocalMode(TLS); return GV; diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll --- a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll @@ -9,8 +9,8 @@ @_ZTIc = external constant i8* ; NO-TLS-DAG: __THREW__ = external global [[PTR]] ; NO-TLS-DAG: __threwValue = external global i32 -; TLS-DAG: __THREW__ = external thread_local(localexec) global [[PTR]] -; TLS-DAG: __threwValue = external thread_local(localexec) global i32 +; TLS-DAG: __THREW__ = external thread_local global [[PTR]] +; TLS-DAG: __threwValue = external thread_local 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 --- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll @@ -10,8 +10,8 @@ @global_var = global i32 0, align 4 ; NO-TLS-DAG: __THREW__ = external global [[PTR]] ; NO-TLS-DAG: __threwValue = external global [[PTR]] -; TLS-DAG: __THREW__ = external thread_local(localexec) global i32 -; TLS-DAG: __threwValue = external thread_local(localexec) global i32 +; TLS-DAG: __THREW__ = external thread_local global i32 +; TLS-DAG: __threwValue = external thread_local global i32 @global_longjmp_ptr = global void (%struct.__jmp_buf_tag*, i32)* @longjmp, align 4 ; CHECK-DAG: @global_longjmp_ptr = global void (%struct.__jmp_buf_tag*, i32)* bitcast (void ([[PTR]], i32)* @emscripten_longjmp to void (%struct.__jmp_buf_tag*, i32)*)