[lld] [WebAssembly] Fix __init_tls_base global in coop threading (PR #208597)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 9 17:53:49 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld

Author: Alex Crichton (alexcrichton)

<details>
<summary>Changes</summary>

This commit updates how `wasm-ld` initializes the `__init_tls_base`
global during module instantiation. Previously this global was left
entirely unmodified meaning that it was always 0. This change updates
the `__wasm_init_memory` function to set this global dynamically in PIC
mode based on the TLS address calculation, or in non-PIC mode the
generation of `__wasm_init_memory` correctly sets it to the desired TLS
address.

cc https://github.com/WebAssembly/wasi-libc/issues/819

> **Note**: this is currently built on https://github.com/llvm/llvm-project/pull/208332

---

Patch is 31.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/208597.diff


11 Files Affected:

- (modified) lld/test/wasm/compress-relocs.s (+6-6) 
- (modified) lld/test/wasm/compress-relocs64.s (+6-6) 
- (modified) lld/test/wasm/cooperative-threading.s (+142-11) 
- (modified) lld/test/wasm/data-segments.ll (+24-24) 
- (modified) lld/test/wasm/runtime-relocations-himem.s (+2-2) 
- (modified) lld/test/wasm/tls-non-shared-memory.s (+7-7) 
- (modified) lld/test/wasm/tls-relocations.s (+2-2) 
- (modified) lld/wasm/Driver.cpp (+12-4) 
- (modified) lld/wasm/InputChunks.cpp (+8-2) 
- (modified) lld/wasm/OutputSections.cpp (+1-2) 
- (modified) lld/wasm/Writer.cpp (+78-31) 


``````````diff
diff --git a/lld/test/wasm/compress-relocs.s b/lld/test/wasm/compress-relocs.s
index 37f1b3b170ff7..e872b941416af 100644
--- a/lld/test/wasm/compress-relocs.s
+++ b/lld/test/wasm/compress-relocs.s
@@ -47,16 +47,16 @@ test_memory_and_indirect_call_relocs:
   end_function
 
 # CHECK:    test_memory_and_indirect_call_relocs
-# CHECK:      41 90 80 84 80 00                 i32.const      65552
+# CHECK:      41 80 80 84 80 00                 i32.const      65536
 # CHECK:      11 80 80 80 80 00 80 80 80 80 00  call_indirect  0
-# CHECK:      28 02 94 80 84 80 00              i32.load       65556
+# CHECK:      28 02 84 80 84 80 00              i32.load       65540
 # CHECK:      11 81 80 80 80 00 80 80 80 80 00  call_indirect  1
 # CHECK:      41 81 80 80 80 00                 i32.const      1
 # CHECK:      11 80 80 80 80 00 80 80 80 80 00  call_indirect  0
 # COMPRESS: test_memory_and_indirect_call_relocs
-# COMPRESS:   41 90 80 04                       i32.const      65552
+# COMPRESS:   41 80 80 04                       i32.const      65536
 # COMPRESS:   11 00 00                          call_indirect  0
-# COMPRESS:   28 02 94 80 04                    i32.load       65556
+# COMPRESS:   28 02 84 80 04                    i32.load       65540
 # COMPRESS:   11 01 00                          call_indirect  1
 # COMPRESS:   41 01                             i32.const      1
 # COMPRESS:   11 00 00                          call_indirect  0
@@ -91,11 +91,11 @@ test_relative_relocs:
   end_function
 
 # CHECK:    test_relative_relocs
-# CHECK:      41 90 80 84 80 00  i32.const  65552
+# CHECK:      41 80 80 84 80 00  i32.const  65536
 # CHECK:      41 81 80 80 80 00  i32.const  1
 # CHECK:      41 83 80 80 80 00  i32.const  3
 # COMPRESS: test_relative_relocs
-# COMPRESS:   41 90 80 04        i32.const  65552
+# COMPRESS:   41 80 80 04        i32.const  65536
 # COMPRESS:   41 01              i32.const  1
 # COMPRESS:   41 03              i32.const  3
 
diff --git a/lld/test/wasm/compress-relocs64.s b/lld/test/wasm/compress-relocs64.s
index f3ff646cc3b1c..2dd18d604df41 100644
--- a/lld/test/wasm/compress-relocs64.s
+++ b/lld/test/wasm/compress-relocs64.s
@@ -36,12 +36,12 @@ test_memory_and_indirect_call_relocs:
   end_function
 
 # CHECK:    test_memory_and_indirect_call_relocs
-# CHECK:      42 90 80 84 80 80 80 80 80 80 00     i64.const 65552
-# CHECK:      29 03 98 80 84 80 80 80 80 80 80 00  i64.load  65560
+# CHECK:      42 80 80 84 80 80 80 80 80 80 00     i64.const 65536
+# CHECK:      29 03 88 80 84 80 80 80 80 80 80 00  i64.load  65544
 # CHECK:      42 81 80 80 80 80 80 80 80 80 00     i64.const 1
 # COMPRESS: test_memory_and_indirect_call_relocs
-# COMPRESS:   42 90 80 04                          i64.const 65552
-# COMPRESS:   29 03 98 80 04                       i64.load  65560
+# COMPRESS:   42 80 80 04                          i64.const 65536
+# COMPRESS:   29 03 88 80 04                       i64.load  65544
 # COMPRESS:   42 01                                i64.const 1
 
   .globl test_relative_relocs
@@ -56,11 +56,11 @@ test_relative_relocs:
   end_function
 
 # CHECK:    test_relative_relocs
-# CHECK:      42 90 80 84 80 80 80 80 80 80 00  i64.const 65552
+# CHECK:      42 80 80 84 80 80 80 80 80 80 00  i64.const 65536
 # CHECK:      42 81 80 80 80 80 80 80 80 80 00  i64.const 1
 # CHECK:      42 83 80 80 80 80 80 80 80 80 00  i64.const 3
 # COMPRESS: test_relative_relocs
-# COMPRESS:   42 90 80 04                       i64.const 65552
+# COMPRESS:   42 80 80 04                       i64.const 65536
 # COMPRESS:   42 01                             i64.const 1
 # COMPRESS:   42 03                             i64.const 3
 
diff --git a/lld/test/wasm/cooperative-threading.s b/lld/test/wasm/cooperative-threading.s
index 8b0f7eb1c256f..ffe5b524489fb 100644
--- a/lld/test/wasm/cooperative-threading.s
+++ b/lld/test/wasm/cooperative-threading.s
@@ -57,6 +57,13 @@ foo:
   .int32  0
   .size foo, 4
 
+.section  .rodata.baz,"",@
+.globl  baz
+.p2align  2
+baz:
+  .int32  1
+  .size baz, 4
+
 .section  .custom_section.target_features,"",@
   .int8 2
   .int8 43
@@ -72,22 +79,51 @@ foo:
 # CHECK-NEXT:     - Minimum:         0x2
 # CHECK-NOT:       Shared
 
-# Only TLS needs a passive data segment; .data stays active and .bss gets no
-# segment at all since memory is only instantiated once and starts zeroed.
+# Ensure __init_stack_pointer, __init_tls_base, and __tls_size are all correct.
+# CHECK:      - Type:            GLOBAL
+# CHECK-NEXT:   Globals:
+# CHECK-NEXT:     - Index:           0
+# CHECK-NEXT:       Type:            I32
+# CHECK-NEXT:       Mutable:         false
+# CHECK-NEXT:       InitExpr:
+# CHECK-NEXT:         Opcode:          I32_CONST
+# CHECK-NEXT:         Value:           65536
+# CHECK-NEXT:     - Index:           1
+# CHECK-NEXT:       Type:            I32
+# CHECK-NEXT:       Mutable:         false
+# CHECK-NEXT:       InitExpr:
+# CHECK-NEXT:         Opcode:          I32_CONST
+# CHECK-NEXT:         Value:           65544
+# CHECK-NEXT:     - Index:           2
+# CHECK-NEXT:       Type:            I32
+# CHECK-NEXT:       Mutable:         false
+# CHECK-NEXT:       InitExpr:
+# CHECK-NEXT:         Opcode:          I32_CONST
+# CHECK-NEXT:         Value:           8
+
+# Only TLS needs a passive data segment; .rodata and .data stay active and
+# .bss gets no segment at all since memory is only instantiated once and
+# starts zeroed. The TLS segment is sorted last.
 # CHECK:        - Type:            DATACOUNT
-# CHECK-NEXT:     Count:           2
+# CHECK-NEXT:     Count:           3
 
 # CHECK:        - Type:            DATA{{$}}
 # CHECK-NEXT:     Segments:
-# CHECK-NEXT:       - SectionOffset:   3
-# CHECK-NEXT:         InitFlags:       1
-# CHECK-NEXT:         Content:         '0100000002000000'
-# CHECK-NEXT:       - SectionOffset:   18
+# CHECK-NEXT:       - SectionOffset:   8
+# CHECK-NEXT:         InitFlags:       0
+# CHECK-NEXT:         Offset:
+# CHECK-NEXT:           Opcode:          I32_CONST
+# CHECK-NEXT:           Value:           65536
+# CHECK-NEXT:         Content:         '01000000'
+# CHECK-NEXT:       - SectionOffset:   19
 # CHECK-NEXT:         InitFlags:       0
 # CHECK-NEXT:         Offset:
 # CHECK-NEXT:           Opcode:          I32_CONST
-# CHECK-NEXT:           Value:           {{[0-9]+}}
+# CHECK-NEXT:           Value:           65540
 # CHECK-NEXT:         Content:         2A000000
+# CHECK-NEXT:       - SectionOffset:   25
+# CHECK-NEXT:         InitFlags:       1
+# CHECK-NEXT:         Content:         '0100000002000000'
 # CHECK-NEXT:   - Type:            CUSTOM
 
 # Globals should use the libcall ABI naming, not the global ABI.
@@ -102,9 +138,14 @@ foo:
 # CHECK-NEXT:        Name:            __tls_align
 
 # DIS-LABEL: <__wasm_init_memory>:
-# DIS:         memory.init     0, 0
-# DIS-NOT:     memory.fill
-# DIS-NOT:     memory.init
+# DIS-EMPTY:
+# DIS-NEXT:      i32.const       65544
+# DIS-NEXT:      i32.const       65544
+# DIS-NEXT:      call    0
+# DIS-NEXT:      i32.const       0
+# DIS-NEXT:      i32.const       8
+# DIS-NEXT:      memory.init     2, 0
+# DIS-NEXT:      end
 
 # DIS-LABEL: <_start>:
 # DIS-EMPTY:
@@ -118,3 +159,93 @@ foo:
 # DIS-NEXT:       i32.load        0
 # DIS-NEXT:       i32.add
 # DIS-NEXT:       end
+
+# Test --cooperative-threading combined with PIC output.
+# RUN: wasm-ld -shared --cooperative-threading -no-gc-sections -o %t.so %t.o
+# RUN: obj2yaml %t.so | FileCheck %s --check-prefix=PIC
+# RUN: llvm-objdump --disassemble-symbols=__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.so | FileCheck %s --check-prefix=PIC-DIS
+
+# The stack pointer is imported under the libcall ABI name and
+# __wasm_set_tls_base is imported for TLS initialization.
+# PIC:       - Type:            IMPORT
+# PIC:           Field:           __init_stack_pointer
+# PIC-NEXT:      Kind:            GLOBAL
+# PIC-NEXT:      GlobalType:      I32
+# PIC-NEXT:      GlobalMutable:   false
+# PIC:           Field:           __memory_base
+# PIC:           Field:           __table_base
+# PIC:           Field:           __wasm_set_tls_base
+# PIC-NEXT:      Kind:            FUNCTION
+
+# The PIC `__init_tls_base` global (global 3) is mutable and initialized ot
+# 0 since its final value is calculated once `__memory_base` is provided.
+# PIC:       - Type:            GLOBAL
+# PIC-NEXT:    Globals:
+# PIC-NEXT:      - Index:           3
+# PIC-NEXT:        Type:            I32
+# PIC-NEXT:        Mutable:         true
+# PIC-NEXT:        InitExpr:
+# PIC-NEXT:          Opcode:          I32_CONST
+# PIC-NEXT:          Value:           0
+# PIC-NEXT:      - Index:           4
+# PIC-NEXT:        Type:            I32
+# PIC-NEXT:        Mutable:         false
+# PIC-NEXT:        InitExpr:
+# PIC-NEXT:          Opcode:          I32_CONST
+# PIC-NEXT:          Value:           8
+
+# In PIC mode the active .rodata and .data segments are combined into a single
+# active segment at __memory_base; the TLS segment remains passive.
+# PIC:       - Type:            DATACOUNT
+# PIC-NEXT:    Count:           2
+# PIC:       - Type:            DATA{{$}}
+# PIC-NEXT:    Segments:
+# PIC-NEXT:      - SectionOffset:   6
+# PIC-NEXT:        InitFlags:       0
+# PIC-NEXT:        Offset:
+# PIC-NEXT:          Opcode:          GLOBAL_GET
+# PIC-NEXT:          Index:           {{[0-9]+}}
+# PIC-NEXT:        Content:         010000002A000000
+# PIC-NEXT:      - SectionOffset:   {{[0-9]+}}
+# PIC-NEXT:        InitFlags:       1
+# PIC-NEXT:        Content:         '0100000002000000'
+# PIC-NEXT:  - Type:            CUSTOM
+
+# PIC:       GlobalNames:
+# PIC-NEXT:      - Index:           0
+# PIC-NEXT:        Name:            __init_stack_pointer
+# PIC-NEXT:      - Index:           1
+# PIC-NEXT:        Name:            __memory_base
+# PIC-NEXT:      - Index:           2
+# PIC-NEXT:        Name:            __table_base
+# PIC-NEXT:      - Index:           3
+# PIC-NEXT:        Name:            __init_tls_base
+# PIC-NEXT:      - Index:           4
+# PIC-NEXT:        Name:            __tls_size
+# PIC-NEXT:      - Index:           5
+# PIC-NEXT:        Name:            __tls_align
+
+# Memory initialization in PIC mode has a few responsibilities: it calculates
+# the TLS address and puts it in a local, stores it into the __init_tls_base
+# global, `__wasm_set_tls_base` is called, TLS is initialized, and then finally
+# BSS is zero'd out.
+# PIC-DIS:      <__wasm_init_memory>:
+# PIC-DIS-NEXT:   .local i32
+# PIC-DIS-NEXT:   i32.const 8
+# PIC-DIS-NEXT:   global.get 1
+# PIC-DIS-NEXT:   i32.add
+# PIC-DIS-NEXT:   local.tee 0
+# PIC-DIS-NEXT:   global.set 3
+# PIC-DIS-NEXT:   local.get 0
+# PIC-DIS-NEXT:   call {{[0-9]+}}
+# PIC-DIS-NEXT:   local.get 0
+# PIC-DIS-NEXT:   i32.const 0
+# PIC-DIS-NEXT:   i32.const 8
+# PIC-DIS-NEXT:   memory.init 1, 0
+# PIC-DIS-NEXT:   i32.const 16
+# PIC-DIS-NEXT:   global.get {{[0-9]+}}
+# PIC-DIS-NEXT:   i32.add
+# PIC-DIS-NEXT:   i32.const 0
+# PIC-DIS-NEXT:   i32.const 4
+# PIC-DIS-NEXT:   memory.fill 0
+# PIC-DIS-NEXT:   end
diff --git a/lld/test/wasm/data-segments.ll b/lld/test/wasm/data-segments.ll
index 7a18fd5efb655..5073e9c4cc8d1 100644
--- a/lld/test/wasm/data-segments.ll
+++ b/lld/test/wasm/data-segments.ll
@@ -93,7 +93,7 @@
 ; ACTIVE-PIC-NEXT:        Offset:
 ; ACTIVE-PIC-NEXT:          Opcode:          GLOBAL_GET
 ; ACTIVE-PIC-NEXT:          Index:           1
-; ACTIVE-PIC-NEXT:        Content:         63000000636F6E7374616E74000000002B00000068656C6C6F00676F6F646279650000002A000000
+; ACTIVE-PIC-NEXT:        Content:         636F6E7374616E74000000002B00000068656C6C6F00676F6F646279650000002A00000063000000
 
 ; PASSIVE-LABEL: - Type:            START
 ; PASSIVE-NEXT:    StartFunction:   2
@@ -114,13 +114,13 @@
 ; PASSIVE-NEXT:    Segments:
 ; PASSIVE-NEXT:      - SectionOffset:   3
 ; PASSIVE-NEXT:        InitFlags:       1
-; PASSIVE-NEXT:        Content:         '63000000'
-; PASSIVE-NEXT:      - SectionOffset:   9
-; PASSIVE-NEXT:        InitFlags:       1
 ; PASSIVE-NEXT:        Content:         636F6E7374616E74000000002B
-; PASSIVE-NEXT:      - SectionOffset:   24
+; PASSIVE-NEXT:      - SectionOffset:   18
 ; PASSIVE-NEXT:        InitFlags:       1
 ; PASSIVE-NEXT:        Content:         68656C6C6F00676F6F646279650000002A000000
+; PASSIVE-NEXT:      - SectionOffset:   40
+; PASSIVE-NEXT:        InitFlags:       1
+; PASSIVE-NEXT:        Content:         '63000000'
 ; PASSIVE-NEXT:  - Type:            CUSTOM
 ; PASSIVE-NEXT:    Name:            name
 ; PASSIVE-NEXT:    FunctionNames:
@@ -153,13 +153,13 @@
 ; PASSIVE-PIC-NEXT:    Segments:
 ; PASSIVE-PIC-NEXT:      - SectionOffset:   3
 ; PASSIVE-PIC-NEXT:        InitFlags:       1
-; PASSIVE-PIC-NEXT:        Content:         '63000000'
-; PASSIVE-PIC-NEXT:      - SectionOffset:   9
-; PASSIVE-PIC-NEXT:        InitFlags:       1
 ; PASSIVE-PIC-NEXT:        Content:         636F6E7374616E74000000002B
-; PASSIVE-PIC-NEXT:      - SectionOffset:   24
+; PASSIVE-PIC-NEXT:      - SectionOffset:   18
 ; PASSIVE-PIC-NEXT:        InitFlags:       1
 ; PASSIVE-PIC-NEXT:        Content:         68656C6C6F00676F6F646279650000002A000000
+; PASSIVE-PIC-NEXT:      - SectionOffset:   40
+; PASSIVE-PIC-NEXT:        InitFlags:       1
+; PASSIVE-PIC-NEXT:        Content:         '63000000'
 ; PASSIVE-PIC-NEXT:  - Type:            CUSTOM
 ; PASSIVE-PIC-NEXT:    Name:            name
 ; PASSIVE-PIC-NEXT:    FunctionNames:
@@ -212,34 +212,34 @@
 ; DIS-NEXT:            end
 
 ; NOPIC-DIS-NEXT:      [[PTR]].const   65536
-; NOPIC-DIS-NEXT:      [[PTR]].const   65536
-; NOPIC-DIS-NEXT:      global.set      1
 ; PIC-DIS-NEXT:        [[PTR]].const   0
 ; PIC-DIS-NEXT:        global.get      1
 ; PIC-DIS-NEXT:        [[PTR]].add
-; PIC-DIS-NEXT:        local.tee       1
-; PIC-DIS-NEXT:        global.set      {{\d*}}
-; PIC-DIS-NEXT:        local.get       1
+
 ; DIS-NEXT:            i32.const       0
-; DIS-NEXT:            i32.const       4
-; DIS-NEXT:            memory.init  0, 0
+; DIS-NEXT:            i32.const       13
+; DIS-NEXT:            memory.init     0, 0
 
-; NOPIC-DIS-NEXT:      [[PTR]].const   65540
-; PIC-DIS-NEXT:        [[PTR]].const   4
+; NOPIC-DIS-NEXT:      [[PTR]].const   65552
+; PIC-DIS-NEXT:        [[PTR]].const   16
 ; PIC-DIS-NEXT:        global.get      1
 ; PIC-DIS-NEXT:        [[PTR]].add
 
 ; DIS-NEXT:            i32.const       0
-; DIS-NEXT:            i32.const       13
+; DIS-NEXT:            i32.const       20
 ; DIS-NEXT:            memory.init     1, 0
 
-; NOPIC-DIS-NEXT:      [[PTR]].const   65556
-; PIC-DIS-NEXT:        [[PTR]].const   20
+; NOPIC-DIS-NEXT:      [[PTR]].const   65572
+; NOPIC-DIS-NEXT:      [[PTR]].const   65572
+; NOPIC-DIS-NEXT:      global.set      1
+; PIC-DIS-NEXT:        [[PTR]].const   36
 ; PIC-DIS-NEXT:        global.get      1
 ; PIC-DIS-NEXT:        [[PTR]].add
-
+; PIC-DIS-NEXT:        local.tee       1
+; PIC-DIS-NEXT:        global.set      {{\d*}}
+; PIC-DIS-NEXT:        local.get       1
 ; DIS-NEXT:            i32.const       0
-; DIS-NEXT:            i32.const       20
+; DIS-NEXT:            i32.const       4
 ; DIS-NEXT:            memory.init     2, 0
 ; NOPIC-DIS-NEXT:      [[PTR]].const   65576
 ; PIC-DIS-NEXT:        [[PTR]].const   40
@@ -272,6 +272,6 @@
 ; DIS-NEXT:           memory.atomic.wait32    0
 ; DIS-NEXT:           drop
 ; DIS-NEXT:          end
+; DIS-NEXT:          data.drop       0
 ; DIS-NEXT:          data.drop       1
-; DIS-NEXT:          data.drop       2
 ; DIS-NEXT:         end
diff --git a/lld/test/wasm/runtime-relocations-himem.s b/lld/test/wasm/runtime-relocations-himem.s
index 2d39a204c7904..2026e62a5af86 100644
--- a/lld/test/wasm/runtime-relocations-himem.s
+++ b/lld/test/wasm/runtime-relocations-himem.s
@@ -47,14 +47,14 @@ data_sym:
 
 # CHECK: <__wasm_apply_data_relocs>:
 # CHECK-EMPTY:
-# CHECK-NEXT:  i32.const -2147483636
+# CHECK-NEXT:  i32.const -2147483644
 # CHECK-NEXT:  global.get 0
 # CHECK-NEXT:  i32.store 0
 # CHECK-NEXT:  end
 
 # CHECK: <__wasm_apply_tls_relocs>:
 # CHECK-EMPTY:
-# CHECK-NEXT:  i32.const -2147483644
+# CHECK-NEXT:  i32.const -2147483636
 # CHECK-NEXT:  global.get 0
 # CHECK-NEXT:  i32.store 0
 # CHECK-NEXT:  end
diff --git a/lld/test/wasm/tls-non-shared-memory.s b/lld/test/wasm/tls-non-shared-memory.s
index 0a87ade7efb2e..21082a5603e7f 100644
--- a/lld/test/wasm/tls-non-shared-memory.s
+++ b/lld/test/wasm/tls-non-shared-memory.s
@@ -70,14 +70,14 @@ tls1:
 # CHECK-NEXT:         Mutable:         false
 # CHECK-NEXT:         InitExpr:
 # CHECK-NEXT:           Opcode:          I32_CONST
-# CHECK-NEXT:           Value:           65536
+# CHECK-NEXT:           Value:           65540
 # GOT.data.internal.tls1
 # CHECK-NEXT:       - Index:           2
 # CHECK-NEXT:         Type:            I32
 # CHECK-NEXT:         Mutable:         false
 # CHECK-NEXT:         InitExpr:
 # CHECK-NEXT:           Opcode:          I32_CONST
-# CHECK-NEXT:           Value:           65536
+# CHECK-NEXT:           Value:           65540
 # CHECK-NEXT:   - Type:            EXPORT
 
 #      CHECK:  - Type:            DATA
@@ -88,14 +88,14 @@ tls1:
 # CHECK-NEXT:        Offset:
 # CHECK-NEXT:          Opcode:          I32_CONST
 # CHECK-NEXT:          Value:           65536
-# CHECK-NEXT:        Content:         2B000000
+# CHECK-NEXT:        Content:         2A000000
 # .tdata
 # CHECK-NEXT:      - SectionOffset:   19
 # CHECK-NEXT:        InitFlags:       0
 # CHECK-NEXT:        Offset:
 # CHECK-NEXT:          Opcode:          I32_CONST
 # CHECK-NEXT:          Value:           65540
-# CHECK-NEXT:        Content:         2A000000
+# CHECK-NEXT:        Content:         2B000000
 # CHECK-NEXT:  - Type:            CUSTOM
 
 # The constant value here which we add to `__tls_base` should not be absolute
@@ -146,7 +146,7 @@ tls1:
 # PIC-NEXT:        Offset:
 # PIC-NEXT:          Opcode:          GLOBAL_GET
 # PIC-NEXT:          Index:           {{\d*}}
-# PIC-NEXT:        Content:         2B0000002A000000
+# PIC-NEXT:        Content:         2A0000002B000000
 # PIC-NEXT:  - Type:            CUSTOM
 
 # Unless we have extended-const, in which case the merging is not needed.
@@ -160,7 +160,7 @@ tls1:
 # EXT-CONST-NEXT:        Offset:
 # EXT-CONST-NEXT:          Opcode:          GLOBAL_GET
 # EXT-CONST-NEXT:          Index:           1
-# EXT-CONST-NEXT:        Content:         2B000000
+# EXT-CONST-NEXT:        Content:         2A000000
 # EXT-CONST-NEXT:      - SectionOffset:   18
 # EXT-CONST-NEXT:        InitFlags:       0
 # EXT-CONST-NEXT:        Offset:
@@ -168,4 +168,4 @@ tls1:
 # This instruction sequence decodes to:
 # (global.get[0x23] 0x1 i32.const[0x41] 0x04 i32.add[0x6A] end[0x0b])
 # EXT-CONST-NEXT:          Body:            230141046A0B
-# EXT-CONST-NEXT:        Content:         2A000000
+# EXT-CONST-NEXT:        Content:         2B000000
diff --git a/lld/test/wasm/tls-relocations.s b/lld/test/wasm/tls-relocations.s
index 9679074d6a0db..b5d1304177744 100644
--- a/lld/test/wasm/tls-relocations.s
+++ b/lld/test/wasm/tls-relocations.s
@@ -64,7 +64,7 @@ tls_sym:
 # ASM-NEXT:                 local.get 0
 # ASM-NEXT:                 i32.const 0
 # ASM-NEXT:                 i32.const 16
-# ASM-NEXT:                 memory.init 0, 0
+# ASM-NEXT:                 memory.init 1, 0
 # call to __wasm_apply_tls_relocs
 # ASM-NEXT:                 call  3
 # ASM-NEXT:                 end
@@ -75,7 +75,7 @@ tls_sym:
 # ASM-NEXT:                 global.get  3
 # ASM-NEXT:                 i32.add
 # ASM-NEXT:                 global.get  1
-# ASM-NEXT:                 i32.const 20
+# ASM-NEXT:                 i32.const 4
 # ASM-NEXT:                 i32.add
 # ASM-NEXT:                 i32.store 0
 # ASM-NEXT:                 i32.const 12
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 9a2e3a82a9279..00b6b1b3b5b2e 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -970,12 +970,20 @@ static void createSyntheticSymbols() {
   }
 
   if (ctx.arg.isMultithreaded()) {
-    // TLS symbols are all hidden/dso-local
+    // TLS symbols are all hidden/dso-local, and note that the `tlsBase` global
+    // serves a different purpose depending on `libcallThreadContext`. If
+    // `libcallThreadContext` is `false` it's the base address of TLS and it's
+    // initialized fresh by each thread. This requires a mutable global.
+    //
+    // If `libca...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/208597


More information about the llvm-commits mailing list