[llvm] a28a466 - [WebAssembly] Add new relocation type for TLS data symbols

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 13 08:00:29 PST 2020


Author: Sam Clegg
Date: 2020-11-13T07:59:29-08:00
New Revision: a28a466210199559d38251c11f30515cc83eadd6

URL: https://github.com/llvm/llvm-project/commit/a28a466210199559d38251c11f30515cc83eadd6
DIFF: https://github.com/llvm/llvm-project/commit/a28a466210199559d38251c11f30515cc83eadd6.diff

LOG: [WebAssembly] Add new relocation type for TLS data symbols

These relocations represent offsets from the __tls_base symbol.

Previously we were just using normal MEMORY_ADDR relocations and relying
on the linker to select a segment-offset rather and absolute value in
Symbol::getVirtualAddress().  Using an explicit relocation type allows
allow us to clearly distinguish absolute from relative relocations based
on the relocation information alone.

One place this is useful is being able to reject absolute relocation in
the PIC case, but still accept TLS relocations.

Differential Revision: https://reviews.llvm.org/D91276

Added: 
    lld/test/wasm/relocation-bad-tls.s
    llvm/test/MC/WebAssembly/tls.s

Modified: 
    lld/test/wasm/tls.s
    lld/wasm/InputChunks.cpp
    lld/wasm/InputFiles.cpp
    lld/wasm/OutputSections.cpp
    lld/wasm/Relocations.cpp
    lld/wasm/Symbols.cpp
    lld/wasm/Writer.cpp
    llvm/include/llvm/BinaryFormat/WasmRelocs.def
    llvm/include/llvm/MC/MCExpr.h
    llvm/lib/BinaryFormat/Wasm.cpp
    llvm/lib/MC/MCExpr.cpp
    llvm/lib/MC/WasmObjectWriter.cpp
    llvm/lib/Object/WasmObjectFile.cpp
    llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
    llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
    llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
    llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll
    llvm/test/CodeGen/WebAssembly/tls-local-exec.ll

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/relocation-bad-tls.s b/lld/test/wasm/relocation-bad-tls.s
new file mode 100644
index 000000000000..3d3e04f64d1a
--- /dev/null
+++ b/lld/test/wasm/relocation-bad-tls.s
@@ -0,0 +1,24 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: not wasm-ld %t.o -o out.wasm 2>&1 | FileCheck %s
+
+.globl _start
+_start:
+  .functype _start () -> ()
+  i32.const foo at TLSREL
+  i32.const bar at TLSREL
+  end_function
+
+.section  .data,"",@
+.globl  foo
+foo:
+  .int32  0
+  .size foo, 4
+
+.section  .bss,"",@
+.globl  bar
+bar:
+  .int32  0
+  .size bar, 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

diff  --git a/lld/test/wasm/tls.s b/lld/test/wasm/tls.s
index 0f6d42e65ac2..a84dd32ebc7d 100644
--- a/lld/test/wasm/tls.s
+++ b/lld/test/wasm/tls.s
@@ -7,7 +7,7 @@
 tls1_addr:
   .functype tls1_addr () -> (i32)
   global.get __tls_base
-  i32.const tls1
+  i32.const tls1 at TLSREL
   i32.add
   end_function
 
@@ -15,7 +15,7 @@ tls1_addr:
 tls2_addr:
   .functype tls2_addr () -> (i32)
   global.get __tls_base
-  i32.const tls2
+  i32.const tls2 at TLSREL
   i32.add
   end_function
 

diff  --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index ddbdb90c44f4..f33178f29b31 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -79,6 +79,7 @@ void InputChunk::verifyRelocTargets() const {
     case R_WASM_TABLE_INDEX_REL_SLEB:
     case R_WASM_MEMORY_ADDR_SLEB:
     case R_WASM_MEMORY_ADDR_REL_SLEB:
+    case R_WASM_MEMORY_ADDR_TLS_SLEB:
       existingValue = static_cast<uint64_t>(decodeSLEB128(loc, &bytesRead));
       break;
     case R_WASM_TABLE_INDEX_SLEB64:
@@ -158,6 +159,7 @@ void InputChunk::writeTo(uint8_t *buf) const {
     case R_WASM_TABLE_INDEX_REL_SLEB:
     case R_WASM_MEMORY_ADDR_SLEB:
     case R_WASM_MEMORY_ADDR_REL_SLEB:
+    case R_WASM_MEMORY_ADDR_TLS_SLEB:
       encodeSLEB128(static_cast<int32_t>(value), loc, 5);
       break;
     case R_WASM_TABLE_INDEX_SLEB64:

diff  --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index 36df781c041d..3cf177532d84 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -11,6 +11,7 @@
 #include "InputChunks.h"
 #include "InputEvent.h"
 #include "InputGlobal.h"
+#include "OutputSegment.h"
 #include "SymbolTable.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
@@ -154,7 +155,8 @@ uint64_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const {
   case R_WASM_MEMORY_ADDR_REL_SLEB:
   case R_WASM_MEMORY_ADDR_REL_SLEB64:
   case R_WASM_MEMORY_ADDR_I32:
-  case R_WASM_MEMORY_ADDR_I64: {
+  case R_WASM_MEMORY_ADDR_I64:
+  case R_WASM_MEMORY_ADDR_TLS_SLEB: {
     const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
     if (sym.isUndefined())
       return 0;
@@ -227,10 +229,24 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc) const {
   case R_WASM_MEMORY_ADDR_REL_SLEB:
   case R_WASM_MEMORY_ADDR_REL_SLEB64:
   case R_WASM_MEMORY_ADDR_I32:
-  case R_WASM_MEMORY_ADDR_I64:
+  case R_WASM_MEMORY_ADDR_I64: {
+    if (isa<UndefinedData>(sym) || sym->isUndefWeak())
+      return 0;
+    auto D = cast<DefinedData>(sym);
+    // Treat non-TLS relocation against symbols that live in the TLS segment
+    // like TLS relocations.  This beaviour exists to support older object
+    // files created before we introduced TLS relocations.
+    // TODO(sbc): Remove this legacy behaviour one day.  This will break
+    // backward compat with old object files built with `-fPIC`.
+    if (D->segment && D->segment->outputSeg->name == ".tdata")
+      return D->getOutputSegmentOffset() + reloc.Addend;
+    return D->getVirtualAddress() + reloc.Addend;
+  }
+  case R_WASM_MEMORY_ADDR_TLS_SLEB:
     if (isa<UndefinedData>(sym) || sym->isUndefWeak())
       return 0;
-    return cast<DefinedData>(sym)->getVirtualAddress() + reloc.Addend;
+    // TLS relocations are relative to the start of the TLS output segment
+    return cast<DefinedData>(sym)->getOutputSegmentOffset() + reloc.Addend;
   case R_WASM_TYPE_INDEX_LEB:
     return typeMap[reloc.Index];
   case R_WASM_FUNCTION_INDEX_LEB:

diff  --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index dbdabddb9320..fca9bd79296c 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -133,13 +133,20 @@ void DataSection::finalizeContents() {
       std::count_if(segments.begin(), segments.end(),
                     [](OutputSegment *segment) { return !segment->isBss; });
 
+#ifndef NDEBUG
+  unsigned activeCount = std::count_if(
+      segments.begin(), segments.end(), [](OutputSegment *segment) {
+        return (segment->initFlags & WASM_SEGMENT_IS_PASSIVE) == 0;
+      });
+#endif
+
+  assert((!config->isPic || activeCount <= 1) &&
+         "Currenly only a single data segment is supported in PIC mode");
+
   writeUleb128(os, segmentCount, "data segment count");
   os.flush();
   bodySize = dataSectionHeader.size();
 
-  assert((!config->isPic || segments.size() <= 1) &&
-         "Currenly only a single data segment is supported in PIC mode");
-
   for (OutputSegment *segment : segments) {
     if (segment->isBss)
       continue;

diff  --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp
index eec33b670127..5d6e82b412a3 100644
--- a/lld/wasm/Relocations.cpp
+++ b/lld/wasm/Relocations.cpp
@@ -9,6 +9,7 @@
 #include "Relocations.h"
 
 #include "InputChunks.h"
+#include "OutputSegment.h"
 #include "SyntheticSections.h"
 
 using namespace llvm;
@@ -88,6 +89,16 @@ void scanRelocations(InputChunk *chunk) {
       if (!isa<GlobalSymbol>(sym))
         addGOTEntry(sym);
       break;
+    case R_WASM_MEMORY_ADDR_TLS_SLEB:
+      if (auto *D = dyn_cast<DefinedData>(sym)) {
+        if (D->segment->outputSeg->name != ".tdata") {
+          error(toString(file) + ": relocation " +
+                relocTypeToString(reloc.Type) + " cannot be used against `" +
+                toString(*sym) +
+                "` in non-TLS section: " + D->segment->outputSeg->name);
+        }
+      }
+      break;
     }
 
     if (config->isPic) {

diff  --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp
index e92af6c07469..784a20fa777a 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -257,14 +257,8 @@ DefinedFunction::DefinedFunction(StringRef name, uint32_t flags, InputFile *f,
 
 uint64_t DefinedData::getVirtualAddress() const {
   LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
-  if (segment) {
-    // For thread local data, the symbol location is relative to the start of
-    // the .tdata section, since they are used as offsets from __tls_base.
-    // Hence, we do not add in segment->outputSeg->startVA.
-    if (segment->outputSeg->name == ".tdata")
-      return segment->outputSegmentOffset + offset;
+  if (segment)
     return segment->outputSeg->startVA + segment->outputSegmentOffset + offset;
-  }
   return offset;
 }
 

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 744c217965d4..8178489c3d00 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -749,15 +749,15 @@ void Writer::assignIndexes() {
 }
 
 static StringRef getOutputDataSegmentName(StringRef name) {
-  // With PIC code we currently only support a single data segment since
-  // we only have a single __memory_base to use as our base address.
-  if (config->isPic)
-    return ".data";
   // We only support one thread-local segment, so we must merge the segments
   // despite --no-merge-data-segments.
   // We also need to merge .tbss into .tdata so they share the same offsets.
   if (name.startswith(".tdata") || name.startswith(".tbss"))
     return ".tdata";
+  // With PIC code we currently only support a single data segment since
+  // we only have a single __memory_base to use as our base address.
+  if (config->isPic)
+    return ".data";
   if (!config->mergeDataSegments)
     return name;
   if (name.startswith(".text."))
@@ -1199,10 +1199,10 @@ void Writer::run() {
 
   if (!config->relocatable) {
     // Create linker synthesized functions
-    if (config->sharedMemory)
-      createInitMemoryFunction();
     if (config->isPic)
       createApplyRelocationsFunction();
+    else if (config->sharedMemory)
+      createInitMemoryFunction();
     createCallCtorsFunction();
 
     // Create export wrappers for commands if needed.

diff  --git a/llvm/include/llvm/BinaryFormat/WasmRelocs.def b/llvm/include/llvm/BinaryFormat/WasmRelocs.def
index 76e2037617e5..4eb12684eaa6 100644
--- a/llvm/include/llvm/BinaryFormat/WasmRelocs.def
+++ b/llvm/include/llvm/BinaryFormat/WasmRelocs.def
@@ -23,3 +23,4 @@ WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB64, 17)
 WASM_RELOC(R_WASM_TABLE_INDEX_SLEB64,     18)
 WASM_RELOC(R_WASM_TABLE_INDEX_I64,        19)
 WASM_RELOC(R_WASM_TABLE_NUMBER_LEB,       20)
+WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB,   21)

diff  --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index 46e60d8f258d..a2c0aea464e4 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -321,8 +321,9 @@ class MCSymbolRefExpr : public MCExpr {
     VK_Hexagon_IE_GOT,
 
     VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
-    VK_WASM_MBREL,     // Memory address relative to memory base
-    VK_WASM_TBREL,     // Table index relative to table bare
+    VK_WASM_TLSREL,    // Memory address relative to __tls_base
+    VK_WASM_MBREL,     // Memory address relative to __memory_base
+    VK_WASM_TBREL,     // Table index relative to __table_base
 
     VK_AMDGPU_GOTPCREL32_LO, // symbol at gotpcrel32@lo
     VK_AMDGPU_GOTPCREL32_HI, // symbol at gotpcrel32@hi

diff  --git a/llvm/lib/BinaryFormat/Wasm.cpp b/llvm/lib/BinaryFormat/Wasm.cpp
index 19dce2bae47d..a22ab5890922 100644
--- a/llvm/lib/BinaryFormat/Wasm.cpp
+++ b/llvm/lib/BinaryFormat/Wasm.cpp
@@ -48,6 +48,7 @@ bool llvm::wasm::relocTypeHasAddend(uint32_t Type) {
   case R_WASM_MEMORY_ADDR_REL_SLEB64:
   case R_WASM_MEMORY_ADDR_I32:
   case R_WASM_MEMORY_ADDR_I64:
+  case R_WASM_MEMORY_ADDR_TLS_SLEB:
   case R_WASM_FUNCTION_OFFSET_I32:
   case R_WASM_SECTION_OFFSET_I32:
     return true;

diff  --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index b433277c3dc5..5326da653999 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -350,6 +350,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
   case VK_Hexagon_IE_GOT: return "IEGOT";
   case VK_WASM_TYPEINDEX: return "TYPEINDEX";
   case VK_WASM_MBREL: return "MBREL";
+  case VK_WASM_TLSREL: return "TLSREL";
   case VK_WASM_TBREL: return "TBREL";
   case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32 at lo";
   case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32 at hi";
@@ -490,6 +491,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
     .Case("typeindex", VK_WASM_TYPEINDEX)
     .Case("tbrel", VK_WASM_TBREL)
     .Case("mbrel", VK_WASM_MBREL)
+    .Case("tlsrel", VK_WASM_TLSREL)
     .Case("gotpcrel32 at lo", VK_AMDGPU_GOTPCREL32_LO)
     .Case("gotpcrel32 at hi", VK_AMDGPU_GOTPCREL32_HI)
     .Case("rel32 at lo", VK_AMDGPU_REL32_LO)

diff  --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 2f1277eb8110..6bcec5f4c37c 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -576,7 +576,8 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
   case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
   case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
   case wasm::R_WASM_MEMORY_ADDR_I32:
-  case wasm::R_WASM_MEMORY_ADDR_I64: {
+  case wasm::R_WASM_MEMORY_ADDR_I64:
+  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB: {
     // Provisional value is address of the global plus the offset
     const MCSymbolWasm *Base =
         cast<MCSymbolWasm>(Layout.getBaseSymbol(*RelEntry.Symbol));
@@ -685,6 +686,7 @@ void WasmObjectWriter::applyRelocations(
     case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
     case wasm::R_WASM_MEMORY_ADDR_SLEB:
     case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
+    case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
       writePatchableSLEB<5>(Stream, Value, Offset);
       break;
     case wasm::R_WASM_TABLE_INDEX_SLEB64:

diff  --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index f8ca6547a76d..63f2742e9215 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -855,6 +855,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
     case wasm::R_WASM_MEMORY_ADDR_SLEB:
     case wasm::R_WASM_MEMORY_ADDR_I32:
     case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
+    case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
       if (!isValidDataSymbol(Reloc.Index))
         return make_error<GenericBinaryError>("Bad relocation data index",
                                               object_error::parse_failed);

diff  --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index d6c3f74c496a..935d26607c7b 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -100,6 +100,11 @@ enum TOF {
   // Only applicable to data symbols.
   MO_MEMORY_BASE_REL,
 
+  // On a symbol operand this indicates that the immediate is the symbol
+  // address relative the __tls_base wasm global.
+  // Only applicable to data symbols.
+  MO_TLS_BASE_REL,
+
   // On a symbol operand this indicates that the immediate is the symbol
   // address relative the __table_base wasm global.
   // Only applicable to function symbols.

diff  --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
index 3fb14c03ed4f..f0f5d9834771 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
@@ -76,6 +76,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
     case MCSymbolRefExpr::VK_WASM_TBREL:
       assert(SymA.isFunction());
       return wasm::R_WASM_TABLE_INDEX_REL_SLEB;
+    case MCSymbolRefExpr::VK_WASM_TLSREL:
+      return wasm::R_WASM_MEMORY_ADDR_TLS_SLEB;
     case MCSymbolRefExpr::VK_WASM_MBREL:
       assert(SymA.isData());
       return is64Bit() ? wasm::R_WASM_MEMORY_ADDR_REL_SLEB64

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
index d1a696f854f8..e838a7440f1d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
@@ -149,7 +149,8 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
 
     SDValue TLSBaseSym = CurDAG->getTargetExternalSymbol("__tls_base", PtrVT);
     SDValue TLSOffsetSym = CurDAG->getTargetGlobalAddress(
-        GA->getGlobal(), DL, PtrVT, GA->getOffset(), 0);
+        GA->getGlobal(), DL, PtrVT, GA->getOffset(),
+        WebAssemblyII::MO_TLS_BASE_REL);
 
     MachineSDNode *TLSBase =
         CurDAG->getMachineNode(GlobalGetIns, DL, PtrVT, TLSBaseSym);

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
index b8e612377529..c8a052d01199 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -106,6 +106,7 @@ class WebAssemblyTargetLowering final : public TargetLowering {
   SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
+  SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index c8d43010608e..86d59ef807ab 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -139,6 +139,9 @@ MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
     case WebAssemblyII::MO_MEMORY_BASE_REL:
       Kind = MCSymbolRefExpr::VK_WASM_MBREL;
       break;
+    case WebAssemblyII::MO_TLS_BASE_REL:
+      Kind = MCSymbolRefExpr::VK_WASM_TLSREL;
+      break;
     case WebAssemblyII::MO_TABLE_BASE_REL:
       Kind = MCSymbolRefExpr::VK_WASM_TBREL;
       break;

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index 78acc2a34156..71e8e1485b75 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -277,10 +277,9 @@ class CoalesceFeaturesAndStripAtomics final : public ModulePass {
   bool stripThreadLocals(Module &M) {
     bool Stripped = false;
     for (auto &GV : M.globals()) {
-      if (GV.getThreadLocalMode() !=
-          GlobalValue::ThreadLocalMode::NotThreadLocal) {
+      if (GV.isThreadLocal()) {
         Stripped = true;
-        GV.setThreadLocalMode(GlobalValue::ThreadLocalMode::NotThreadLocal);
+        GV.setThreadLocal(false);
       }
     }
     return Stripped;

diff  --git a/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll b/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll
index 1ce100b8653c..16a312bd6bad 100644
--- a/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll
+++ b/llvm/test/CodeGen/WebAssembly/tls-general-dynamic.ll
@@ -12,7 +12,7 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT: .functype  address_of_tls () -> (i32)
 define i32 @address_of_tls() {
   ; TLS-DAG: global.get __tls_base
-  ; TLS-DAG: i32.const tls
+  ; TLS-DAG: i32.const tls at TLSREL
   ; TLS-NEXT: i32.add
   ; TLS-NEXT: return
 
@@ -25,7 +25,7 @@ define i32 @address_of_tls() {
 ; CHECK-NEXT: .functype ptr_to_tls () -> (i32)
 define i32* @ptr_to_tls() {
   ; TLS-DAG: global.get __tls_base
-  ; TLS-DAG: i32.const tls
+  ; TLS-DAG: i32.const tls at TLSREL
   ; TLS-NEXT: i32.add
   ; TLS-NEXT: return
 
@@ -38,7 +38,7 @@ define i32* @ptr_to_tls() {
 ; CHECK-NEXT: .functype tls_load () -> (i32)
 define i32 @tls_load() {
   ; TLS-DAG: global.get __tls_base
-  ; TLS-DAG: i32.const tls
+  ; TLS-DAG: i32.const tls at TLSREL
   ; TLS-NEXT: i32.add
   ; TLS-NEXT: i32.load 0
   ; TLS-NEXT: return
@@ -54,7 +54,7 @@ define i32 @tls_load() {
 ; CHECK-NEXT: .functype tls_store (i32) -> ()
 define void @tls_store(i32 %x) {
   ; TLS-DAG: global.get __tls_base
-  ; TLS-DAG: i32.const tls
+  ; TLS-DAG: i32.const tls at TLSREL
   ; TLS-NEXT: i32.add
   ; TLS-NEXT: i32.store 0
   ; TLS-NEXT: return

diff  --git a/llvm/test/CodeGen/WebAssembly/tls-local-exec.ll b/llvm/test/CodeGen/WebAssembly/tls-local-exec.ll
index 02979a28af99..7cc043a13ac0 100644
--- a/llvm/test/CodeGen/WebAssembly/tls-local-exec.ll
+++ b/llvm/test/CodeGen/WebAssembly/tls-local-exec.ll
@@ -8,7 +8,7 @@ target triple = "wasm32-unknown-unknown"
 ; CHECK-NEXT: .functype  address_of_tls () -> (i32)
 define i32 @address_of_tls() {
   ; TLS-DAG: global.get __tls_base
-  ; TLS-DAG: i32.const tls
+  ; TLS-DAG: i32.const tls at TLSREL
   ; TLS-NEXT: i32.add
   ; TLS-NEXT: return
 
@@ -21,7 +21,7 @@ define i32 @address_of_tls() {
 ; CHECK-NEXT: .functype ptr_to_tls () -> (i32)
 define i32* @ptr_to_tls() {
   ; TLS-DAG: global.get __tls_base
-  ; TLS-DAG: i32.const tls
+  ; TLS-DAG: i32.const tls at TLSREL
   ; TLS-NEXT: i32.add
   ; TLS-NEXT: return
 
@@ -34,7 +34,7 @@ define i32* @ptr_to_tls() {
 ; CHECK-NEXT: .functype tls_load () -> (i32)
 define i32 @tls_load() {
   ; TLS-DAG: global.get __tls_base
-  ; TLS-DAG: i32.const tls
+  ; TLS-DAG: i32.const tls at TLSREL
   ; TLS-NEXT: i32.add
   ; TLS-NEXT: i32.load 0
   ; TLS-NEXT: return
@@ -50,7 +50,7 @@ define i32 @tls_load() {
 ; CHECK-NEXT: .functype tls_store (i32) -> ()
 define void @tls_store(i32 %x) {
   ; TLS-DAG: global.get __tls_base
-  ; TLS-DAG: i32.const tls
+  ; TLS-DAG: i32.const tls at TLSREL
   ; TLS-NEXT: i32.add
   ; TLS-NEXT: i32.store 0
   ; TLS-NEXT: return

diff  --git a/llvm/test/MC/WebAssembly/tls.s b/llvm/test/MC/WebAssembly/tls.s
new file mode 100644
index 000000000000..025c94c5894e
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/tls.s
@@ -0,0 +1,43 @@
+# RUN: llvm-mc -triple=wasm32-unknown-unknown < %s | FileCheck %s
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -o %t.o < %s
+# RUN: obj2yaml %t.o | FileCheck %s --check-prefix=CHECK-OBJ
+
+tls_store:
+  .functype tls_store (i32) -> ()
+  # CHECK: global.get __tls_base
+  # CHECK-NEXT: i32.const tls at TLSREL
+  # CHECK-NEXT: i32.add
+  # CHECK-NEXT: i32.store 0
+  global.get __tls_base
+  i32.const tls at TLSREL
+  i32.add
+  i32.store 0
+  end_function
+
+
+#      CHECK-OBJ:  - Type:            CODE
+# CHECK-OBJ-NEXT:    Relocations:
+# CHECK-OBJ-NEXT:      - Type:            R_WASM_MEMORY_ADDR_LEB
+# CHECK-OBJ-NEXT:        Index:           1
+# CHECK-OBJ-NEXT:        Offset:          0x00000004
+# CHECK-OBJ-NEXT:      - Type:            R_WASM_MEMORY_ADDR_TLS_SLEB
+# CHECK-OBJ-NEXT:        Index:           2
+# CHECK-OBJ-NEXT:        Offset:          0x0000000A
+
+#      CHECK-OBJ:  - Type:            CUSTOM
+# CHECK-OBJ-NEXT:    Name:            linking
+# CHECK-OBJ-NEXT:    Version:         2
+# CHECK-OBJ-NEXT:    SymbolTable:
+# CHECK-OBJ-NEXT:      - Index:           0
+# CHECK-OBJ-NEXT:        Kind:            FUNCTION
+# CHECK-OBJ-NEXT:        Name:            tls_store
+# CHECK-OBJ-NEXT:        Flags:           [ BINDING_LOCAL ]
+# CHECK-OBJ-NEXT:        Function:        0
+# CHECK-OBJ-NEXT:      - Index:           1
+# CHECK-OBJ-NEXT:        Kind:            DATA
+# CHECK-OBJ-NEXT:        Name:            __tls_base
+# CHECK-OBJ-NEXT:        Flags:           [ UNDEFINED ]
+# CHECK-OBJ-NEXT:      - Index:           2
+# CHECK-OBJ-NEXT:        Kind:            DATA
+# CHECK-OBJ-NEXT:        Name:            tls
+# CHECK-OBJ-NEXT:        Flags:           [ UNDEFINED ]


        


More information about the llvm-commits mailing list