[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-22 Thread Sy Brand via cfe-commits


@@ -278,10 +278,17 @@ class CoalesceFeaturesAndStripAtomics final : public 
ModulePass {
 bool StrippedAtomics = false;
 bool StrippedTLS = false;
 
+// In cooperative threading mode, thread locals are meaningful even without
+// atomics.
+bool CooperativeThreading =
+WasmTM->getSubtargetImpl()->hasCooperativeMultithreading();
+
 if (!Features[WebAssembly::FeatureAtomics]) {
   StrippedAtomics = stripAtomics(M);
-  StrippedTLS = stripThreadLocals(M);
-} else if (!Features[WebAssembly::FeatureBulkMemory]) {
+  if (!CooperativeThreading)
+StrippedTLS = stripThreadLocals(M);
+}
+if (!Features[WebAssembly::FeatureBulkMemory]) {
   StrippedTLS |= stripThreadLocals(M);

TartanLlama wrote:

Ah, I forgot `|=` doesn't short-circuit, I've changed the condition to ensure 
it's called called twice

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-22 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/25] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-16 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/21] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-12 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/19] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-12 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/18] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-12 Thread Sy Brand via cfe-commits

TartanLlama wrote:

@sbc100 looks all green now, anything else needed?

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-11 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/17] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread Sy Brand via cfe-commits


@@ -1057,7 +1057,15 @@ static StringRef getOutputDataSegmentName(const 
InputChunk &seg) {
 OutputSegment *Writer::createOutputSegment(StringRef name) {
   LLVM_DEBUG(dbgs() << "new segment: " << name << "\n");
   OutputSegment *s = make(name);
-  if (ctx.arg.sharedMemory)
+  // In the shared memory case, all data segments must be passive since they
+  // will be initialized once by the main thread and then shared with other
+  // threads. In the non-shared memory case, we use passive segments only for
+  // TLS segments, so that they can be reused, and for .bss segments, which
+  // don't need to be included in the binary at all.

TartanLlama wrote:

I've updated the comment

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/17] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/16] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread Sy Brand via cfe-commits


@@ -283,10 +283,17 @@ class CoalesceFeaturesAndStripAtomics final : public 
ModulePass {
 bool StrippedAtomics = false;
 bool StrippedTLS = false;
 
+// In cooperative threading mode, thread locals are meaningful even without
+// atomics.
+bool CooperativeThreading =
+WasmTM->getSubtargetImpl()->hasCooperativeMultithreading();
+
 if (!Features[WebAssembly::FeatureAtomics]) {
   StrippedAtomics = stripAtomics(M);
-  StrippedTLS = stripThreadLocals(M);
-} else if (!Features[WebAssembly::FeatureBulkMemory]) {
+  if (!CooperativeThreading)
+StrippedTLS = stripThreadLocals(M);
+}
+if (!Features[WebAssembly::FeatureBulkMemory]) {

TartanLlama wrote:

The only difference in behaviour is in the `CooperativeThreading` case, which 
now does not strip thread locals in the `!atomics` case, but still does in the 
`!bulk_memory` case. The latter was the reason for removing the `else`. 

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/15] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread Sy Brand via cfe-commits


@@ -1019,7 +1027,7 @@ static void createOptionalSymbols() {
   if (ctx.sym.firstPageEnd)
 ctx.sym.firstPageEnd->setVA(ctx.arg.pageSize);
 
-  // For non-shared memory programs we still need to define __tls_base since we
+  // For non-multithreaded programs we still need to define __tls_base since we
   // allow object files built with TLS to be linked into single threaded
   // programs, and such object files can contain references to this symbol.

TartanLlama wrote:

I've simplified the comment

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/14] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff origin/main HEAD --extensions c,h,cpp -- 
clang/lib/Driver/ToolChains/WebAssembly.cpp clang/test/Driver/wasm-toolchain.c 
lld/wasm/Config.h lld/wasm/Driver.cpp lld/wasm/Relocations.cpp 
lld/wasm/SyntheticSections.cpp lld/wasm/Writer.cpp 
llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp 
llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h 
llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp 
--diff_from_common_commit
``

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:





View the diff from clang-format here.


``diff
diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h
index 517789b2d..f2f1b895f 100644
--- a/lld/wasm/Config.h
+++ b/lld/wasm/Config.h
@@ -136,9 +136,7 @@ struct Config {
   std::optional> extraFeatures;
   llvm::SmallVector buildIdVector;
 
-  bool isMultithreaded() const {
-return sharedMemory || cooperativeThreading;
-  }
+  bool isMultithreaded() const { return sharedMemory || cooperativeThreading; }
 };
 
 // The Ctx object hold all other (non-configuration) global state.
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 90c60da81..16a55b13a 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -561,8 +561,7 @@ static void readConfigs(opt::InputArgList &args) {
   ctx.arg.soName = args.getLastArgValue(OPT_soname);
   ctx.arg.importTable = args.hasArg(OPT_import_table);
   ctx.arg.importUndefined = args.hasArg(OPT_import_undefined);
-  ctx.arg.cooperativeThreading =
-  args.hasArg(OPT_cooperative_threading);
+  ctx.arg.cooperativeThreading = args.hasArg(OPT_cooperative_threading);
   ;
   ctx.arg.ltoo = args::getInteger(args, OPT_lto_O, 2);
   if (ctx.arg.ltoo > 3)
@@ -759,8 +758,7 @@ static void setConfigs() {
   }
   if (ctx.arg.cooperativeThreading) {
 if (ctx.arg.sharedMemory)
-  error(
-  "--cooperative-threading is incompatible with --shared-memory");
+  error("--cooperative-threading is incompatible with --shared-memory");
 ctx.arg.libcallThreadContext = true;
   }
 }

``




https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-08 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/13] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Derek Schuff via cfe-commits

https://github.com/dschuff approved this pull request.


https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Derek Schuff via cfe-commits


@@ -0,0 +1,85 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+# Test that --cooperative-multithreading and --shared-memory are mutually 
exclusive.
+# RUN: not wasm-ld --cooperative-multithreading --shared-memory %t.o -o 
%t2.wasm 2>&1 | FileCheck %s --check-prefix=INCOMPAT
+# INCOMPAT: --cooperative-multithreading is incompatible with --shared-memory
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false

dschuff wrote:

Presumably. Assuming this test is currently passing, does that mean that we 
just don't print the 'Shared' field at all if it's false? I guess in that case 
we could just do `CHECK-NOT: Shared`

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Derek Schuff via cfe-commits


@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"

dschuff wrote:

I think this assertion isn't necessary if we are removing the flag from the 
linker; it should just result in an error, right?

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sam Clegg via cfe-commits

sbc100 wrote:

@dschuff any thoughts on this?

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sam Clegg via cfe-commits


@@ -283,10 +283,17 @@ class CoalesceFeaturesAndStripAtomics final : public 
ModulePass {
 bool StrippedAtomics = false;
 bool StrippedTLS = false;
 
+// In cooperative threading mode, thread locals are meaningful even without
+// atomics.
+bool CooperativeThreading =
+WasmTM->getSubtargetImpl()->hasCooperativeMultithreading();
+
 if (!Features[WebAssembly::FeatureAtomics]) {
   StrippedAtomics = stripAtomics(M);
-  StrippedTLS = stripThreadLocals(M);
-} else if (!Features[WebAssembly::FeatureBulkMemory]) {
+  if (!CooperativeThreading)
+StrippedTLS = stripThreadLocals(M);
+}
+if (!Features[WebAssembly::FeatureBulkMemory]) {

sbc100 wrote:

Does the the removal of the `else` there change the behaviour in the case we 
have atomics enabled but not explicitly bulk memory?

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sam Clegg via cfe-commits


@@ -0,0 +1,85 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+# Test that --cooperative-multithreading and --shared-memory are mutually 
exclusive.
+# RUN: not wasm-ld --cooperative-multithreading --shared-memory %t.o -o 
%t2.wasm 2>&1 | FileCheck %s --check-prefix=INCOMPAT
+# INCOMPAT: --cooperative-multithreading is incompatible with --shared-memory
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false

sbc100 wrote:

Should this be `true`?

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sam Clegg via cfe-commits


@@ -1019,7 +1027,7 @@ static void createOptionalSymbols() {
   if (ctx.sym.firstPageEnd)
 ctx.sym.firstPageEnd->setVA(ctx.arg.pageSize);
 
-  // For non-shared memory programs we still need to define __tls_base since we
+  // For non-multithreaded programs we still need to define __tls_base since we
   // allow object files built with TLS to be linked into single threaded
   // programs, and such object files can contain references to this symbol.

sbc100 wrote:

This sentence has both `non-multithreaded` and `single threaded` which reads a 
little odd to me.

Could we rephrase?  Maybe shorten this sentence somehow?

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sam Clegg via cfe-commits

https://github.com/sbc100 approved this pull request.


https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sam Clegg via cfe-commits


@@ -174,10 +179,10 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");

sbc100 wrote:

How about just just `--cooperative-threading` / WantsCooperativeThreading`?

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/12] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/11] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/10] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-05 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 01/10] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals 

[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-03 Thread Sy Brand via cfe-commits


@@ -57,7 +57,7 @@ void writeGetTLSBase(const Ctx &ctx, raw_ostream &os) {
 writeU8(os, WASM_OPCODE_CALL, "call");
 writeUleb128(os, ctx.sym.getTLSBase->getFunctionIndex(), "function index");
   } else {
-writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_SET");
+writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");

TartanLlama wrote:

Indeed

https://github.com/llvm/llvm-project/pull/200855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)

2026-06-03 Thread Sy Brand via cfe-commits

https://github.com/TartanLlama updated 
https://github.com/llvm/llvm-project/pull/200855

>From 83c5f9ab46715c25d95e0bfe6b6d5b0e1e2dd5b0 Mon Sep 17 00:00:00 2001
From: Sy Brand 
Date: Sun, 31 May 2026 17:23:22 +0100
Subject: [PATCH 1/9] Cooperative multithreading changes

---
 clang/lib/Driver/ToolChains/WebAssembly.cpp   |  8 +-
 clang/test/Driver/wasm-toolchain.c|  7 ++
 lld/test/wasm/cooperative-multithreading.s| 81 +++
 lld/test/wasm/thread-context-abi-mismatch.s   |  4 +-
 lld/wasm/Config.h |  6 ++
 lld/wasm/Driver.cpp   | 11 ++-
 lld/wasm/Options.td   |  5 +-
 lld/wasm/Relocations.cpp  |  2 +-
 lld/wasm/SyntheticSections.cpp| 20 ++---
 lld/wasm/Writer.cpp   | 45 +++
 .../WebAssembly/WebAssemblySubtarget.cpp  |  7 +-
 .../Target/WebAssembly/WebAssemblySubtarget.h |  4 +
 .../WebAssembly/WebAssemblyTargetMachine.cpp  | 11 ++-
 .../WebAssembly/cooperative-strip-tls.ll  | 20 +
 .../WebAssembly/target-features-tls.ll|  1 +
 15 files changed, 193 insertions(+), 39 deletions(-)
 create mode 100644 lld/test/wasm/cooperative-multithreading.s
 create mode 100644 llvm/test/CodeGen/WebAssembly/cooperative-strip-tls.ll

diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 4c1cd937e81aa..ce5463b167a58 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -88,8 +88,8 @@ static bool WantsPthread(const llvm::Triple &Triple, const 
ArgList &Args) {
   return WantsPthread;
 }
 
-static bool WantsLibcallThreadContext(const llvm::Triple &Triple,
-  const ArgList &Args) {
+static bool WantsCooperativeMultithreading(const llvm::Triple &Triple,
+   const ArgList &Args) {
   return Triple.getOS() == llvm::Triple::WASIp3;
 }
 
@@ -174,8 +174,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (WantsLibcallThreadContext(ToolChain.getTriple(), Args))
-CmdArgs.push_back("--libcall-thread-context");
+  if (WantsCooperativeMultithreading(ToolChain.getTriple(), Args))
+CmdArgs.push_back("--cooperative-multithreading");
 
   if (WantsPthread(ToolChain.getTriple(), Args))
 CmdArgs.push_back("--shared-memory");
diff --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index 29a94aeec77a9..40d75da3166d9 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -303,3 +303,10 @@
 // RUN:   | FileCheck -check-prefix=LINK_WALI_BASIC %s
 // LINK_WALI_BASIC: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_WALI_BASIC: wasm-ld{{.*}}" "-L/foo/lib/wasm32-linux-muslwali" "crt1.o" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins.a" "-o" "a.out"
+
+// Test that `wasm32-wasip3` passes `--cooperative-multithreading` to the 
linker.
+
+// RUN: %clang -### --target=wasm32-wasip3 -fuse-ld=lld %s --sysroot /foo 2>&1 
\
+// RUN:   | FileCheck -check-prefix=LINK_WASIP3_COOP %s
+// LINK_WASIP3_COOP: wasm-ld{{.*}}" {{.*}} "--cooperative-multithreading"
+// LINK_WASIP3_COOP-NOT: "--libcall-thread-context"
diff --git a/lld/test/wasm/cooperative-multithreading.s 
b/lld/test/wasm/cooperative-multithreading.s
new file mode 100644
index 0..cb41dd392d5e2
--- /dev/null
+++ b/lld/test/wasm/cooperative-multithreading.s
@@ -0,0 +1,81 @@
+# Test that --cooperative-multithreading uses the libcall ABI naming for
+# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
+# works without --shared-memory and atomics.
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --cooperative-multithreading -no-gc-sections -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | 
FileCheck %s --check-prefix=DIS
+
+.globl __wasm_get_tls_base
+__wasm_get_tls_base:
+.functype   __wasm_get_tls_base () -> (i32)
+i32.const 0
+end_function
+
+.globl _start
+_start:
+  .functype _start () -> (i32)
+  call __wasm_get_tls_base
+  i32.const tls1@TLSREL
+  i32.add
+  i32.load 0
+  call __wasm_get_tls_base
+  i32.const tls2@TLSREL
+  i32.add
+  i32.load 0
+  i32.add
+  end_function
+
+.section  .tdata.tls1,"",@
+.globl  tls1
+tls1:
+  .int32  1
+  .size tls1, 4
+
+.section  .tdata.tls2,"",@
+.globl  tls2
+tls2:
+  .int32  2
+  .size tls2, 4
+
+.section  .custom_section.target_features,"",@
+  .int8 2
+  .int8 43
+  .int8 11
+  .ascii  "bulk-memory"
+  .int8 43
+  .int8 7
+  .ascii  "atomics"
+
+# Memory must NOT be marked as shared.
+# CHECK:  - Type:MEMORY
+# CHECK-NEXT:   Memories:
+# CHECK-NEXT: - Minimum: 0x2
+# CHECK-NOT:   Shared:  false
+
+# Globals