Skip to content

Commit 75c583d

Browse files
committed
GlobalsModRef, ValueTracking: Look through threadlocal.address intrinsic
1 parent 00a4f09 commit 75c583d

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -694,11 +694,11 @@ inline Value *getArgumentAliasingToReturnedPointer(CallBase *Call,
694694
bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(
695695
const CallBase *Call, bool MustPreserveNullness);
696696

697-
/// This method strips off any GEP address adjustments and pointer casts from
698-
/// the specified value, returning the original object being addressed. Note
699-
/// that the returned value has pointer type if the specified value does. If
700-
/// the MaxLookup value is non-zero, it limits the number of instructions to
701-
/// be stripped off.
697+
/// This method strips off any GEP address adjustments, pointer casts
698+
/// or `llvm.threadlocal.address` from the specified value \p V, returning the
699+
/// original object being addressed. Note that the returned value has pointer
700+
/// type if the specified value does. If the \p MaxLookup value is non-zero, it
701+
/// limits the number of instructions to be stripped off.
702702
const Value *getUnderlyingObject(const Value *V, unsigned MaxLookup = 6);
703703
inline Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6) {
704704
// Force const to avoid infinite recursion.

llvm/lib/Analysis/GlobalsModRef.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,14 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
344344
if (AnalyzeUsesOfPointer(I, Readers, Writers, OkayStoreDest))
345345
return true;
346346
} else if (auto *Call = dyn_cast<CallBase>(I)) {
347+
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
348+
if (II->getIntrinsicID() == Intrinsic::threadlocal_address &&
349+
V == II->getArgOperand(0)) {
350+
if (AnalyzeUsesOfPointer(II, Readers, Writers))
351+
return true;
352+
continue;
353+
}
354+
}
347355
// Make sure that this is just the function being called, not that it is
348356
// passing into the function.
349357
if (Call->isDataOperand(&U)) {

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6282,6 +6282,12 @@ const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup) {
62826282
continue;
62836283
}
62846284
} else if (auto *Call = dyn_cast<CallBase>(V)) {
6285+
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(V)) {
6286+
if (II->getIntrinsicID() == Intrinsic::threadlocal_address) {
6287+
V = II->getArgOperand(0);
6288+
continue;
6289+
}
6290+
}
62856291
// CaptureTracking can know about special capturing properties of some
62866292
// intrinsics like launder.invariant.group, that can't be expressed with
62876293
// the attributes, but have properties like returning aliasing pointer.

llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@ entry:
2222
ret i32 %v
2323
}
2424

25+
@g1_tls = internal thread_local global i32 0
26+
27+
define i32 @test1_tls(ptr %param) {
28+
; Ensure that we can fold a store to a load of a global across a store to
29+
; a parameter when the global is non-escaping.
30+
;
31+
; CHECK-LABEL: @test1_tls(
32+
; CHECK: %p = call ptr @llvm.threadlocal.address.p0(ptr @g1_tls)
33+
; CHECK: store i32 42, ptr %p
34+
; CHECK-NOT: load i32
35+
; CHECK: ret i32 42
36+
entry:
37+
%p = call ptr @llvm.threadlocal.address(ptr @g1_tls)
38+
store i32 42, ptr %p
39+
store i32 7, ptr %param
40+
%v = load i32, ptr %p
41+
ret i32 %v
42+
}
43+
2544
declare ptr @f()
2645

2746
define i32 @test2() {

0 commit comments

Comments
 (0)