[llvm] GlobalsModRef, ValueTracking: Look through threadlocal.address intrinsic (PR #88418)
Matthias Braun via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 11 10:47:50 PDT 2024
https://github.com/MatzeB created https://github.com/llvm/llvm-project/pull/88418
Analyses should typically look through `threadlocal.address` intrinsic to get at the underlying `GlobalValue`. This fixes `GlobalsAAResult::AnalyzeUsesOfPointer` and `llvm::getUnderlyingObject`.
>From 78a7c78b537bcd928160e26abdb20d1f72a400f2 Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Thu, 11 Apr 2024 10:33:00 -0700
Subject: [PATCH] GlobalsModRef, ValueTracking: Look through
threadlocal.address intrinsic
---
llvm/lib/Analysis/GlobalsModRef.cpp | 8 ++++++++
llvm/lib/Analysis/ValueTracking.cpp | 6 ++++++
.../GlobalsModRef/nonescaping-noalias.ll | 19 +++++++++++++++++++
3 files changed, 33 insertions(+)
diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp
index 527f19b194eeb9..1ceb1b26294183 100644
--- a/llvm/lib/Analysis/GlobalsModRef.cpp
+++ b/llvm/lib/Analysis/GlobalsModRef.cpp
@@ -344,6 +344,14 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
if (AnalyzeUsesOfPointer(I, Readers, Writers, OkayStoreDest))
return true;
} else if (auto *Call = dyn_cast<CallBase>(I)) {
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
+ if (II->getIntrinsicID() == Intrinsic::threadlocal_address &&
+ V == II->getArgOperand(0)) {
+ if (AnalyzeUsesOfPointer(II, Readers, Writers))
+ return true;
+ continue;
+ }
+ }
// Make sure that this is just the function being called, not that it is
// passing into the function.
if (Call->isDataOperand(&U)) {
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3a10de72a27562..d25ebd80d2411d 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6269,6 +6269,12 @@ const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup) {
continue;
}
} else if (auto *Call = dyn_cast<CallBase>(V)) {
+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(V)) {
+ if (II->getIntrinsicID() == Intrinsic::threadlocal_address) {
+ V = II->getArgOperand(0);
+ continue;
+ }
+ }
// CaptureTracking can know about special capturing properties of some
// intrinsics like launder.invariant.group, that can't be expressed with
// the attributes, but have properties like returning aliasing pointer.
diff --git a/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll b/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
index d109b3b8748ba7..f28e73c48b3e8e 100644
--- a/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
+++ b/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
@@ -22,6 +22,25 @@ entry:
ret i32 %v
}
+ at g1_tls = internal thread_local global i32 0
+
+define i32 @test1_tls(ptr %param) {
+; Ensure that we can fold a store to a load of a global across a store to
+; a parameter when the global is non-escaping.
+;
+; CHECK-LABEL: @test1_tls(
+; CHECK: %p = call ptr @llvm.threadlocal.address.p0(ptr @g1_tls)
+; CHECK: store i32 42, ptr %p
+; CHECK-NOT: load i32
+; CHECK: ret i32 42
+entry:
+ %p = call ptr @llvm.threadlocal.address(ptr @g1_tls)
+ store i32 42, ptr %p
+ store i32 7, ptr %param
+ %v = load i32, ptr %p
+ ret i32 %v
+}
+
declare ptr @f()
define i32 @test2() {
More information about the llvm-commits
mailing list