Skip to content

Commit 864f0ff

Browse files
authored
[clang][IR] Overload @llvm.thread.pointer to support non-AS0 targets (llvm#132489)
Thread-local globals live, by default, in the default globals address space, which may not be 0, so we need to overload @llvm.thread.pointer to support other address spaces, and use the default globals address space in Clang.
1 parent 0ab67ec commit 864f0ff

File tree

23 files changed

+74
-50
lines changed

23 files changed

+74
-50
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6115,8 +6115,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
61156115
case Builtin::BI__builtin_thread_pointer: {
61166116
if (!getContext().getTargetInfo().isTLSSupported())
61176117
CGM.ErrorUnsupported(E, "__builtin_thread_pointer");
6118-
// Fall through - it's already mapped to the intrinsic by ClangBuiltin.
6119-
break;
6118+
6119+
return RValue::get(Builder.CreateIntrinsic(llvm::Intrinsic::thread_pointer,
6120+
{GlobalsInt8PtrTy}, {}));
61206121
}
61216122
case Builtin::BI__builtin_os_log_format:
61226123
return emitBuiltinOSLogFormat(*E);

clang/test/CodeGen/builtins-arm64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ void f0(void *a, void *b) {
1010

1111
void *tp (void) {
1212
return __builtin_thread_pointer ();
13-
// CHECK-LINUX: call {{.*}} @llvm.thread.pointer()
13+
// CHECK-LINUX: call {{.*}} @llvm.thread.pointer.p0()
1414
}
1515

1616
// CHECK: call {{.*}} @llvm.bitreverse.i32(i32 %a)

clang/test/CodeGen/builtins-wasm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,5 +749,5 @@ int externref_is_null(__externref_t arg) {
749749

750750
void *tp (void) {
751751
return __builtin_thread_pointer ();
752-
// WEBASSEMBLY: call {{.*}} @llvm.thread.pointer()
752+
// WEBASSEMBLY: call {{.*}} @llvm.thread.pointer.p0()
753753
}

llvm/docs/LangRef.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3133,6 +3133,9 @@ as follows:
31333133
program memory space defaults to the default address space of 0,
31343134
which corresponds to a Von Neumann architecture that has code
31353135
and data in the same space.
3136+
3137+
.. _globals_addrspace:
3138+
31363139
``G<address space>``
31373140
Specifies the address space to be used by default when creating global
31383141
variables. If omitted, the globals address space defaults to the default
@@ -15061,7 +15064,8 @@ Syntax:
1506115064

1506215065
::
1506315066

15064-
declare ptr @llvm.thread.pointer()
15067+
declare ptr @llvm.thread.pointer.p0()
15068+
declare ptr addrspace(5) @llvm.thread.pointer.p5()
1506515069

1506615070
Overview:
1506715071
"""""""""
@@ -15078,7 +15082,8 @@ specific: it may point to the start of TLS area, to the end, or somewhere
1507815082
in the middle. Depending on the target, this intrinsic may read a register,
1507915083
call a helper function, read from an alternate memory space, or perform
1508015084
other operations necessary to locate the TLS area. Not all targets support
15081-
this intrinsic.
15085+
this intrinsic. The address space must be the :ref:`globals address space
15086+
<globals_addrspace>`.
1508215087

1508315088
'``llvm.call.preallocated.setup``' Intrinsic
1508415089
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ def int_stackrestore : DefaultAttrsIntrinsic<[], [llvm_anyptr_ty]>,
903903

904904
def int_get_dynamic_area_offset : DefaultAttrsIntrinsic<[llvm_anyint_ty]>;
905905

906-
def int_thread_pointer : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
906+
def int_thread_pointer : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [], [IntrNoMem]>,
907907
ClangBuiltin<"__builtin_thread_pointer">;
908908

909909
// IntrInaccessibleMemOrArgMemOnly is a little more pessimistic than strictly

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,8 @@ static bool upgradeArmOrAarch64IntrinsicFunction(bool IsArm, Function *F,
646646

647647
if (Name == "thread.pointer") {
648648
// '(arm|aarch64).thread.pointer'.
649-
NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(),
650-
Intrinsic::thread_pointer);
649+
NewFn = Intrinsic::getOrInsertDeclaration(
650+
F->getParent(), Intrinsic::thread_pointer, F->getReturnType());
651651
return true;
652652
}
653653

@@ -1475,6 +1475,14 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn,
14751475
}
14761476
break;
14771477

1478+
case 't':
1479+
if (Name == "thread.pointer") {
1480+
NewFn = Intrinsic::getDeclaration(
1481+
F->getParent(), Intrinsic::thread_pointer, F->getReturnType());
1482+
return true;
1483+
}
1484+
break;
1485+
14781486
case 'v': {
14791487
if (Name == "var.annotation" && F->arg_size() == 4) {
14801488
rename(F);

llvm/lib/IR/Verifier.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6553,6 +6553,14 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
65536553
&Call);
65546554
break;
65556555
}
6556+
case Intrinsic::thread_pointer: {
6557+
Check(Call.getType()->getPointerAddressSpace() ==
6558+
DL.getDefaultGlobalsAddressSpace(),
6559+
"llvm.thread.pointer intrinsic return type must be for the globals "
6560+
"address space",
6561+
&Call);
6562+
break;
6563+
}
65566564
case Intrinsic::threadlocal_address: {
65576565
const Value &Arg0 = *Call.getArgOperand(0);
65586566
Check(isa<GlobalValue>(Arg0),

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28169,8 +28169,8 @@ bool AArch64TargetLowering::shouldNormalizeToSelectSequence(LLVMContext &,
2816928169

2817028170
static Value *UseTlsOffset(IRBuilderBase &IRB, unsigned Offset) {
2817128171
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
28172-
Function *ThreadPointerFunc =
28173-
Intrinsic::getOrInsertDeclaration(M, Intrinsic::thread_pointer);
28172+
Function *ThreadPointerFunc = Intrinsic::getOrInsertDeclaration(
28173+
M, Intrinsic::thread_pointer, IRB.getPtrTy());
2817428174
return IRB.CreatePointerCast(
2817528175
IRB.CreateConstGEP1_32(IRB.getInt8Ty(), IRB.CreateCall(ThreadPointerFunc),
2817628176
Offset),

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23431,8 +23431,8 @@ bool RISCVTargetLowering::preferScalarizeSplat(SDNode *N) const {
2343123431

2343223432
static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
2343323433
Module *M = IRB.GetInsertBlock()->getModule();
23434-
Function *ThreadPointerFunc =
23435-
Intrinsic::getOrInsertDeclaration(M, Intrinsic::thread_pointer);
23434+
Function *ThreadPointerFunc = Intrinsic::getOrInsertDeclaration(
23435+
M, Intrinsic::thread_pointer, IRB.getPtrTy());
2343623436
return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
2343723437
IRB.CreateCall(ThreadPointerFunc), Offset);
2343823438
}

llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,9 @@ Value *getAndroidSlotPtr(IRBuilder<> &IRB, int Slot) {
290290
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
291291
// Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER
292292
// in Bionic's libc/private/bionic_tls.h.
293-
Function *ThreadPointerFunc =
294-
Intrinsic::getOrInsertDeclaration(M, Intrinsic::thread_pointer);
293+
Function *ThreadPointerFunc = Intrinsic::getOrInsertDeclaration(
294+
M, Intrinsic::thread_pointer,
295+
IRB.getPtrTy(M->getDataLayout().getDefaultGlobalsAddressSpace()));
295296
return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
296297
IRB.CreateCall(ThreadPointerFunc), 8 * Slot);
297298
}

llvm/test/Assembler/autoupgrade-thread-pointer.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ declare ptr @llvm.arm.thread.pointer()
66

77
define ptr @test1() {
88
; CHECK-LABEL: define ptr @test1()
9-
; CHECK: call ptr @llvm.thread.pointer()
9+
; CHECK: call ptr @llvm.thread.pointer.p0()
1010
%1 = call ptr @llvm.aarch64.thread.pointer()
1111
ret ptr %1
1212
}
1313

1414
define ptr @test2() {
1515
; CHECK-LABEL: define ptr @test2()
16-
; CHECK: call ptr @llvm.thread.pointer()
16+
; CHECK: call ptr @llvm.thread.pointer.p0()
1717
%1 = call ptr @llvm.arm.thread.pointer()
1818
ret ptr %1
1919
}

llvm/test/CodeGen/AArch64/stack-tagging-prologue.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ entry:
2323

2424
; INSTR-LABEL: define void @OneVar(
2525
; INSTR: [[BASE:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
26-
; INSTR: [[TLS:%.*]] = call ptr @llvm.thread.pointer()
26+
; INSTR: [[TLS:%.*]] = call ptr @llvm.thread.pointer.p0()
2727
; INSTR: [[TLS_SLOT:%.*]] = getelementptr i8, ptr [[TLS]], i32 -24
2828
; INSTR: [[TLS_VALUE:%.*]] = load i64, ptr [[TLS_SLOT]], align 8
2929
; INSTR: [[FP:%.*]] = call ptr @llvm.frameaddress.p0(i32 0)

llvm/test/Instrumentation/HWAddressSanitizer/alloca-array.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ declare void @use(ptr, ptr)
99
define void @test_alloca() sanitize_hwaddress {
1010
; CHECK-LABEL: define void @test_alloca
1111
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
12-
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.thread.pointer()
12+
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.thread.pointer.p0()
1313
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
1414
; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
1515
; CHECK-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3

llvm/test/Instrumentation/HWAddressSanitizer/alloca-compat.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ declare void @use32(ptr)
1111
define void @test_alloca() sanitize_hwaddress {
1212
; CHECK-LABEL: define void @test_alloca
1313
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
14-
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.thread.pointer()
14+
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.thread.pointer.p0()
1515
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i32 48
1616
; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
1717
; CHECK-NEXT: [[TMP4:%.*]] = ashr i64 [[TMP3]], 3

llvm/test/Instrumentation/HWAddressSanitizer/alloca-with-calls.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ define void @test_alloca() sanitize_hwaddress {
1212
; CHECK-LABEL: define void @test_alloca
1313
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
1414
; CHECK-NEXT: entry:
15-
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer()
15+
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer.p0()
1616
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
1717
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 8
1818
; CHECK-NEXT: [[TMP3:%.*]] = ashr i64 [[TMP2]], 3

llvm/test/Instrumentation/HWAddressSanitizer/exception-lifetime.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ define void @test() sanitize_hwaddress personality ptr @__gxx_personality_v0 {
1818
; CHECK-LABEL: define void @test
1919
; CHECK-SAME: () #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 {
2020
; CHECK-NEXT: entry:
21-
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer()
21+
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer.p0()
2222
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
2323
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 8
2424
; CHECK-NEXT: [[TMP3:%.*]] = ashr i64 [[TMP2]], 3

llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ define void @test_alloca() sanitize_hwaddress {
8888
; CHECK-LABEL: define void @test_alloca
8989
; CHECK-SAME: () #[[ATTR0]] {
9090
; CHECK-NEXT: entry:
91-
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer()
91+
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer.p0()
9292
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
9393
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 8
9494
; CHECK-NEXT: [[TMP3:%.*]] = ashr i64 [[TMP2]], 3
@@ -134,7 +134,7 @@ define void @test_alloca() sanitize_hwaddress {
134134
; NOIFUNC-TLS-HISTORY-LABEL: define void @test_alloca
135135
; NOIFUNC-TLS-HISTORY-SAME: () #[[ATTR0]] {
136136
; NOIFUNC-TLS-HISTORY-NEXT: entry:
137-
; NOIFUNC-TLS-HISTORY-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer()
137+
; NOIFUNC-TLS-HISTORY-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer.p0()
138138
; NOIFUNC-TLS-HISTORY-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
139139
; NOIFUNC-TLS-HISTORY-NEXT: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 8
140140
; NOIFUNC-TLS-HISTORY-NEXT: [[TMP3:%.*]] = ashr i64 [[TMP2]], 3

llvm/test/Instrumentation/HWAddressSanitizer/use-after-scope-setjmp.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ define dso_local noundef i1 @_Z6targetv() sanitize_hwaddress {
1212
; CHECK-LABEL: define dso_local noundef i1 @_Z6targetv
1313
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
1414
; CHECK-NEXT: entry:
15-
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer()
15+
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @llvm.thread.pointer.p0()
1616
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 48
1717
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 8
1818
; CHECK-NEXT: [[TMP3:%.*]] = ashr i64 [[TMP2]], 3

0 commit comments

Comments
 (0)