Skip to content

Commit 15825b7

Browse files
committed
Auto merge of #139385 - joboet:threadlocal_address, r=nikic
rustc_codegen_llvm: use `threadlocal.address` intrinsic to access TLS Fixes #136044 r? `@nikic`
2 parents aa5832b + e4d9b06 commit 15825b7

File tree

3 files changed

+20
-9
lines changed

3 files changed

+20
-9
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,9 +1452,15 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
14521452
impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
14531453
fn get_static(&mut self, def_id: DefId) -> &'ll Value {
14541454
// Forward to the `get_static` method of `CodegenCx`
1455-
let s = self.cx().get_static(def_id);
1456-
// Cast to default address space if globals are in a different addrspace
1457-
self.cx().const_pointercast(s, self.type_ptr())
1455+
let global = self.cx().get_static(def_id);
1456+
if self.cx().tcx.is_thread_local_static(def_id) {
1457+
let pointer = self.call_intrinsic("llvm.threadlocal.address", &[global]);
1458+
// Cast to default address space if globals are in a different addrspace
1459+
self.pointercast(pointer, self.type_ptr())
1460+
} else {
1461+
// Cast to default address space if globals are in a different addrspace
1462+
self.cx().const_pointercast(global, self.type_ptr())
1463+
}
14581464
}
14591465
}
14601466

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,7 @@ impl<'ll> CodegenCx<'ll, '_> {
12431243
}
12441244

12451245
ifn!("llvm.ptrmask", fn(ptr, t_isize) -> ptr);
1246+
ifn!("llvm.threadlocal.address", fn(ptr) -> ptr);
12461247

12471248
None
12481249
}

tests/codegen/thread-local.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,41 @@ use std::cell::Cell;
1414

1515
thread_local!(static A: Cell<u32> = const { Cell::new(1) });
1616

17-
// CHECK: [[TLS_AUX:@.+]] = external thread_local local_unnamed_addr global i64
18-
// CHECK: [[TLS:@.+]] = internal thread_local unnamed_addr global
17+
// CHECK: [[TLS_AUX:@.+]] = external thread_local{{.*}} global i64
18+
// CHECK: [[TLS:@.+]] = internal thread_local{{.*}} global
1919

2020
// CHECK-LABEL: @get
2121
#[no_mangle]
2222
fn get() -> u32 {
23-
// CHECK: [[RET_0:%.+]] = load i32, {{.*}}[[TLS]]{{.*}}
23+
// CHECK: [[PTR:%.+]] = tail call {{.*}} ptr @llvm.threadlocal.address.p0(ptr [[TLS]])
24+
// CHECK-NEXT: [[RET_0:%.+]] = load i32, ptr [[PTR]]
2425
// CHECK-NEXT: ret i32 [[RET_0]]
2526
A.with(|a| a.get())
2627
}
2728

2829
// CHECK-LABEL: @set
2930
#[no_mangle]
3031
fn set(v: u32) {
31-
// CHECK: store i32 %0, {{.*}}[[TLS]]{{.*}}
32+
// CHECK: [[PTR:%.+]] = tail call {{.*}} ptr @llvm.threadlocal.address.p0(ptr [[TLS]])
33+
// CHECK-NEXT: store i32 %0, ptr [[PTR]]
3234
// CHECK-NEXT: ret void
3335
A.with(|a| a.set(v))
3436
}
3537

3638
// CHECK-LABEL: @get_aux
3739
#[no_mangle]
3840
fn get_aux() -> u64 {
39-
// CHECK: [[RET_1:%.+]] = load i64, {{.*}}[[TLS_AUX]]
41+
// CHECK: [[PTR:%.+]] = tail call {{.*}} ptr @llvm.threadlocal.address.p0(ptr [[TLS_AUX]])
42+
// CHECK-NEXT: [[RET_1:%.+]] = load i64, ptr [[PTR]]
4043
// CHECK-NEXT: ret i64 [[RET_1]]
4144
aux::A.with(|a| a.get())
4245
}
4346

4447
// CHECK-LABEL: @set_aux
4548
#[no_mangle]
4649
fn set_aux(v: u64) {
47-
// CHECK: store i64 %0, {{.*}}[[TLS_AUX]]
50+
// CHECK: [[PTR:%.+]] = tail call {{.*}} ptr @llvm.threadlocal.address.p0(ptr [[TLS_AUX]])
51+
// CHECK-NEXT: store i64 %0, ptr [[PTR]]
4852
// CHECK-NEXT: ret void
4953
aux::A.with(|a| a.set(v))
5054
}

0 commit comments

Comments
 (0)