InstCombine: When comparing two GEPs that were derived from the same base pointer but use different types, expand the offset calculation and to the compare on the offset if profitable.

This came up in SmallVector code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150962 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer
2012-02-20 15:07:47 +00:00
parent d2348639e6
commit 9bb40853ee
2 changed files with 40 additions and 0 deletions

View File

@@ -607,6 +607,20 @@ Instruction *InstCombiner::FoldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
return new ICmpInst(ICmpInst::getSignedPredicate(Cond),
GEPLHS->getOperand(0), GEPRHS->getOperand(0));
// If we're comparing GEPs with two base pointers that only differ in type
// and both GEPs have only constant indices or just one use, then fold
// the compare with the adjusted indices.
if (TD &&
(GEPLHS->hasAllConstantIndices() || GEPLHS->hasOneUse()) &&
(GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
PtrBase->stripPointerCasts() ==
GEPRHS->getOperand(0)->stripPointerCasts()) {
Value *Cmp = Builder->CreateICmp(ICmpInst::getSignedPredicate(Cond),
EmitGEPOffset(GEPLHS),
EmitGEPOffset(GEPRHS));
return ReplaceInstUsesWith(I, Cmp);
}
// Otherwise, the base pointers are different and the indices are
// different, bail out.
return 0;