}
}
+ // 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]))
; 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