diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 9c658cfbd1e..9896bc76930 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -263,14 +263,32 @@ public: return true; // Values are always values. } - /// stripPointerCasts - This method strips off any unneeded pointer - /// casts from the specified value, returning the original uncasted value. - /// Note that the returned value has pointer type if the specified value does. + /// stripPointerCasts - This method strips off any unneeded pointer casts and + /// all-zero GEPs from the specified value, returning the original uncasted + /// value. If this is called on a non-pointer value, it returns 'this'. Value *stripPointerCasts(); const Value *stripPointerCasts() const { return const_cast(this)->stripPointerCasts(); } + /// stripConstantOffsets - This method strips off unneeded pointer casts and + /// all-constant GEPs from the specified value, returning the original + /// pointer value. If this is called on a non-pointer value, it returns + /// 'this'. + Value *stripConstantOffsets(); + const Value *stripConstantOffsets() const { + return const_cast(this)->stripConstantOffsets(); + } + + /// stripInBoundsOffsets - This method strips off unneeded pointer casts and + /// any in-bounds Offsets from the specified value, returning the original + /// pointer value. If this is called on a non-pointer value, it returns + /// 'this'. + Value *stripInBoundsOffsets(); + const Value *stripInBoundsOffsets() const { + return const_cast(this)->stripInBoundsOffsets(); + } + /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. bool isDereferenceablePointer() const; diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 370ab962888..c024e9260b1 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -1522,28 +1522,6 @@ static Value *ExtractEquivalentCondition(Value *V, CmpInst::Predicate Pred, return 0; } -/// stripPointerAdjustments - This is like Value::stripPointerCasts, but also -/// removes inbounds gep operations, regardless of their indices. -static Value *stripPointerAdjustmentsImpl(Value *V, - SmallPtrSet &VisitedGEPs) { - GEPOperator *GEP = dyn_cast(V); - if (GEP == 0 || !GEP->isInBounds()) - return V; - - // If we've already seen this GEP, we will end up infinitely looping. This - // can happen in unreachable code. - if (!VisitedGEPs.insert(GEP)) - return V; - - return stripPointerAdjustmentsImpl(GEP->getOperand(0)->stripPointerCasts(), - VisitedGEPs); -} - -static Value *stripPointerAdjustments(Value *V) { - SmallPtrSet VisitedGEPs; - return stripPointerAdjustmentsImpl(V, VisitedGEPs); -} - /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// fold the result. If not, this returns null. @@ -1625,9 +1603,9 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, // Be more aggressive about stripping pointer adjustments when checking a // comparison of an alloca address to another object. We can rip off all // inbounds GEP operations, even if they are variable. - LHSPtr = stripPointerAdjustments(LHSPtr); + LHSPtr = LHSPtr->stripInBoundsOffsets(); if (llvm::isIdentifiedObject(LHSPtr)) { - RHSPtr = stripPointerAdjustments(RHSPtr); + RHSPtr = RHSPtr->stripInBoundsOffsets(); if (llvm::isKnownNonNull(LHSPtr) || llvm::isKnownNonNull(RHSPtr)) { // If both sides are different identified objects, they aren't equal // unless they're null. @@ -1644,7 +1622,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, if (llvm::isKnownNonNull(LHSPtr) && isa(RHSPtr)) return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred)); } else if (isa(LHSPtr)) { - RHSPtr = stripPointerAdjustments(RHSPtr); + RHSPtr = RHSPtr->stripInBoundsOffsets(); // An alloca can't be equal to an argument. if (isa(RHSPtr)) return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred)); diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 207c06d2231..40b2d95e3d0 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -317,20 +317,43 @@ void Value::replaceAllUsesWith(Value *New) { BB->replaceSuccessorsPhiUsesWith(cast(New)); } -Value *Value::stripPointerCasts() { - if (!getType()->isPointerTy()) - return this; +namespace { +// Various metrics for how much to strip off of pointers. +enum PointerStripKind { + PSK_ZeroIndices, + PSK_ConstantIndices, + PSK_InBounds, + PSK_All +}; + +template +static Value *stripPointerCastsAndOffsets(Value *V) { + if (!V->getType()->isPointerTy()) + return V; // Even though we don't look through PHI nodes, we could be called on an // instruction in an unreachable block, which may be on a cycle. SmallPtrSet Visited; - Value *V = this; Visited.insert(V); do { if (GEPOperator *GEP = dyn_cast(V)) { - if (!GEP->hasAllZeroIndices()) - return V; + switch (StripKind) { + case PSK_ZeroIndices: + if (!GEP->hasAllZeroIndices()) + return V; + break; + case PSK_ConstantIndices: + if (!GEP->hasAllConstantIndices()) + return V; + break; + case PSK_InBounds: + if (!GEP->isInBounds()) + return V; + break; + case PSK_All: + break; + } V = GEP->getPointerOperand(); } else if (Operator::getOpcode(V) == Instruction::BitCast) { V = cast(V)->getOperand(0); @@ -346,6 +369,19 @@ Value *Value::stripPointerCasts() { return V; } +} // namespace + +Value *Value::stripPointerCasts() { + return stripPointerCastsAndOffsets(this); +} + +Value *Value::stripConstantOffsets() { + return stripPointerCastsAndOffsets(this); +} + +Value *Value::stripInBoundsOffsets() { + return stripPointerCastsAndOffsets(this); +} /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store.