Skip to content

Conversation

@nikic
Copy link
Contributor

@nikic nikic commented Jul 12, 2024

This is a special case of the general ptrtoint(gep) to add(ptrtoint) transform that is particularly profitable, as everything folds away.

Proof: https://alive2.llvm.org/ce/z/fwv8_L

Fixes #86417.

This is a special case of the general ptrtoint(gep) to
add(ptrtoint) transform that is particularly profitable, as
everything folds away.

Proof: https://alive2.llvm.org/ce/z/fwv8_L

Fixes llvm#86417.
@nikic nikic requested review from dtcxzyw and goldsteinn July 12, 2024 15:18
@llvmbot llvmbot added llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms labels Jul 12, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 12, 2024

@llvm/pr-subscribers-llvm-analysis

Author: Nikita Popov (nikic)

Changes

This is a special case of the general ptrtoint(gep) to add(ptrtoint) transform that is particularly profitable, as everything folds away.

Proof: https://alive2.llvm.org/ce/z/fwv8_L

Fixes #86417.


Full diff: https://github.com/llvm/llvm-project/pull/98649.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+8)
  • (modified) llvm/test/Transforms/InstSimplify/ptrtoint.ll (+2-10)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 0917a362eccf5..242c200f7ef15 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5333,6 +5333,14 @@ static Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
     if (Op->getType() == Ty)
       return Op;
 
+  // ptrtoint (ptradd (Ptr, X - ptrtoint(Ptr))) -> X
+  Value *Ptr, *X;
+  if (CastOpc == Instruction::PtrToInt &&
+      match(Op, m_PtrAdd(m_Value(Ptr),
+                         m_Sub(m_Value(X), m_PtrToInt(m_Deferred(Ptr))))) &&
+      X->getType() == Ty && Ty == Q.DL.getIndexType(Ptr->getType()))
+    return X;
+
   return nullptr;
 }
 
diff --git a/llvm/test/Transforms/InstSimplify/ptrtoint.ll b/llvm/test/Transforms/InstSimplify/ptrtoint.ll
index 55a5a0d452f10..734618713c342 100644
--- a/llvm/test/Transforms/InstSimplify/ptrtoint.ll
+++ b/llvm/test/Transforms/InstSimplify/ptrtoint.ll
@@ -4,11 +4,7 @@
 define i64 @ptrtoint_gep_sub(ptr %ptr, i64 %end.addr) {
 ; CHECK-LABEL: define i64 @ptrtoint_gep_sub(
 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[END_ADDR:%.*]]) {
-; CHECK-NEXT:    [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR]] to i64
-; CHECK-NEXT:    [[SIZE:%.*]] = sub i64 [[END_ADDR]], [[PTR_ADDR]]
-; CHECK-NEXT:    [[END:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[SIZE]]
-; CHECK-NEXT:    [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i64
-; CHECK-NEXT:    ret i64 [[END_ADDR2]]
+; CHECK-NEXT:    ret i64 [[END_ADDR]]
 ;
   %ptr.addr = ptrtoint ptr %ptr to i64
   %size = sub i64 %end.addr, %ptr.addr
@@ -20,11 +16,7 @@ define i64 @ptrtoint_gep_sub(ptr %ptr, i64 %end.addr) {
 define <2 x i64> @ptrtoint_gep_sub_vector(<2 x ptr> %ptr, <2 x i64> %end.addr) {
 ; CHECK-LABEL: define <2 x i64> @ptrtoint_gep_sub_vector(
 ; CHECK-SAME: <2 x ptr> [[PTR:%.*]], <2 x i64> [[END_ADDR:%.*]]) {
-; CHECK-NEXT:    [[PTR_ADDR:%.*]] = ptrtoint <2 x ptr> [[PTR]] to <2 x i64>
-; CHECK-NEXT:    [[SIZE:%.*]] = sub <2 x i64> [[END_ADDR]], [[PTR_ADDR]]
-; CHECK-NEXT:    [[END:%.*]] = getelementptr i8, <2 x ptr> [[PTR]], <2 x i64> [[SIZE]]
-; CHECK-NEXT:    [[END_ADDR2:%.*]] = ptrtoint <2 x ptr> [[END]] to <2 x i64>
-; CHECK-NEXT:    ret <2 x i64> [[END_ADDR2]]
+; CHECK-NEXT:    ret <2 x i64> [[END_ADDR]]
 ;
   %ptr.addr = ptrtoint <2 x ptr> %ptr to <2 x i64>
   %size = sub <2 x i64> %end.addr, %ptr.addr

@llvmbot
Copy link
Member

llvmbot commented Jul 12, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

This is a special case of the general ptrtoint(gep) to add(ptrtoint) transform that is particularly profitable, as everything folds away.

Proof: https://alive2.llvm.org/ce/z/fwv8_L

Fixes #86417.


Full diff: https://github.com/llvm/llvm-project/pull/98649.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+8)
  • (modified) llvm/test/Transforms/InstSimplify/ptrtoint.ll (+2-10)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 0917a362eccf5..242c200f7ef15 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5333,6 +5333,14 @@ static Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
     if (Op->getType() == Ty)
       return Op;
 
+  // ptrtoint (ptradd (Ptr, X - ptrtoint(Ptr))) -> X
+  Value *Ptr, *X;
+  if (CastOpc == Instruction::PtrToInt &&
+      match(Op, m_PtrAdd(m_Value(Ptr),
+                         m_Sub(m_Value(X), m_PtrToInt(m_Deferred(Ptr))))) &&
+      X->getType() == Ty && Ty == Q.DL.getIndexType(Ptr->getType()))
+    return X;
+
   return nullptr;
 }
 
diff --git a/llvm/test/Transforms/InstSimplify/ptrtoint.ll b/llvm/test/Transforms/InstSimplify/ptrtoint.ll
index 55a5a0d452f10..734618713c342 100644
--- a/llvm/test/Transforms/InstSimplify/ptrtoint.ll
+++ b/llvm/test/Transforms/InstSimplify/ptrtoint.ll
@@ -4,11 +4,7 @@
 define i64 @ptrtoint_gep_sub(ptr %ptr, i64 %end.addr) {
 ; CHECK-LABEL: define i64 @ptrtoint_gep_sub(
 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[END_ADDR:%.*]]) {
-; CHECK-NEXT:    [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR]] to i64
-; CHECK-NEXT:    [[SIZE:%.*]] = sub i64 [[END_ADDR]], [[PTR_ADDR]]
-; CHECK-NEXT:    [[END:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[SIZE]]
-; CHECK-NEXT:    [[END_ADDR2:%.*]] = ptrtoint ptr [[END]] to i64
-; CHECK-NEXT:    ret i64 [[END_ADDR2]]
+; CHECK-NEXT:    ret i64 [[END_ADDR]]
 ;
   %ptr.addr = ptrtoint ptr %ptr to i64
   %size = sub i64 %end.addr, %ptr.addr
@@ -20,11 +16,7 @@ define i64 @ptrtoint_gep_sub(ptr %ptr, i64 %end.addr) {
 define <2 x i64> @ptrtoint_gep_sub_vector(<2 x ptr> %ptr, <2 x i64> %end.addr) {
 ; CHECK-LABEL: define <2 x i64> @ptrtoint_gep_sub_vector(
 ; CHECK-SAME: <2 x ptr> [[PTR:%.*]], <2 x i64> [[END_ADDR:%.*]]) {
-; CHECK-NEXT:    [[PTR_ADDR:%.*]] = ptrtoint <2 x ptr> [[PTR]] to <2 x i64>
-; CHECK-NEXT:    [[SIZE:%.*]] = sub <2 x i64> [[END_ADDR]], [[PTR_ADDR]]
-; CHECK-NEXT:    [[END:%.*]] = getelementptr i8, <2 x ptr> [[PTR]], <2 x i64> [[SIZE]]
-; CHECK-NEXT:    [[END_ADDR2:%.*]] = ptrtoint <2 x ptr> [[END]] to <2 x i64>
-; CHECK-NEXT:    ret <2 x i64> [[END_ADDR2]]
+; CHECK-NEXT:    ret <2 x i64> [[END_ADDR]]
 ;
   %ptr.addr = ptrtoint <2 x ptr> %ptr to <2 x i64>
   %size = sub <2 x i64> %end.addr, %ptr.addr

dtcxzyw added a commit to dtcxzyw/llvm-opt-benchmark that referenced this pull request Jul 12, 2024
Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@nikic nikic merged commit 9d34b67 into llvm:main Jul 15, 2024
@nikic nikic deleted the instsimplify-ptrtoint-gep branch July 15, 2024 07:26
nikic added a commit that referenced this pull request Oct 16, 2025
InstCombine currently fails to call into InstSimplify for cast
instructions. I noticed this because the transform from
#98649 can be triggered via
`-passes=instsimplify` but not `-passes=instcombine`, which is not
supposed to happen.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Oct 16, 2025
…2849)

InstCombine currently fails to call into InstSimplify for cast
instructions. I noticed this because the transform from
llvm/llvm-project#98649 can be triggered via
`-passes=instsimplify` but not `-passes=instcombine`, which is not
supposed to happen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize out sub+GEPi when it's used in ptr2int

3 participants