[PATCH] D105088: [InstCombine] Fold IntToPtr/PtrToInt to bitcast

Krishna Kariya via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 29 01:28:43 PDT 2021


Krishnakariya created this revision.
Krishnakariya added reviewers: nikic, spatel, nlopes, efriedma.
Herald added subscribers: hiraditya, arichardson.
Krishnakariya requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

The inttoptr/ptrtoint roundtrip optimization is not always correct. We are working towards removing this optimization and adding support to specific cases where this optimization works. This patch is the first one on this line.

Consider the example,

  %i = ptrtoint i8* %X to i64
  %p = inttoptr i64 %i to i16*   
  %cmp = icmp eq i8* %load, %p

In this specific case, the inttoptr/ptrtoint optimization is correct as it only compares the pointers. In this patch, we fold inttoptr/ptrtoint to a bitcast (if src and dest types are different).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D105088

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
  llvm/test/Transforms/InstCombine/ptr-int-ptr-icmp.ll


Index: llvm/test/Transforms/InstCombine/ptr-int-ptr-icmp.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/ptr-int-ptr-icmp.ll
@@ -0,0 +1,37 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -instcombine -S  < %s | FileCheck %s
+
+define i1 @func(i8* %X, i8* %Y) {
+; CHECK-LABEL: @func(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8* [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %i = ptrtoint i8* %X to i64
+  %p = inttoptr i64 %i to i8*
+  %cmp = icmp eq i8* %p, %Y
+  ret i1 %cmp
+}
+
+define i1 @func2(i16* %X, i8* %Y) {
+; CHECK-LABEL: @func2(
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i16* [[X:%.*]] to i8*
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8* [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %i = ptrtoint i16* %X to i64
+  %p = inttoptr i64 %i to i8*
+  %cmp = icmp eq i8* %p, %Y
+  ret i1 %cmp
+}
+
+define i1 @func3(i16* %X, i8* %Y) {
+; CHECK-LABEL: @func3(
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i16* [[X:%.*]] to i8*
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8* [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %i = ptrtoint i16* %X to i64
+  %p = inttoptr i64 %i to i8*
+  %cmp = icmp eq i8* %Y, %p
+  ret i1 %cmp
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4539,6 +4539,21 @@
   auto *CastOp0 = dyn_cast<CastInst>(ICmp.getOperand(0));
   if (!CastOp0)
     return nullptr;
+  
+  // icmp (inttoptr (ptrtoint p1)), p2 --> icmp p1, p2.  
+  if (CastOp0->getOpcode() == Instruction::IntToPtr) {
+    if (auto *I = dyn_cast<PtrToIntInst>(CastOp0->getOperand(0))) {
+      Value *P = I->getOperand(0);
+      Type *Op0Ty = CastOp0->getDestTy();
+      Value *NewOp0 = nullptr;
+      if (I->getSrcTy() != Op0Ty)
+        NewOp0 = Builder.CreateBitCast(P, Op0Ty);
+      else
+        NewOp0 = P;
+      return new ICmpInst(ICmp.getPredicate(), NewOp0, ICmp.getOperand(1));
+    }
+  }
+
   if (!isa<Constant>(ICmp.getOperand(1)) && !isa<CastInst>(ICmp.getOperand(1)))
     return nullptr;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D105088.355131.patch
Type: text/x-patch
Size: 2266 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210629/d501ab51/attachment.bin>


More information about the llvm-commits mailing list