From 7428509ec4543372e28af90af1ed8e628c469745 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sun, 7 Aug 2016 07:58:12 +0000 Subject: [PATCH] [InstSimplify] Fold gep (gep V, C), (sub 0, V) to C git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277952 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/InstructionSimplify.cpp | 20 ++++++++++++++++++++ test/Transforms/InstSimplify/compare.ll | 13 +++++++++++++ 2 files changed, 33 insertions(+) diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 69c60eb6f3c..e6aed6d6816 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -3645,6 +3645,26 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef 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(Ops[i])) diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll index bf22dbda4f1..39e71c8c7ac 100644 --- a/test/Transforms/InstSimplify/compare.ll +++ b/test/Transforms/InstSimplify/compare.ll @@ -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 -- 2.11.0