[llvm] [ValueTracking] Allow getUnderlyingPointer to look through inttoptr/ptrtoint round trip casts (PR #146432)
Drew Kersnar via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 30 16:04:31 PDT 2025
https://github.com/dakersnar created https://github.com/llvm/llvm-project/pull/146432
It has been established in past discussions that optimizing away a round trip ptrtoint -> inttoptr cast in something like InstCombine is not correct (https://www.ralfj.de/blog/2020/12/14/provenance.html, https://github.com/llvm/llvm-project/issues/33896). However, is it possibly correct to strip this round trip when recursing through `getUnderlyingObject`? This would improve alias analysis.
>From f716a09141b201df574b91b627d50b101c6c9d91 Mon Sep 17 00:00:00 2001
From: Drew Kersnar <dkersnar at nvidia.com>
Date: Mon, 30 Jun 2025 22:36:56 +0000
Subject: [PATCH] [ValueTracking] Allow getUnderlyingPointer to look through
inttoptr/ptrtoint round trip casts
---
llvm/lib/Analysis/ValueTracking.cpp | 4 ++++
llvm/unittests/Analysis/ValueTrackingTest.cpp | 12 ++++++++++++
2 files changed, 16 insertions(+)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e576f4899810a..837c6a6caa4b2 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6661,6 +6661,10 @@ const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup) {
if (!NewV->getType()->isPointerTy())
return V;
V = NewV;
+ } else if (Operator::getOpcode(V) == Instruction::IntToPtr &&
+ Operator::getOpcode(cast<Operator>(V)->getOperand(0)) ==
+ Instruction::PtrToInt) {
+ V = cast<Operator>(cast<Operator>(V)->getOperand(0))->getOperand(0);
} else if (auto *GA = dyn_cast<GlobalAlias>(V)) {
if (GA->isInterposable())
return V;
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 129052fbe08b8..b40f38d464ed9 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -3350,6 +3350,18 @@ TEST_F(ValueTrackingTest, ComputeConstantRange) {
}
}
+TEST_F(ValueTrackingTest, GetUnderlyingObject) {
+ parseAssembly(R"(
+ @globalmem = external global i8
+ define void @test() {
+ %A = getelementptr i8, ptr @globalmem, i64 0
+ %A2 = getelementptr i8, ptr inttoptr (i32 ptrtoint (ptr @globalmem to i32) to ptr), i64 0
+ ret void
+ }
+ )");
+ EXPECT_EQ(getUnderlyingObject(A), getUnderlyingObject(A2));
+}
+
struct FindAllocaForValueTestParams {
const char *IR;
bool AnyOffsetResult;
More information about the llvm-commits
mailing list