[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