diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -577,8 +577,9 @@ CallParams.removeOperand(0); // For funcrefs, call_indirect is done through __funcref_call_table and the - // funcref is always installed in slot 0 of the table, therefore instead of having - // the function pointer added at the end of the params list, a zero (the index in + // funcref is always installed in slot 0 of the table, therefore instead of + // having the function pointer added at the end of the params list, a zero + // (the index in // __funcref_call_table is added). if (IsFuncrefCall) { Register RegZero = @@ -1156,7 +1157,7 @@ // If the callee is a GlobalAddress node (quite common, every direct call // is) turn it into a TargetGlobalAddress node so that LowerGlobalAddress // doesn't at MO_GOT which is not needed for direct calls. - GlobalAddressSDNode* GA = cast(Callee); + GlobalAddressSDNode *GA = cast(Callee); Callee = DAG.getTargetGlobalAddress(GA->getGlobal(), DL, getPointerTy(DAG.getDataLayout()), GA->getOffset()); @@ -1717,58 +1718,27 @@ report_fatal_error("cannot use thread-local storage without bulk memory", false); + // Here we assume that all TLS addresses are `localexec`--i.e., no dynamic + // linking in WebAssembly. In the future, if toolchains do support dynamic + // linking, this code will have to re-learn how to do this and users will have + // to override this default with `-ftls-model=...` and/or + // __attribute__((tls_model("...")))`. const GlobalValue *GV = GA->getGlobal(); + MVT PtrVT = getPointerTy(DAG.getDataLayout()); + auto GlobalGet = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64 + : WebAssembly::GLOBAL_GET_I32; + const char *BaseName = MF.createExternalSymbolName("__tls_base"); + SDValue BaseAddr( + DAG.getMachineNode(GlobalGet, DL, PtrVT, + DAG.getTargetExternalSymbol(BaseName, PtrVT)), + 0); - // Currently Emscripten does not support dynamic linking with threads. - // Therefore, if we have thread-local storage, only the local-exec model - // is possible. - // TODO: remove this and implement proper TLS models once Emscripten - // supports dynamic linking with threads. - if (GV->getThreadLocalMode() != GlobalValue::LocalExecTLSModel && - !Subtarget->getTargetTriple().isOSEmscripten()) { - report_fatal_error("only -ftls-model=local-exec is supported for now on " - "non-Emscripten OSes: variable " + - GV->getName(), - false); - } - - auto model = GV->getThreadLocalMode(); - - // Unsupported TLS modes - assert(model != GlobalValue::NotThreadLocal); - assert(model != GlobalValue::InitialExecTLSModel); - - if (model == GlobalValue::LocalExecTLSModel || - model == GlobalValue::LocalDynamicTLSModel || - (model == GlobalValue::GeneralDynamicTLSModel && - getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))) { - // For DSO-local TLS variables we use offset from __tls_base - - MVT PtrVT = getPointerTy(DAG.getDataLayout()); - auto GlobalGet = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64 - : WebAssembly::GLOBAL_GET_I32; - const char *BaseName = MF.createExternalSymbolName("__tls_base"); - - SDValue BaseAddr( - DAG.getMachineNode(GlobalGet, DL, PtrVT, - DAG.getTargetExternalSymbol(BaseName, PtrVT)), - 0); - - SDValue TLSOffset = DAG.getTargetGlobalAddress( - GV, DL, PtrVT, GA->getOffset(), WebAssemblyII::MO_TLS_BASE_REL); - SDValue SymOffset = - DAG.getNode(WebAssemblyISD::WrapperREL, DL, PtrVT, TLSOffset); + SDValue TLSOffset = DAG.getTargetGlobalAddress( + GV, DL, PtrVT, GA->getOffset(), WebAssemblyII::MO_TLS_BASE_REL); + SDValue SymOffset = + DAG.getNode(WebAssemblyISD::WrapperREL, DL, PtrVT, TLSOffset); - return DAG.getNode(ISD::ADD, DL, PtrVT, BaseAddr, SymOffset); - } - - assert(model == GlobalValue::GeneralDynamicTLSModel); - - EVT VT = Op.getValueType(); - return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT, - DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, - GA->getOffset(), - WebAssemblyII::MO_GOT_TLS)); + return DAG.getNode(ISD::ADD, DL, PtrVT, BaseAddr, SymOffset); } SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op, @@ -1791,8 +1761,7 @@ if (GV->getValueType()->isFunctionTy()) { BaseName = MF.createExternalSymbolName("__table_base"); OperandFlags = WebAssemblyII::MO_TABLE_BASE_REL; - } - else { + } else { BaseName = MF.createExternalSymbolName("__memory_base"); OperandFlags = WebAssemblyII::MO_MEMORY_BASE_REL; }