[InstSimplify] Fold gep (gep V, C), (sub 0, V) to C
authorDavid Majnemer <david.majnemer@gmail.com>
Sun, 7 Aug 2016 07:58:12 +0000 (07:58 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sun, 7 Aug 2016 07:58:12 +0000 (07:58 +0000)
llvm-svn: 277952

llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/compare.ll

index 69c60eb..e6aed6d 100644 (file)
@@ -3645,6 +3645,26 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
     }
   }
 
+  // gep (gep V, C), (sub 0, V) -> C
+  if (Q.DL.getTypeAllocSize(LastType) == 1 &&
+      all_of(Ops.slice(1).drop_back(1),
+             [](Value *Idx) { return match(Idx, m_Zero()); })) {
+    unsigned PtrWidth =
+        Q.DL.getPointerSizeInBits(Ops[0]->getType()->getPointerAddressSpace());
+    if (Q.DL.getTypeSizeInBits(Ops.back()->getType()) == PtrWidth) {
+      APInt BasePtrOffset(PtrWidth, 0);
+      Value *StrippedBasePtr =
+          Ops[0]->stripAndAccumulateInBoundsConstantOffsets(Q.DL,
+                                                            BasePtrOffset);
+
+      if (match(Ops.back(),
+                m_Sub(m_Zero(), m_PtrToInt(m_Specific(StrippedBasePtr))))) {
+        auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset);
+        return ConstantExpr::getIntToPtr(CI, GEPTy);
+      }
+    }
+  }
+
   // Check to see if this is constant foldable.
   for (unsigned i = 0, e = Ops.size(); i != e; ++i)
     if (!isa<Constant>(Ops[i]))
index bf22dbd..39e71c8 100644 (file)
@@ -219,6 +219,19 @@ define i1 @gep17() {
 ; CHECK-NEXT: ret i1 true
 }
 
+define i32 @gep18() {
+; CHECK-LABEL: @gep18(
+  %alloca = alloca i32, align 4                                     ; alloca + 0
+  %gep = getelementptr inbounds i32, i32* %alloca, i32 1            ; alloca + 4
+  %bc = bitcast i32* %gep to [4 x i8]*                              ; alloca + 4
+  %pti = ptrtoint i32* %alloca to i32                               ; alloca
+  %sub = sub i32 0, %pti                                            ; -alloca
+  %add = getelementptr [4 x i8], [4 x i8]* %bc, i32 0, i32 %sub     ; alloca + 4 - alloca == 4
+  %add_to_int = ptrtoint i8* %add to i32                            ; 4
+  ret i32 %add_to_int                                               ; 4
+; CHECK-NEXT: ret i32 4
+}
+
 define i1 @zext(i32 %x) {
 ; CHECK-LABEL: @zext(
   %e1 = zext i32 %x to i64