[llvm] [Value] Look through inttoptr (add ..) in accumulateConstantOffsets (PR #124981)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 29 12:32:50 PST 2025


https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/124981

Look through inttoptr (add (ptrtoint P), C) when accumulating offsets.

Adds a missing fold after
https://github.com/llvm/llvm-project/pull/123518

Alive2 for the tests with changes: https://alive2.llvm.org/ce/z/VvPrzv

>From 435936000793fa7edb14225abf6cbe5de2ff94fd Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 29 Jan 2025 20:16:37 +0000
Subject: [PATCH 1/2] [Value ] Add tests with cmps with inttoptr (add ..)
 ConstExpr.

---
 .../constant-fold-inttoptr-add.ll             | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 llvm/test/Transforms/InstSimplify/constant-fold-inttoptr-add.ll

diff --git a/llvm/test/Transforms/InstSimplify/constant-fold-inttoptr-add.ll b/llvm/test/Transforms/InstSimplify/constant-fold-inttoptr-add.ll
new file mode 100644
index 00000000000000..50f63f75b98c3e
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/constant-fold-inttoptr-add.ll
@@ -0,0 +1,87 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -p instcombine -S %s | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+
+ at glob = external global [314 x i64]
+
+define i1 @known_constexpr_add_eq() {
+; CHECK-LABEL: define i1 @known_constexpr_add_eq() {
+; CHECK-NEXT:    [[COND:%.*]] = icmp eq ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %cond = icmp eq ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+  ret i1 %cond
+}
+
+define i1 @known_constexpr_add_ne() {
+; CHECK-LABEL: define i1 @known_constexpr_add_ne() {
+; CHECK-NEXT:    [[COND:%.*]] = icmp ne ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %cond = icmp ne ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+  ret i1 %cond
+}
+
+define i1 @wrap_positive_to_negate() {
+; CHECK-LABEL: define i1 @wrap_positive_to_negate() {
+; CHECK-NEXT:    ret i1 false
+;
+  %cond = icmp eq ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr getelementptr nuw (i8, ptr @glob, i64 1)to i64), i64 9223372036854775808) to ptr)
+  ret i1 %cond
+}
+
+; 9223372036854775808 = 2^63
+define i1 @wrap_positive_to_zero() {
+; CHECK-LABEL: define i1 @wrap_positive_to_zero() {
+; CHECK-NEXT:    [[COND:%.*]] = icmp eq ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr getelementptr nuw (i8, ptr @glob, i64 -9223372036854775808) to i64), i64 -9223372036854775808) to ptr)
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %cond = icmp eq ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr getelementptr nuw (i8, ptr @glob, i64 9223372036854775808)to i64), i64 9223372036854775808) to ptr)
+  ret i1 %cond
+}
+
+define i1 @not_known_constexpr_add_sle() {
+; CHECK-LABEL: define i1 @not_known_constexpr_add_sle() {
+; CHECK-NEXT:    [[COND:%.*]] = icmp sle ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %cond = icmp sle ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+  ret i1 %cond
+}
+
+define i1 @not_known_constexpr_add_ule() {
+; CHECK-LABEL: define i1 @not_known_constexpr_add_ule() {
+; CHECK-NEXT:    [[COND:%.*]] = icmp ule ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %cond = icmp ule ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+  ret i1 %cond
+}
+
+define i1 @not_known_constexpr_add_sge() {
+; CHECK-LABEL: define i1 @not_known_constexpr_add_sge() {
+; CHECK-NEXT:    [[COND:%.*]] = icmp sge ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %cond = icmp sge ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+  ret i1 %cond
+}
+
+define i1 @not_known_constexpr_add_uge() {
+; CHECK-LABEL: define i1 @not_known_constexpr_add_uge() {
+; CHECK-NEXT:    [[COND:%.*]] = icmp uge ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %cond = icmp uge ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
+  ret i1 %cond
+}
+
+define i1 @not_known_integer_width_does_not_match_pointer_index_width() {
+; CHECK-LABEL: define i1 @not_known_integer_width_does_not_match_pointer_index_width() {
+; CHECK-NEXT:    [[COND:%.*]] = icmp eq ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i32 add (i32 ptrtoint (ptr @glob to i32), i32 -80) to ptr)
+; CHECK-NEXT:    ret i1 [[COND]]
+;
+  %cond = icmp eq ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i32 add (i32 ptrtoint (ptr @glob to i32), i32 -80) to ptr)
+  ret i1 %cond
+}

>From 0982e7649c1334cc2d2073d1c4544f3bcd9652cb Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 29 Jan 2025 20:23:07 +0000
Subject: [PATCH 2/2] [Value] Look through inttoptr (add ..) in
 accumulateConstantOffsets

Look through inttoptr (add (ptrtoint P), C) when accumulating offsets.

Adds a missing fold after
https://github.com/llvm/llvm-project/pull/123518

Alive2 for the tests with changes: https://alive2.llvm.org/ce/z/VvPrzv
---
 llvm/lib/Analysis/ConstantFolding.cpp         |  9 +++++----
 llvm/lib/IR/Value.cpp                         | 19 +++++++++++++++++++
 .../constant-fold-inttoptr-add.ll             |  9 +++------
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 80c1277e631653..04741c57492ae6 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1258,11 +1258,12 @@ Constant *llvm::ConstantFoldCompareInstOperands(
     if (Ops0->getType()->isPointerTy() && !ICmpInst::isSigned(Predicate)) {
       unsigned IndexWidth = DL.getIndexTypeSizeInBits(Ops0->getType());
       APInt Offset0(IndexWidth, 0);
-      Value *Stripped0 =
-          Ops0->stripAndAccumulateInBoundsConstantOffsets(DL, Offset0);
+      bool AllowNonInbounds = ICmpInst::isEquality(Predicate);
+      Value *Stripped0 = Ops0->stripAndAccumulateConstantOffsets(
+          DL, Offset0, AllowNonInbounds);
       APInt Offset1(IndexWidth, 0);
-      Value *Stripped1 =
-          Ops1->stripAndAccumulateInBoundsConstantOffsets(DL, Offset1);
+      Value *Stripped1 = Ops1->stripAndAccumulateConstantOffsets(
+          DL, Offset1, AllowNonInbounds);
       if (Stripped0 == Stripped1)
         return ConstantInt::getBool(
             Ops0->getContext(),
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index eddb67282fca46..48905609429b19 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -775,6 +775,25 @@ const Value *Value::stripAndAccumulateConstantOffsets(
           V = RV;
         if (AllowInvariantGroup && Call->isLaunderOrStripInvariantGroup())
           V = Call->getArgOperand(0);
+    } else if (auto *Int2Ptr = dyn_cast<Operator>(V)) {
+      // Try to accumulate across (inttoptr (add (ptrtoint p), off)).
+      if (!Int2Ptr || Int2Ptr->getOpcode() != Instruction::IntToPtr ||
+          Int2Ptr->getOperand(0)->getType()->getScalarSizeInBits() != BitWidth)
+        return V;
+      auto *Add = dyn_cast<AddOperator>(Int2Ptr->getOperand(0));
+      if (!AllowNonInbounds || !Add)
+        return V;
+      auto *Ptr2Int = dyn_cast<PtrToIntOperator>(Add->getOperand(0));
+      auto *CI = dyn_cast<ConstantInt>(Add->getOperand(1));
+      if (!Ptr2Int || !CI)
+        return V;
+
+      APInt AddOffset = CI->getValue();
+      if (AddOffset.getSignificantBits() > BitWidth)
+        return V;
+
+      Offset = AddOffset.sextOrTrunc(BitWidth);
+      V = Ptr2Int->getOperand(0);
     }
     assert(V->getType()->isPtrOrPtrVectorTy() && "Unexpected operand type!");
   } while (Visited.insert(V).second);
diff --git a/llvm/test/Transforms/InstSimplify/constant-fold-inttoptr-add.ll b/llvm/test/Transforms/InstSimplify/constant-fold-inttoptr-add.ll
index 50f63f75b98c3e..a0a34e2fe73958 100644
--- a/llvm/test/Transforms/InstSimplify/constant-fold-inttoptr-add.ll
+++ b/llvm/test/Transforms/InstSimplify/constant-fold-inttoptr-add.ll
@@ -7,8 +7,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:
 
 define i1 @known_constexpr_add_eq() {
 ; CHECK-LABEL: define i1 @known_constexpr_add_eq() {
-; CHECK-NEXT:    [[COND:%.*]] = icmp eq ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
-; CHECK-NEXT:    ret i1 [[COND]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cond = icmp eq ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
   ret i1 %cond
@@ -16,8 +15,7 @@ define i1 @known_constexpr_add_eq() {
 
 define i1 @known_constexpr_add_ne() {
 ; CHECK-LABEL: define i1 @known_constexpr_add_ne() {
-; CHECK-NEXT:    [[COND:%.*]] = icmp ne ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
-; CHECK-NEXT:    ret i1 [[COND]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cond = icmp ne ptr getelementptr inbounds nuw (i8, ptr @glob, i64 80), inttoptr (i64 add (i64 ptrtoint (ptr @glob to i64), i64 -80) to ptr)
   ret i1 %cond
@@ -34,8 +32,7 @@ define i1 @wrap_positive_to_negate() {
 ; 9223372036854775808 = 2^63
 define i1 @wrap_positive_to_zero() {
 ; CHECK-LABEL: define i1 @wrap_positive_to_zero() {
-; CHECK-NEXT:    [[COND:%.*]] = icmp eq ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr getelementptr nuw (i8, ptr @glob, i64 -9223372036854775808) to i64), i64 -9223372036854775808) to ptr)
-; CHECK-NEXT:    ret i1 [[COND]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cond = icmp eq ptr @glob, inttoptr (i64 add (i64 ptrtoint (ptr getelementptr nuw (i8, ptr @glob, i64 9223372036854775808)to i64), i64 9223372036854775808) to ptr)
   ret i1 %cond



More information about the llvm-commits mailing list