Skip to content

Commit ea58410

Browse files
authored
[WebAssembly] Implement %llvm.thread.pointer intrinsic (#117817)
We can simply use the `__tls_base` global for this which is guaranteed to be non-zero and unique per thread. Fixes: #117433
1 parent 0f0c0c3 commit ea58410

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

clang/test/CodeGen/builtins-wasm.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,3 +740,8 @@ __externref_t externref_null() {
740740
// WEBASSEMBLY: tail call ptr addrspace(10) @llvm.wasm.ref.null.extern()
741741
// WEBASSEMBLY-NEXT: ret
742742
}
743+
744+
void *tp (void) {
745+
return __builtin_thread_pointer ();
746+
// WEBASSEMBLY: call {{.*}} @llvm.thread.pointer()
747+
}

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,17 @@ SDValue WebAssemblyTargetLowering::LowerIntrinsic(SDValue Op,
20892089
}
20902090
return DAG.getNode(WebAssemblyISD::SHUFFLE, DL, Op.getValueType(), Ops);
20912091
}
2092+
2093+
case Intrinsic::thread_pointer: {
2094+
MVT PtrVT = getPointerTy(DAG.getDataLayout());
2095+
auto GlobalGet = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64
2096+
: WebAssembly::GLOBAL_GET_I32;
2097+
const char *TlsBase = MF.createExternalSymbolName("__tls_base");
2098+
return SDValue(
2099+
DAG.getMachineNode(GlobalGet, DL, PtrVT,
2100+
DAG.getTargetExternalSymbol(TlsBase, PtrVT)),
2101+
0);
2102+
}
20922103
}
20932104
}
20942105

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=wasm32-unknown-unknown | FileCheck %s --check-prefix=WASM32
3+
; RUN: llc < %s -mtriple=wasm64-unknown-unknown | FileCheck %s --check-prefix=WASM64
4+
5+
declare ptr @llvm.thread.pointer()
6+
7+
define ptr @thread_pointer() nounwind {
8+
; WASM32-LABEL: thread_pointer:
9+
; WASM32: .functype thread_pointer () -> (i32)
10+
; WASM32-NEXT: # %bb.0:
11+
; WASM32-NEXT: global.get __tls_base
12+
; WASM32-NEXT: # fallthrough-return
13+
;
14+
; WASM64-LABEL: thread_pointer:
15+
; WASM64: .functype thread_pointer () -> (i64)
16+
; WASM64-NEXT: # %bb.0:
17+
; WASM64-NEXT: global.get __tls_base
18+
; WASM64-NEXT: # fallthrough-return
19+
%1 = tail call ptr @llvm.thread.pointer()
20+
ret ptr %1
21+
}

0 commit comments

Comments
 (0)