Look through addrspacecasts when turning ptr comparisons into

index comparisons.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210488 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matt Arsenault
2014-06-09 19:20:29 +00:00
parent 77b0b852fa
commit 8a0c2d17f5
2 changed files with 65 additions and 7 deletions

View File

@@ -612,9 +612,10 @@ Instruction *InstCombiner::FoldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
if (ICmpInst::isSigned(Cond))
return nullptr;
// Look through bitcasts.
if (BitCastInst *BCI = dyn_cast<BitCastInst>(RHS))
RHS = BCI->getOperand(0);
// Look through bitcasts and addrspacecasts. We do not however want to remove
// 0 GEPs.
if (!isa<GetElementPtrInst>(RHS))
RHS = RHS->stripPointerCasts();
Value *PtrBase = GEPLHS->getOperand(0);
if (DL && PtrBase == RHS && GEPLHS->isInBounds()) {
@@ -655,9 +656,24 @@ Instruction *InstCombiner::FoldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
(GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
PtrBase->stripPointerCasts() ==
GEPRHS->getOperand(0)->stripPointerCasts()) {
Value *LOffset = EmitGEPOffset(GEPLHS);
Value *ROffset = EmitGEPOffset(GEPRHS);
// If we looked through an addrspacecast between different sized address
// spaces, the LHS and RHS pointers are different sized
// integers. Truncate to the smaller one.
Type *LHSIndexTy = LOffset->getType();
Type *RHSIndexTy = ROffset->getType();
if (LHSIndexTy != RHSIndexTy) {
if (LHSIndexTy->getPrimitiveSizeInBits() <
RHSIndexTy->getPrimitiveSizeInBits()) {
ROffset = Builder->CreateTrunc(ROffset, LHSIndexTy);
} else
LOffset = Builder->CreateTrunc(LOffset, RHSIndexTy);
}
Value *Cmp = Builder->CreateICmp(ICmpInst::getSignedPredicate(Cond),
EmitGEPOffset(GEPLHS),
EmitGEPOffset(GEPRHS));
LOffset, ROffset);
return ReplaceInstUsesWith(I, Cmp);
}