Skip to content

Conversation

@sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Nov 27, 2024

We can simply use the __tls_base global for this which is guaranteed to be non-zero and unique per thread.

Fixes: #117433

@llvmbot
Copy link
Member

llvmbot commented Nov 27, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-backend-webassembly

Author: Sam Clegg (sbc100)

Changes

We can simply use the __tls_base global for this which is guaranteed to be non-zero and unique per thread.

Fixes: #117433


Full diff: https://github.com/llvm/llvm-project/pull/117817.diff

2 Files Affected:

  • (modified) llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (+11)
  • (added) llvm/test/CodeGen/WebAssembly/thread_pointer.ll (+21)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 2d00889407ff48..94b49387b58f91 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -2089,6 +2089,17 @@ SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
     }
     return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
   }
+
+  case Intrinsic::thread_pointer: {
+    MVT PtrVT = getPointerTy(DAG.getDataLayout());
+    auto GlobalGet = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64
+                                       : WebAssembly::GLOBAL_GET_I32;
+    const char *TlsBase = MF.createExternalSymbolName("__tls_base");
+    return SDValue(
+        DAG.getMachineNode(GlobalGet, DL, PtrVT,
+                           DAG.getTargetExternalSymbol(TlsBase, PtrVT)),
+        0);
+  }
   }
 }
 
diff --git a/llvm/test/CodeGen/WebAssembly/thread_pointer.ll b/llvm/test/CodeGen/WebAssembly/thread_pointer.ll
new file mode 100644
index 00000000000000..cca739716fe887
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/thread_pointer.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=wasm32-unknown-unknown | FileCheck %s --check-prefix=wasm32
+; RUN: llc < %s -mtriple=wasm64-unknown-unknown | FileCheck %s --check-prefix=wasm64
+
+declare ptr @llvm.thread.pointer()
+
+define ptr @thread_pointer() nounwind {
+; wasm32-LABEL: thread_pointer:
+; wasm32:         .functype thread_pointer () -> (i32)
+; wasm32-NEXT:  # %bb.0:
+; wasm32-NEXT:    global.get __tls_base
+; wasm32-NEXT:    # fallthrough-return
+;
+; wasm64-LABEL: thread_pointer:
+; wasm64:         .functype thread_pointer () -> (i64)
+; wasm64-NEXT:  # %bb.0:
+; wasm64-NEXT:    global.get __tls_base
+; wasm64-NEXT:    # fallthrough-return
+  %1 = tail call ptr @llvm.thread.pointer()
+  ret ptr %1
+}

@dschuff
Copy link
Member

dschuff commented Nov 27, 2024

Generally LGTM; maybe we also want to add a test for __builtin_thread_pointer to clang/test/CodeGen/builtins-wasm.c

@sbc100
Copy link
Collaborator Author

sbc100 commented Nov 27, 2024

Generally LGTM; maybe we also want to add a test for __builtin_thread_pointer to clang/test/CodeGen/builtins-wasm.c

I only see that testing in clang/test/CodeGen/builtins-arm64.c, most platforms don't seem to test this.

@sbc100
Copy link
Collaborator Author

sbc100 commented Nov 27, 2024

Generally LGTM; maybe we also want to add a test for __builtin_thread_pointer to clang/test/CodeGen/builtins-wasm.c

I only see that testing in clang/test/CodeGen/builtins-arm64.c, most platforms don't seem to test this.

Done!

@llvmbot llvmbot added the clang Clang issues not falling into any other category label Nov 27, 2024
We can simply use the `__tls_base` global for this which is guaranteed
to be non-zero and unique per thread.

Fixes: llvm#117433
@dschuff
Copy link
Member

dschuff commented Nov 27, 2024

Hm, looking at the implementation in clang/lib/CodeGen/CGBuiltin.cpp it should work for any target where isTLSSupported() is true, so I guess there's not much risk of it breaking just for us.

@sbc100 sbc100 changed the title [WebAssembly] Implement %llvm.thread.pointer intrinsic. NFC [WebAssembly] Implement %llvm.thread.pointer intrinsic Nov 27, 2024
@sbc100 sbc100 merged commit ea58410 into llvm:main Nov 27, 2024
5 of 6 checks passed
@sbc100 sbc100 deleted the thread_pointer branch November 27, 2024 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:WebAssembly clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[WebAssembly] ICE when using __builtin_thread_pointer

3 participants