[clang] [lld] [llvm] [WebAssembly] Cooperative threading for WASIP3 (PR #200855)
@@ -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)
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)
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)
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)
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)
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)
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)
@@ -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)
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)
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)
@@ -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)
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)
@@ -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)
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)
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)
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)
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)
@@ -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)
@@ -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)
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)
@@ -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)
@@ -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)
@@ -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)
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)
@@ -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)
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)
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)
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)
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)
@@ -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)
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
