Hi Dan,<div><br></div><div>Great to see this patch back in. Could you also add a testcase for the infinite loop?</div><div><br></div><div>Nick</div><div><br><div class="gmail_quote">2009/7/13 Dan Gohman <span dir="ltr"><<a href="mailto:gohman@apple.com">gohman@apple.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Author: djg<br>
Date: Mon Jul 13 16:35:55 2009<br>
New Revision: 75511<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=75511&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=75511&view=rev</a><br>
Log:<br>
Reapply 75252, with a fix to avoid the infinite recursion case. The<br>
check for avoiding re-analyzing a widening cast needed to happen<br>
earlier, as getSCEV itself may result in a isLoopGuardedByCond query.<br>
<br>
Modified:<br>
llvm/trunk/include/llvm/Analysis/ScalarEvolution.h<br>
llvm/trunk/lib/Analysis/ScalarEvolution.cpp<br>
llvm/trunk/test/Transforms/IndVarSimplify/iv-sext.ll<br>
<br>
Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=75511&r1=75510&r2=75511&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=75511&r1=75510&r2=75511&view=diff</a><br>
<br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)<br>
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Mon Jul 13 16:35:55 2009<br>
@@ -26,6 +26,7 @@<br>
#include "llvm/Support/DataTypes.h"<br>
#include "llvm/Support/ValueHandle.h"<br>
#include "llvm/Support/Allocator.h"<br>
+#include "llvm/Support/ConstantRange.h"<br>
#include "llvm/ADT/FoldingSet.h"<br>
#include "llvm/ADT/DenseMap.h"<br>
#include <iosfwd><br>
@@ -330,12 +331,20 @@<br>
/// found.<br>
BasicBlock* getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);<br>
<br>
- /// isNecessaryCond - Test whether the given CondValue value is a condition<br>
- /// which is at least as strict as the one described by Pred, LHS, and RHS.<br>
+ /// isNecessaryCond - Test whether the condition described by Pred, LHS,<br>
+ /// and RHS is a necessary condition for the given Cond value to evaluate<br>
+ /// to true.<br>
bool isNecessaryCond(Value *Cond, ICmpInst::Predicate Pred,<br>
const SCEV *LHS, const SCEV *RHS,<br>
bool Inverse);<br>
<br>
+ /// isNecessaryCondOperands - Test whether the condition described by Pred,<br>
+ /// LHS, and RHS is a necessary condition for the condition described by<br>
+ /// Pred, FoundLHS, and FoundRHS to evaluate to true.<br>
+ bool isNecessaryCondOperands(ICmpInst::Predicate Pred,<br>
+ const SCEV *LHS, const SCEV *RHS,<br>
+ const SCEV *FoundLHS, const SCEV *FoundRHS);<br>
+<br>
/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is<br>
/// in the header of its containing loop, we know the loop executes a<br>
/// constant number of times, and the PHI node is just a recurrence<br>
@@ -495,10 +504,16 @@<br>
<br>
/// isLoopGuardedByCond - Test whether entry to the loop is protected by<br>
/// a conditional between LHS and RHS. This is used to help avoid max<br>
- /// expressions in loop trip counts.<br>
+ /// expressions in loop trip counts, and to eliminate casts.<br>
bool isLoopGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,<br>
const SCEV *LHS, const SCEV *RHS);<br>
<br>
+ /// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is<br>
+ /// protected by a conditional between LHS and RHS. This is used to<br>
+ /// to eliminate casts.<br>
+ bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,<br>
+ const SCEV *LHS, const SCEV *RHS);<br>
+<br>
/// getBackedgeTakenCount - If the specified loop has a predictable<br>
/// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute<br>
/// object. The backedge-taken count is the number of times the loop header<br>
@@ -534,13 +549,42 @@<br>
/// bitwidth of S.<br>
uint32_t GetMinTrailingZeros(const SCEV *S);<br>
<br>
- /// GetMinLeadingZeros - Determine the minimum number of zero bits that S is<br>
- /// guaranteed to begin with (at every loop iteration).<br>
- uint32_t GetMinLeadingZeros(const SCEV *S);<br>
-<br>
- /// GetMinSignBits - Determine the minimum number of sign bits that S is<br>
- /// guaranteed to begin with.<br>
- uint32_t GetMinSignBits(const SCEV *S);<br>
+ /// getUnsignedRange - Determine the unsigned range for a particular SCEV.<br>
+ ///<br>
+ ConstantRange getUnsignedRange(const SCEV *S);<br>
+<br>
+ /// getSignedRange - Determine the signed range for a particular SCEV.<br>
+ ///<br>
+ ConstantRange getSignedRange(const SCEV *S);<br>
+<br>
+ /// isKnownNegative - Test if the given expression is known to be negative.<br>
+ ///<br>
+ bool isKnownNegative(const SCEV *S);<br>
+<br>
+ /// isKnownPositive - Test if the given expression is known to be positive.<br>
+ ///<br>
+ bool isKnownPositive(const SCEV *S);<br>
+<br>
+ /// isKnownNonNegative - Test if the given expression is known to be<br>
+ /// non-negative.<br>
+ ///<br>
+ bool isKnownNonNegative(const SCEV *S);<br>
+<br>
+ /// isKnownNonPositive - Test if the given expression is known to be<br>
+ /// non-positive.<br>
+ ///<br>
+ bool isKnownNonPositive(const SCEV *S);<br>
+<br>
+ /// isKnownNonZero - Test if the given expression is known to be<br>
+ /// non-zero.<br>
+ ///<br>
+ bool isKnownNonZero(const SCEV *S);<br>
+<br>
+ /// isKnownNonZero - Test if the given expression is known to satisfy<br>
+ /// the condition described by Pred, LHS, and RHS.<br>
+ ///<br>
+ bool isKnownPredicate(ICmpInst::Predicate Pred,<br>
+ const SCEV *LHS, const SCEV *RHS);<br>
<br>
virtual bool runOnFunction(Function &F);<br>
virtual void releaseMemory();<br>
<br>
Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=75511&r1=75510&r2=75511&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=75511&r1=75510&r2=75511&view=diff</a><br>
<br>
==============================================================================<br>
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)<br>
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Jul 13 16:35:55 2009<br>
@@ -787,6 +787,11 @@<br>
// this: for (unsigned char X = 0; X < 100; ++X) { int Y = X; }<br>
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Op))<br>
if (AR->isAffine()) {<br>
+ const SCEV *Start = AR->getStart();<br>
+ const SCEV *Step = AR->getStepRecurrence(*this);<br>
+ unsigned BitWidth = getTypeSizeInBits(AR->getType());<br>
+ const Loop *L = AR->getLoop();<br>
+<br>
// Check whether the backedge-taken count is SCEVCouldNotCompute.<br>
// Note that this serves two purposes: It filters out loops that are<br>
// simply not analyzable, and it covers the case where this code is<br>
@@ -795,12 +800,10 @@<br>
// in infinite recursion. In the later case, the analysis code will<br>
// cope with a conservative value, and it will take care to purge<br>
// that value once it has finished.<br>
- const SCEV *MaxBECount = getMaxBackedgeTakenCount(AR->getLoop());<br>
+ const SCEV *MaxBECount = getMaxBackedgeTakenCount(L);<br>
if (!isa<SCEVCouldNotCompute>(MaxBECount)) {<br>
// Manually compute the final value for AR, checking for<br>
// overflow.<br>
- const SCEV *Start = AR->getStart();<br>
- const SCEV *Step = AR->getStepRecurrence(*this);<br>
<br>
// Check whether the backedge-taken count can be losslessly casted to<br>
// the addrec's type. The count is always unsigned.<br>
@@ -809,8 +812,7 @@<br>
const SCEV *RecastedMaxBECount =<br>
getTruncateOrZeroExtend(CastedMaxBECount, MaxBECount->getType());<br>
if (MaxBECount == RecastedMaxBECount) {<br>
- const Type *WideTy =<br>
- IntegerType::get(getTypeSizeInBits(Start->getType()) * 2);<br>
+ const Type *WideTy = IntegerType::get(BitWidth * 2);<br>
// Check whether Start+Step*MaxBECount has no unsigned overflow.<br>
const SCEV *ZMul =<br>
getMulExpr(CastedMaxBECount,<br>
@@ -824,7 +826,7 @@<br>
// Return the expression with the addrec on the outside.<br>
return getAddRecExpr(getZeroExtendExpr(Start, Ty),<br>
getZeroExtendExpr(Step, Ty),<br>
- AR->getLoop());<br>
+ L);<br>
<br>
// Similar to above, only this time treat the step value as signed.<br>
// This covers loops that count down.<br>
@@ -840,7 +842,35 @@<br>
// Return the expression with the addrec on the outside.<br>
return getAddRecExpr(getZeroExtendExpr(Start, Ty),<br>
getSignExtendExpr(Step, Ty),<br>
- AR->getLoop());<br>
+ L);<br>
+ }<br>
+<br>
+ // If the backedge is guarded by a comparison with the pre-inc value<br>
+ // the addrec is safe. Also, if the entry is guarded by a comparison<br>
+ // with the start value and the backedge is guarded by a comparison<br>
+ // with the post-inc value, the addrec is safe.<br>
+ if (isKnownPositive(Step)) {<br>
+ const SCEV *N = getConstant(APInt::getMinValue(BitWidth) -<br>
+ getUnsignedRange(Step).getUnsignedMax());<br>
+ if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT, AR, N) ||<br>
+ (isLoopGuardedByCond(L, ICmpInst::ICMP_ULT, Start, N) &&<br>
+ isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT,<br>
+ AR->getPostIncExpr(*this), N)))<br>
+ // Return the expression with the addrec on the outside.<br>
+ return getAddRecExpr(getZeroExtendExpr(Start, Ty),<br>
+ getZeroExtendExpr(Step, Ty),<br>
+ L);<br>
+ } else if (isKnownNegative(Step)) {<br>
+ const SCEV *N = getConstant(APInt::getMaxValue(BitWidth) -<br>
+ getSignedRange(Step).getSignedMin());<br>
+ if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT, AR, N) &&<br>
+ (isLoopGuardedByCond(L, ICmpInst::ICMP_UGT, Start, N) ||<br>
+ isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT,<br>
+ AR->getPostIncExpr(*this), N)))<br>
+ // Return the expression with the addrec on the outside.<br>
+ return getAddRecExpr(getZeroExtendExpr(Start, Ty),<br>
+ getSignExtendExpr(Step, Ty),<br>
+ L);<br>
}<br>
}<br>
}<br>
@@ -889,6 +919,11 @@<br>
// this: for (signed char X = 0; X < 100; ++X) { int Y = X; }<br>
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Op))<br>
if (AR->isAffine()) {<br>
+ const SCEV *Start = AR->getStart();<br>
+ const SCEV *Step = AR->getStepRecurrence(*this);<br>
+ unsigned BitWidth = getTypeSizeInBits(AR->getType());<br>
+ const Loop *L = AR->getLoop();<br>
+<br>
// Check whether the backedge-taken count is SCEVCouldNotCompute.<br>
// Note that this serves two purposes: It filters out loops that are<br>
// simply not analyzable, and it covers the case where this code is<br>
@@ -897,12 +932,10 @@<br>
// in infinite recursion. In the later case, the analysis code will<br>
// cope with a conservative value, and it will take care to purge<br>
// that value once it has finished.<br>
- const SCEV *MaxBECount = getMaxBackedgeTakenCount(AR->getLoop());<br>
+ const SCEV *MaxBECount = getMaxBackedgeTakenCount(L);<br>
if (!isa<SCEVCouldNotCompute>(MaxBECount)) {<br>
// Manually compute the final value for AR, checking for<br>
// overflow.<br>
- const SCEV *Start = AR->getStart();<br>
- const SCEV *Step = AR->getStepRecurrence(*this);<br>
<br>
// Check whether the backedge-taken count can be losslessly casted to<br>
// the addrec's type. The count is always unsigned.<br>
@@ -911,8 +944,7 @@<br>
const SCEV *RecastedMaxBECount =<br>
getTruncateOrZeroExtend(CastedMaxBECount, MaxBECount->getType());<br>
if (MaxBECount == RecastedMaxBECount) {<br>
- const Type *WideTy =<br>
- IntegerType::get(getTypeSizeInBits(Start->getType()) * 2);<br>
+ const Type *WideTy = IntegerType::get(BitWidth * 2);<br>
// Check whether Start+Step*MaxBECount has no signed overflow.<br>
const SCEV *SMul =<br>
getMulExpr(CastedMaxBECount,<br>
@@ -926,7 +958,35 @@<br>
// Return the expression with the addrec on the outside.<br>
return getAddRecExpr(getSignExtendExpr(Start, Ty),<br>
getSignExtendExpr(Step, Ty),<br>
- AR->getLoop());<br>
+ L);<br>
+ }<br>
+<br>
+ // If the backedge is guarded by a comparison with the pre-inc value<br>
+ // the addrec is safe. Also, if the entry is guarded by a comparison<br>
+ // with the start value and the backedge is guarded by a comparison<br>
+ // with the post-inc value, the addrec is safe.<br>
+ if (isKnownPositive(Step)) {<br>
+ const SCEV *N = getConstant(APInt::getSignedMinValue(BitWidth) -<br>
+ getSignedRange(Step).getSignedMax());<br>
+ if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SLT, AR, N) ||<br>
+ (isLoopGuardedByCond(L, ICmpInst::ICMP_SLT, Start, N) &&<br>
+ isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SLT,<br>
+ AR->getPostIncExpr(*this), N)))<br>
+ // Return the expression with the addrec on the outside.<br>
+ return getAddRecExpr(getSignExtendExpr(Start, Ty),<br>
+ getSignExtendExpr(Step, Ty),<br>
+ L);<br>
+ } else if (isKnownNegative(Step)) {<br>
+ const SCEV *N = getConstant(APInt::getSignedMaxValue(BitWidth) -<br>
+ getSignedRange(Step).getSignedMin());<br>
+ if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SGT, AR, N) ||<br>
+ (isLoopGuardedByCond(L, ICmpInst::ICMP_SGT, Start, N) &&<br>
+ isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SGT,<br>
+ AR->getPostIncExpr(*this), N)))<br>
+ // Return the expression with the addrec on the outside.<br>
+ return getAddRecExpr(getSignExtendExpr(Start, Ty),<br>
+ getSignExtendExpr(Step, Ty),<br>
+ L);<br>
}<br>
}<br>
}<br>
@@ -2368,19 +2428,16 @@<br>
const StructLayout &SL = *TD->getStructLayout(STy);<br>
unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();<br>
uint64_t Offset = SL.getElementOffset(FieldNo);<br>
- TotalOffset = getAddExpr(TotalOffset,<br>
- getIntegerSCEV(Offset, IntPtrTy));<br>
+ TotalOffset = getAddExpr(TotalOffset, getIntegerSCEV(Offset, IntPtrTy));<br>
} else {<br>
// For an array, add the element offset, explicitly scaled.<br>
const SCEV *LocalOffset = getSCEV(Index);<br>
if (!isa<PointerType>(LocalOffset->getType()))<br>
// Getelementptr indicies are signed.<br>
- LocalOffset = getTruncateOrSignExtend(LocalOffset,<br>
- IntPtrTy);<br>
+ LocalOffset = getTruncateOrSignExtend(LocalOffset, IntPtrTy);<br>
LocalOffset =<br>
getMulExpr(LocalOffset,<br>
- getIntegerSCEV(TD->getTypeAllocSize(*GTI),<br>
- IntPtrTy));<br>
+ getIntegerSCEV(TD->getTypeAllocSize(*GTI), IntPtrTy));<br>
TotalOffset = getAddExpr(TotalOffset, LocalOffset);<br>
}<br>
}<br>
@@ -2468,18 +2525,95 @@<br>
return 0;<br>
}<br>
<br>
-uint32_t<br>
-ScalarEvolution::GetMinLeadingZeros(const SCEV *S) {<br>
- // TODO: Handle other SCEV expression types here.<br>
+/// getUnsignedRange - Determine the unsigned range for a particular SCEV.<br>
+///<br>
+ConstantRange<br>
+ScalarEvolution::getUnsignedRange(const SCEV *S) {<br>
<br>
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S))<br>
- return C->getValue()->getValue().countLeadingZeros();<br>
+ return ConstantRange(C->getValue()->getValue());<br>
+<br>
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {<br>
+ ConstantRange X = getUnsignedRange(Add->getOperand(0));<br>
+ for (unsigned i = 1, e = Add->getNumOperands(); i != e; ++i)<br>
+ X = X.add(getUnsignedRange(Add->getOperand(i)));<br>
+ return X;<br>
+ }<br>
+<br>
+ if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {<br>
+ ConstantRange X = getUnsignedRange(Mul->getOperand(0));<br>
+ for (unsigned i = 1, e = Mul->getNumOperands(); i != e; ++i)<br>
+ X = X.multiply(getUnsignedRange(Mul->getOperand(i)));<br>
+ return X;<br>
+ }<br>
+<br>
+ if (const SCEVSMaxExpr *SMax = dyn_cast<SCEVSMaxExpr>(S)) {<br>
+ ConstantRange X = getUnsignedRange(SMax->getOperand(0));<br>
+ for (unsigned i = 1, e = SMax->getNumOperands(); i != e; ++i)<br>
+ X = X.smax(getUnsignedRange(SMax->getOperand(i)));<br>
+ return X;<br>
+ }<br>
+<br>
+ if (const SCEVUMaxExpr *UMax = dyn_cast<SCEVUMaxExpr>(S)) {<br>
+ ConstantRange X = getUnsignedRange(UMax->getOperand(0));<br>
+ for (unsigned i = 1, e = UMax->getNumOperands(); i != e; ++i)<br>
+ X = X.umax(getUnsignedRange(UMax->getOperand(i)));<br>
+ return X;<br>
+ }<br>
+<br>
+ if (const SCEVUDivExpr *UDiv = dyn_cast<SCEVUDivExpr>(S)) {<br>
+ ConstantRange X = getUnsignedRange(UDiv->getLHS());<br>
+ ConstantRange Y = getUnsignedRange(UDiv->getRHS());<br>
+ return X.udiv(Y);<br>
+ }<br>
+<br>
+ if (const SCEVZeroExtendExpr *ZExt = dyn_cast<SCEVZeroExtendExpr>(S)) {<br>
+ ConstantRange X = getUnsignedRange(ZExt->getOperand());<br>
+ return X.zeroExtend(cast<IntegerType>(ZExt->getType())->getBitWidth());<br>
+ }<br>
+<br>
+ if (const SCEVSignExtendExpr *SExt = dyn_cast<SCEVSignExtendExpr>(S)) {<br>
+ ConstantRange X = getUnsignedRange(SExt->getOperand());<br>
+ return X.signExtend(cast<IntegerType>(SExt->getType())->getBitWidth());<br>
+ }<br>
+<br>
+ if (const SCEVTruncateExpr *Trunc = dyn_cast<SCEVTruncateExpr>(S)) {<br>
+ ConstantRange X = getUnsignedRange(Trunc->getOperand());<br>
+ return X.truncate(cast<IntegerType>(Trunc->getType())->getBitWidth());<br>
+ }<br>
+<br>
+ ConstantRange FullSet(getTypeSizeInBits(S->getType()), true);<br>
<br>
- if (const SCEVZeroExtendExpr *C = dyn_cast<SCEVZeroExtendExpr>(S)) {<br>
- // A zero-extension cast adds zero bits.<br>
- return GetMinLeadingZeros(C->getOperand()) +<br>
- (getTypeSizeInBits(C->getType()) -<br>
- getTypeSizeInBits(C->getOperand()->getType()));<br>
+ if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {<br>
+ const SCEV *T = getBackedgeTakenCount(AddRec->getLoop());<br>
+ const SCEVConstant *Trip = dyn_cast<SCEVConstant>(T);<br>
+ if (!Trip) return FullSet;<br>
+<br>
+ // TODO: non-affine addrec<br>
+ if (AddRec->isAffine()) {<br>
+ const Type *Ty = AddRec->getType();<br>
+ const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop());<br>
+ if (getTypeSizeInBits(MaxBECount->getType()) <= getTypeSizeInBits(Ty)) {<br>
+ MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty);<br>
+<br>
+ const SCEV *Start = AddRec->getStart();<br>
+ const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this);<br>
+<br>
+ // Check for overflow.<br>
+ if (!isKnownPredicate(ICmpInst::ICMP_ULE, Start, End))<br>
+ return FullSet;<br>
+<br>
+ ConstantRange StartRange = getUnsignedRange(Start);<br>
+ ConstantRange EndRange = getUnsignedRange(End);<br>
+ APInt Min = APIntOps::umin(StartRange.getUnsignedMin(),<br>
+ EndRange.getUnsignedMin());<br>
+ APInt Max = APIntOps::umax(StartRange.getUnsignedMax(),<br>
+ EndRange.getUnsignedMax());<br>
+ if (Min.isMinValue() && Max.isMaxValue())<br>
+ return ConstantRange(Min.getBitWidth(), /*isFullSet=*/true);<br>
+ return ConstantRange(Min, Max+1);<br>
+ }<br>
+ }<br>
}<br>
<br>
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {<br>
@@ -2488,67 +2622,119 @@<br>
APInt Mask = APInt::getAllOnesValue(BitWidth);<br>
APInt Zeros(BitWidth, 0), Ones(BitWidth, 0);<br>
ComputeMaskedBits(U->getValue(), Mask, Zeros, Ones, TD);<br>
- return Zeros.countLeadingOnes();<br>
+ return ConstantRange(Ones, ~Zeros);<br>
}<br>
<br>
- return 1;<br>
+ return FullSet;<br>
}<br>
<br>
-uint32_t<br>
-ScalarEvolution::GetMinSignBits(const SCEV *S) {<br>
- // TODO: Handle other SCEV expression types here.<br>
+/// getSignedRange - Determine the signed range for a particular SCEV.<br>
+///<br>
+ConstantRange<br>
+ScalarEvolution::getSignedRange(const SCEV *S) {<br>
+<br>
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S))<br>
+ return ConstantRange(C->getValue()->getValue());<br>
<br>
- if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S)) {<br>
- const APInt &A = C->getValue()->getValue();<br>
- return A.isNegative() ? A.countLeadingOnes() :<br>
- A.countLeadingZeros();<br>
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {<br>
+ ConstantRange X = getSignedRange(Add->getOperand(0));<br>
+ for (unsigned i = 1, e = Add->getNumOperands(); i != e; ++i)<br>
+ X = X.add(getSignedRange(Add->getOperand(i)));<br>
+ return X;<br>
}<br>
<br>
- if (const SCEVSignExtendExpr *C = dyn_cast<SCEVSignExtendExpr>(S)) {<br>
- // A sign-extension cast adds sign bits.<br>
- return GetMinSignBits(C->getOperand()) +<br>
- (getTypeSizeInBits(C->getType()) -<br>
- getTypeSizeInBits(C->getOperand()->getType()));<br>
+ if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {<br>
+ ConstantRange X = getSignedRange(Mul->getOperand(0));<br>
+ for (unsigned i = 1, e = Mul->getNumOperands(); i != e; ++i)<br>
+ X = X.multiply(getSignedRange(Mul->getOperand(i)));<br>
+ return X;<br>
}<br>
<br>
- if (const SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(S)) {<br>
- unsigned BitWidth = getTypeSizeInBits(A->getType());<br>
+ if (const SCEVSMaxExpr *SMax = dyn_cast<SCEVSMaxExpr>(S)) {<br>
+ ConstantRange X = getSignedRange(SMax->getOperand(0));<br>
+ for (unsigned i = 1, e = SMax->getNumOperands(); i != e; ++i)<br>
+ X = X.smax(getSignedRange(SMax->getOperand(i)));<br>
+ return X;<br>
+ }<br>
<br>
- // Special case decrementing a value (ADD X, -1):<br>
- if (const SCEVConstant *CRHS = dyn_cast<SCEVConstant>(A->getOperand(0)))<br>
- if (CRHS->isAllOnesValue()) {<br>
- SmallVector<const SCEV *, 4> OtherOps(A->op_begin() + 1, A->op_end());<br>
- const SCEV *OtherOpsAdd = getAddExpr(OtherOps);<br>
- unsigned LZ = GetMinLeadingZeros(OtherOpsAdd);<br>
-<br>
- // If the input is known to be 0 or 1, the output is 0/-1, which is all<br>
- // sign bits set.<br>
- if (LZ == BitWidth - 1)<br>
- return BitWidth;<br>
-<br>
- // If we are subtracting one from a positive number, there is no carry<br>
- // out of the result.<br>
- if (LZ > 0)<br>
- return GetMinSignBits(OtherOpsAdd);<br>
- }<br>
-<br>
- // Add can have at most one carry bit. Thus we know that the output<br>
- // is, at worst, one more bit than the inputs.<br>
- unsigned Min = BitWidth;<br>
- for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) {<br>
- unsigned N = GetMinSignBits(A->getOperand(i));<br>
- Min = std::min(Min, N) - 1;<br>
- if (Min == 0) return 1;<br>
+ if (const SCEVUMaxExpr *UMax = dyn_cast<SCEVUMaxExpr>(S)) {<br>
+ ConstantRange X = getSignedRange(UMax->getOperand(0));<br>
+ for (unsigned i = 1, e = UMax->getNumOperands(); i != e; ++i)<br>
+ X = X.umax(getSignedRange(UMax->getOperand(i)));<br>
+ return X;<br>
+ }<br>
+<br>
+ if (const SCEVUDivExpr *UDiv = dyn_cast<SCEVUDivExpr>(S)) {<br>
+ ConstantRange X = getSignedRange(UDiv->getLHS());<br>
+ ConstantRange Y = getSignedRange(UDiv->getRHS());<br>
+ return X.udiv(Y);<br>
+ }<br>
+<br>
+ if (const SCEVZeroExtendExpr *ZExt = dyn_cast<SCEVZeroExtendExpr>(S)) {<br>
+ ConstantRange X = getSignedRange(ZExt->getOperand());<br>
+ return X.zeroExtend(cast<IntegerType>(ZExt->getType())->getBitWidth());<br>
+ }<br>
+<br>
+ if (const SCEVSignExtendExpr *SExt = dyn_cast<SCEVSignExtendExpr>(S)) {<br>
+ ConstantRange X = getSignedRange(SExt->getOperand());<br>
+ return X.signExtend(cast<IntegerType>(SExt->getType())->getBitWidth());<br>
+ }<br>
+<br>
+ if (const SCEVTruncateExpr *Trunc = dyn_cast<SCEVTruncateExpr>(S)) {<br>
+ ConstantRange X = getSignedRange(Trunc->getOperand());<br>
+ return X.truncate(cast<IntegerType>(Trunc->getType())->getBitWidth());<br>
+ }<br>
+<br>
+ ConstantRange FullSet(getTypeSizeInBits(S->getType()), true);<br>
+<br>
+ if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {<br>
+ const SCEV *T = getBackedgeTakenCount(AddRec->getLoop());<br>
+ const SCEVConstant *Trip = dyn_cast<SCEVConstant>(T);<br>
+ if (!Trip) return FullSet;<br>
+<br>
+ // TODO: non-affine addrec<br>
+ if (AddRec->isAffine()) {<br>
+ const Type *Ty = AddRec->getType();<br>
+ const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop());<br>
+ if (getTypeSizeInBits(MaxBECount->getType()) <= getTypeSizeInBits(Ty)) {<br>
+ MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty);<br>
+<br>
+ const SCEV *Start = AddRec->getStart();<br>
+ const SCEV *Step = AddRec->getStepRecurrence(*this);<br>
+ const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this);<br>
+<br>
+ // Check for overflow.<br>
+ if (!(isKnownPositive(Step) &&<br>
+ isKnownPredicate(ICmpInst::ICMP_SLT, Start, End)) &&<br>
+ !(isKnownNegative(Step) &&<br>
+ isKnownPredicate(ICmpInst::ICMP_SGT, Start, End)))<br>
+ return FullSet;<br>
+<br>
+ ConstantRange StartRange = getSignedRange(Start);<br>
+ ConstantRange EndRange = getSignedRange(End);<br>
+ APInt Min = APIntOps::smin(StartRange.getSignedMin(),<br>
+ EndRange.getSignedMin());<br>
+ APInt Max = APIntOps::smax(StartRange.getSignedMax(),<br>
+ EndRange.getSignedMax());<br>
+ if (Min.isMinSignedValue() && Max.isMaxSignedValue())<br>
+ return ConstantRange(Min.getBitWidth(), /*isFullSet=*/true);<br>
+ return ConstantRange(Min, Max+1);<br>
+ }<br>
}<br>
- return 1;<br>
}<br>
<br>
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {<br>
// For a SCEVUnknown, ask ValueTracking.<br>
- return ComputeNumSignBits(U->getValue(), TD);<br>
+ unsigned BitWidth = getTypeSizeInBits(U->getType());<br>
+ unsigned NS = ComputeNumSignBits(U->getValue(), TD);<br>
+ if (NS == 1)<br>
+ return FullSet;<br>
+ return<br>
+ ConstantRange(APInt::getSignedMinValue(BitWidth).ashr(NS - 1),<br>
+ APInt::getSignedMaxValue(BitWidth).ashr(NS - 1)+1);<br>
}<br>
<br>
- return 1;<br>
+ return FullSet;<br>
}<br>
<br>
/// createSCEV - We know that there is no SCEV for the specified value.<br>
@@ -3628,7 +3814,7 @@<br>
if (!isSCEVable(Op->getType()))<br>
return V;<br>
<br>
- const SCEV *OpV = getSCEVAtScope(getSCEV(Op), L);<br>
+ const SCEV* OpV = getSCEVAtScope(Op, L);<br>
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(OpV)) {<br>
Constant *C = SC->getValue();<br>
if (C->getType() != Op->getType())<br>
@@ -4029,12 +4215,176 @@<br>
return false;<br>
}<br>
<br>
-/// isLoopGuardedByCond - Test whether entry to the loop is protected by<br>
-/// a conditional between LHS and RHS. This is used to help avoid max<br>
-/// expressions in loop trip counts.<br>
-bool ScalarEvolution::isLoopGuardedByCond(const Loop *L,<br>
- ICmpInst::Predicate Pred,<br>
- const SCEV *LHS, const SCEV *RHS) {<br>
+bool ScalarEvolution::isKnownNegative(const SCEV *S) {<br>
+ return getSignedRange(S).getSignedMax().isNegative();<br>
+}<br>
+<br>
+bool ScalarEvolution::isKnownPositive(const SCEV *S) {<br>
+ return getSignedRange(S).getSignedMin().isStrictlyPositive();<br>
+}<br>
+<br>
+bool ScalarEvolution::isKnownNonNegative(const SCEV *S) {<br>
+ return !getSignedRange(S).getSignedMin().isNegative();<br>
+}<br>
+<br>
+bool ScalarEvolution::isKnownNonPositive(const SCEV *S) {<br>
+ return !getSignedRange(S).getSignedMax().isStrictlyPositive();<br>
+}<br>
+<br>
+bool ScalarEvolution::isKnownNonZero(const SCEV *S) {<br>
+ return isKnownNegative(S) || isKnownPositive(S);<br>
+}<br>
+<br>
+bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,<br>
+ const SCEV *LHS, const SCEV *RHS) {<br>
+<br>
+ if (HasSameValue(LHS, RHS))<br>
+ return ICmpInst::isTrueWhenEqual(Pred);<br>
+<br>
+ switch (Pred) {<br>
+ default:<br>
+ assert(0 && "Unexpected ICmpInst::Predicate value!");<br>
+ break;<br>
+ case ICmpInst::ICMP_SGT:<br>
+ Pred = ICmpInst::ICMP_SLT;<br>
+ std::swap(LHS, RHS);<br>
+ case ICmpInst::ICMP_SLT: {<br>
+ ConstantRange LHSRange = getSignedRange(LHS);<br>
+ ConstantRange RHSRange = getSignedRange(RHS);<br>
+ if (LHSRange.getSignedMax().slt(RHSRange.getSignedMin()))<br>
+ return true;<br>
+ if (LHSRange.getSignedMin().sge(RHSRange.getSignedMax()))<br>
+ return false;<br>
+<br>
+ const SCEV *Diff = getMinusSCEV(LHS, RHS);<br>
+ ConstantRange DiffRange = getUnsignedRange(Diff);<br>
+ if (isKnownNegative(Diff)) {<br>
+ if (DiffRange.getUnsignedMax().ult(LHSRange.getUnsignedMin()))<br>
+ return true;<br>
+ if (DiffRange.getUnsignedMin().uge(LHSRange.getUnsignedMax()))<br>
+ return false;<br>
+ } else if (isKnownPositive(Diff)) {<br>
+ if (LHSRange.getUnsignedMax().ult(DiffRange.getUnsignedMin()))<br>
+ return true;<br>
+ if (LHSRange.getUnsignedMin().uge(DiffRange.getUnsignedMax()))<br>
+ return false;<br>
+ }<br>
+ break;<br>
+ }<br>
+ case ICmpInst::ICMP_SGE:<br>
+ Pred = ICmpInst::ICMP_SLE;<br>
+ std::swap(LHS, RHS);<br>
+ case ICmpInst::ICMP_SLE: {<br>
+ ConstantRange LHSRange = getSignedRange(LHS);<br>
+ ConstantRange RHSRange = getSignedRange(RHS);<br>
+ if (LHSRange.getSignedMax().sle(RHSRange.getSignedMin()))<br>
+ return true;<br>
+ if (LHSRange.getSignedMin().sgt(RHSRange.getSignedMax()))<br>
+ return false;<br>
+<br>
+ const SCEV *Diff = getMinusSCEV(LHS, RHS);<br>
+ ConstantRange DiffRange = getUnsignedRange(Diff);<br>
+ if (isKnownNonPositive(Diff)) {<br>
+ if (DiffRange.getUnsignedMax().ule(LHSRange.getUnsignedMin()))<br>
+ return true;<br>
+ if (DiffRange.getUnsignedMin().ugt(LHSRange.getUnsignedMax()))<br>
+ return false;<br>
+ } else if (isKnownNonNegative(Diff)) {<br>
+ if (LHSRange.getUnsignedMax().ule(DiffRange.getUnsignedMin()))<br>
+ return true;<br>
+ if (LHSRange.getUnsignedMin().ugt(DiffRange.getUnsignedMax()))<br>
+ return false;<br>
+ }<br>
+ break;<br>
+ }<br>
+ case ICmpInst::ICMP_UGT:<br>
+ Pred = ICmpInst::ICMP_ULT;<br>
+ std::swap(LHS, RHS);<br>
+ case ICmpInst::ICMP_ULT: {<br>
+ ConstantRange LHSRange = getUnsignedRange(LHS);<br>
+ ConstantRange RHSRange = getUnsignedRange(RHS);<br>
+ if (LHSRange.getUnsignedMax().ult(RHSRange.getUnsignedMin()))<br>
+ return true;<br>
+ if (LHSRange.getUnsignedMin().uge(RHSRange.getUnsignedMax()))<br>
+ return false;<br>
+<br>
+ const SCEV *Diff = getMinusSCEV(LHS, RHS);<br>
+ ConstantRange DiffRange = getUnsignedRange(Diff);<br>
+ if (LHSRange.getUnsignedMax().ult(DiffRange.getUnsignedMin()))<br>
+ return true;<br>
+ if (LHSRange.getUnsignedMin().uge(DiffRange.getUnsignedMax()))<br>
+ return false;<br>
+ break;<br>
+ }<br>
+ case ICmpInst::ICMP_UGE:<br>
+ Pred = ICmpInst::ICMP_ULE;<br>
+ std::swap(LHS, RHS);<br>
+ case ICmpInst::ICMP_ULE: {<br>
+ ConstantRange LHSRange = getUnsignedRange(LHS);<br>
+ ConstantRange RHSRange = getUnsignedRange(RHS);<br>
+ if (LHSRange.getUnsignedMax().ule(RHSRange.getUnsignedMin()))<br>
+ return true;<br>
+ if (LHSRange.getUnsignedMin().ugt(RHSRange.getUnsignedMax()))<br>
+ return false;<br>
+<br>
+ const SCEV *Diff = getMinusSCEV(LHS, RHS);<br>
+ ConstantRange DiffRange = getUnsignedRange(Diff);<br>
+ if (LHSRange.getUnsignedMax().ule(DiffRange.getUnsignedMin()))<br>
+ return true;<br>
+ if (LHSRange.getUnsignedMin().ugt(DiffRange.getUnsignedMax()))<br>
+ return false;<br>
+ break;<br>
+ }<br>
+ case ICmpInst::ICMP_NE: {<br>
+ if (getUnsignedRange(LHS).intersectWith(getUnsignedRange(RHS)).isEmptySet())<br>
+ return true;<br>
+ if (getSignedRange(LHS).intersectWith(getSignedRange(RHS)).isEmptySet())<br>
+ return true;<br>
+<br>
+ const SCEV *Diff = getMinusSCEV(LHS, RHS);<br>
+ if (isKnownNonZero(Diff))<br>
+ return true;<br>
+ break;<br>
+ }<br>
+ case ICmpInst::ICMP_EQ:<br>
+ break;<br>
+ }<br>
+ return false;<br>
+}<br>
+<br>
+/// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is<br>
+/// protected by a conditional between LHS and RHS. This is used to<br>
+/// to eliminate casts.<br>
+bool<br>
+ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,<br>
+ ICmpInst::Predicate Pred,<br>
+ const SCEV *LHS, const SCEV *RHS) {<br>
+ // Interpret a null as meaning no loop, where there is obviously no guard<br>
+ // (interprocedural conditions notwithstanding).<br>
+ if (!L) return true;<br>
+<br>
+ BasicBlock *Latch = L->getLoopLatch();<br>
+ if (!Latch)<br>
+ return false;<br>
+<br>
+ BranchInst *LoopContinuePredicate =<br>
+ dyn_cast<BranchInst>(Latch->getTerminator());<br>
+ if (!LoopContinuePredicate ||<br>
+ LoopContinuePredicate->isUnconditional())<br>
+ return false;<br>
+<br>
+ return<br>
+ isNecessaryCond(LoopContinuePredicate->getCondition(), Pred, LHS, RHS,<br>
+ LoopContinuePredicate->getSuccessor(0) != L->getHeader());<br>
+}<br>
+<br>
+/// isLoopGuardedByCond - Test whether entry to the loop is protected<br>
+/// by a conditional between LHS and RHS. This is used to help avoid max<br>
+/// expressions in loop trip counts, and to eliminate casts.<br>
+bool<br>
+ScalarEvolution::isLoopGuardedByCond(const Loop *L,<br>
+ ICmpInst::Predicate Pred,<br>
+ const SCEV *LHS, const SCEV *RHS) {<br>
// Interpret a null as meaning no loop, where there is obviously no guard<br>
// (interprocedural conditions notwithstanding).<br>
if (!L) return false;<br>
@@ -4063,8 +4413,9 @@<br>
return false;<br>
}<br>
<br>
-/// isNecessaryCond - Test whether the given CondValue value is a condition<br>
-/// which is at least as strict as the one described by Pred, LHS, and RHS.<br>
+/// isNecessaryCond - Test whether the condition described by Pred, LHS,<br>
+/// and RHS is a necessary condition for the given Cond value to evaluate<br>
+/// to true.<br>
bool ScalarEvolution::isNecessaryCond(Value *CondValue,<br>
ICmpInst::Predicate Pred,<br>
const SCEV *LHS, const SCEV *RHS,<br>
@@ -4089,30 +4440,35 @@<br>
// see if it is the comparison we are looking for.<br>
Value *PreCondLHS = ICI->getOperand(0);<br>
Value *PreCondRHS = ICI->getOperand(1);<br>
- ICmpInst::Predicate Cond;<br>
+ ICmpInst::Predicate FoundPred;<br>
if (Inverse)<br>
- Cond = ICI->getInversePredicate();<br>
+ FoundPred = ICI->getInversePredicate();<br>
else<br>
- Cond = ICI->getPredicate();<br>
+ FoundPred = ICI->getPredicate();<br>
<br>
- if (Cond == Pred)<br>
+ if (FoundPred == Pred)<br>
; // An exact match.<br>
- else if (!ICmpInst::isTrueWhenEqual(Cond) && Pred == ICmpInst::ICMP_NE)<br>
- ; // The actual condition is beyond sufficient.<br>
- else<br>
+ else if (!ICmpInst::isTrueWhenEqual(FoundPred) && Pred == ICmpInst::ICMP_NE) {<br>
+ // The actual condition is beyond sufficient.<br>
+ FoundPred = ICmpInst::ICMP_NE;<br>
+ // NE is symmetric but the original comparison may not be. Swap<br>
+ // the operands if necessary so that they match below.<br>
+ if (isa<SCEVConstant>(LHS))<br>
+ std::swap(PreCondLHS, PreCondRHS);<br>
+ } else<br>
// Check a few special cases.<br>
- switch (Cond) {<br>
+ switch (FoundPred) {<br>
case ICmpInst::ICMP_UGT:<br>
if (Pred == ICmpInst::ICMP_ULT) {<br>
std::swap(PreCondLHS, PreCondRHS);<br>
- Cond = ICmpInst::ICMP_ULT;<br>
+ FoundPred = ICmpInst::ICMP_ULT;<br>
break;<br>
}<br>
return false;<br>
case ICmpInst::ICMP_SGT:<br>
if (Pred == ICmpInst::ICMP_SLT) {<br>
std::swap(PreCondLHS, PreCondRHS);<br>
- Cond = ICmpInst::ICMP_SLT;<br>
+ FoundPred = ICmpInst::ICMP_SLT;<br>
break;<br>
}<br>
return false;<br>
@@ -4121,8 +4477,8 @@<br>
// so check for this case by checking if the NE is comparing against<br>
// a minimum or maximum constant.<br>
if (!ICmpInst::isTrueWhenEqual(Pred))<br>
- if (ConstantInt *CI = dyn_cast<ConstantInt>(PreCondRHS)) {<br>
- const APInt &A = CI->getValue();<br>
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(RHS)) {<br>
+ const APInt &A = C->getValue()->getValue();<br>
switch (Pred) {<br>
case ICmpInst::ICMP_SLT:<br>
if (A.isMaxSignedValue()) break;<br>
@@ -4139,7 +4495,7 @@<br>
default:<br>
return false;<br>
}<br>
- Cond = ICmpInst::ICMP_NE;<br>
+ FoundPred = Pred;<br>
// NE is symmetric but the original comparison may not be. Swap<br>
// the operands if necessary so that they match below.<br>
if (isa<SCEVConstant>(LHS))<br>
@@ -4152,14 +4508,73 @@<br>
return false;<br>
}<br>
<br>
- if (!PreCondLHS->getType()->isInteger()) return false;<br>
+ assert(Pred == FoundPred && "Conditions were not reconciled!");<br>
+<br>
+ // Bail if the ICmp's operands' types are wider than the needed type<br>
+ // before attempting to call getSCEV on them. This avoids infinite<br>
+ // recursion, since the analysis of widening casts can require loop<br>
+ // exit condition information for overflow checking, which would<br>
+ // lead back here.<br>
+ if (getTypeSizeInBits(LHS->getType()) <<br>
+ getTypeSizeInBits(PreCondLHS->getType()))<br>
+ return false;<br>
+<br>
+ const SCEV *FoundLHS = getSCEV(PreCondLHS);<br>
+ const SCEV *FoundRHS = getSCEV(PreCondRHS);<br>
+<br>
+ // Balance the types. The case where FoundLHS' type is wider than<br>
+ // LHS' type is checked for above.<br>
+ if (getTypeSizeInBits(LHS->getType()) ><br>
+ getTypeSizeInBits(FoundLHS->getType())) {<br>
+ if (CmpInst::isSigned(Pred)) {<br>
+ FoundLHS = getSignExtendExpr(FoundLHS, LHS->getType());<br>
+ FoundRHS = getSignExtendExpr(FoundRHS, LHS->getType());<br>
+ } else {<br>
+ FoundLHS = getZeroExtendExpr(FoundLHS, LHS->getType());<br>
+ FoundRHS = getZeroExtendExpr(FoundRHS, LHS->getType());<br>
+ }<br>
+ }<br>
+<br>
+ return isNecessaryCondOperands(Pred, LHS, RHS,<br>
+ FoundLHS, FoundRHS) ||<br>
+ // ~x < ~y --> x > y<br>
+ isNecessaryCondOperands(Pred, LHS, RHS,<br>
+ getNotSCEV(FoundRHS), getNotSCEV(FoundLHS));<br>
+}<br>
+<br>
+/// isNecessaryCondOperands - Test whether the condition described by Pred,<br>
+/// LHS, and RHS is a necessary condition for the condition described by<br>
+/// Pred, FoundLHS, and FoundRHS to evaluate to true.<br>
+bool<br>
+ScalarEvolution::isNecessaryCondOperands(ICmpInst::Predicate Pred,<br>
+ const SCEV *LHS, const SCEV *RHS,<br>
+ const SCEV *FoundLHS,<br>
+ const SCEV *FoundRHS) {<br>
+ switch (Pred) {<br>
+ default: break;<br>
+ case ICmpInst::ICMP_SLT:<br>
+ if (isKnownPredicate(ICmpInst::ICMP_SLE, LHS, FoundLHS) &&<br>
+ isKnownPredicate(ICmpInst::ICMP_SGE, RHS, FoundRHS))<br>
+ return true;<br>
+ break;<br>
+ case ICmpInst::ICMP_SGT:<br>
+ if (isKnownPredicate(ICmpInst::ICMP_SGE, LHS, FoundLHS) &&<br>
+ isKnownPredicate(ICmpInst::ICMP_SLE, RHS, FoundRHS))<br>
+ return true;<br>
+ break;<br>
+ case ICmpInst::ICMP_ULT:<br>
+ if (isKnownPredicate(ICmpInst::ICMP_ULE, LHS, FoundLHS) &&<br>
+ isKnownPredicate(ICmpInst::ICMP_UGE, RHS, FoundRHS))<br>
+ return true;<br>
+ break;<br>
+ case ICmpInst::ICMP_UGT:<br>
+ if (isKnownPredicate(ICmpInst::ICMP_UGE, LHS, FoundLHS) &&<br>
+ isKnownPredicate(ICmpInst::ICMP_ULE, RHS, FoundRHS))<br>
+ return true;<br>
+ break;<br>
+ }<br>
<br>
- const SCEV *PreCondLHSSCEV = getSCEV(PreCondLHS);<br>
- const SCEV *PreCondRHSSCEV = getSCEV(PreCondRHS);<br>
- return (HasSameValue(LHS, PreCondLHSSCEV) &&<br>
- HasSameValue(RHS, PreCondRHSSCEV)) ||<br>
- (HasSameValue(LHS, getNotSCEV(PreCondRHSSCEV)) &&<br>
- HasSameValue(RHS, getNotSCEV(PreCondLHSSCEV)));<br>
+ return false;<br>
}<br>
<br>
/// getBECount - Subtract the end and start values and divide by the step,<br>
@@ -4180,9 +4595,9 @@<br>
// Check Add for unsigned overflow.<br>
// TODO: More sophisticated things could be done here.<br>
const Type *WideTy = Context->getIntegerType(getTypeSizeInBits(Ty) + 1);<br>
- const SCEV *OperandExtendedAdd =<br>
- getAddExpr(getZeroExtendExpr(Diff, WideTy),<br>
- getZeroExtendExpr(RoundUp, WideTy));<br>
+ const SCEV *EDiff = getZeroExtendExpr(Diff, WideTy);<br>
+ const SCEV *ERoundUp = getZeroExtendExpr(RoundUp, WideTy);<br>
+ const SCEV *OperandExtendedAdd = getAddExpr(EDiff, ERoundUp);<br>
if (getZeroExtendExpr(Add, WideTy) != OperandExtendedAdd)<br>
return getCouldNotCompute();<br>
<br>
@@ -4244,9 +4659,9 @@<br>
const SCEV *Start = AddRec->getOperand(0);<br>
<br>
// Determine the minimum constant start value.<br>
- const SCEV *MinStart = isa<SCEVConstant>(Start) ? Start :<br>
- getConstant(isSigned ? APInt::getSignedMinValue(BitWidth) :<br>
- APInt::getMinValue(BitWidth));<br>
+ const SCEV *MinStart = getConstant(isSigned ?<br>
+ getSignedRange(Start).getSignedMin() :<br>
+ getUnsignedRange(Start).getUnsignedMin());<br>
<br>
// If we know that the condition is true in order to enter the loop,<br>
// then we know that it will run exactly (m-n)/s times. Otherwise, we<br>
@@ -4254,18 +4669,16 @@<br>
// the division must round up.<br>
const SCEV *End = RHS;<br>
if (!isLoopGuardedByCond(L,<br>
- isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,<br>
+ isSigned ? ICmpInst::ICMP_SLT :<br>
+ ICmpInst::ICMP_ULT,<br>
getMinusSCEV(Start, Step), RHS))<br>
End = isSigned ? getSMaxExpr(RHS, Start)<br>
: getUMaxExpr(RHS, Start);<br>
<br>
// Determine the maximum constant end value.<br>
- const SCEV *MaxEnd =<br>
- isa<SCEVConstant>(End) ? End :<br>
- getConstant(isSigned ? APInt::getSignedMaxValue(BitWidth)<br>
- .ashr(GetMinSignBits(End) - 1) :<br>
- APInt::getMaxValue(BitWidth)<br>
- .lshr(GetMinLeadingZeros(End)));<br>
+ const SCEV *MaxEnd = getConstant(isSigned ?<br>
+ getSignedRange(End).getSignedMax() :<br>
+ getUnsignedRange(End).getUnsignedMax());<br>
<br>
// Finally, we subtract these two values and divide, rounding up, to get<br>
// the number of times the backedge is executed.<br>
<br>
Modified: llvm/trunk/test/Transforms/IndVarSimplify/iv-sext.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/iv-sext.ll?rev=75511&r1=75510&r2=75511&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/iv-sext.ll?rev=75511&r1=75510&r2=75511&view=diff</a><br>
<br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/IndVarSimplify/iv-sext.ll (original)<br>
+++ llvm/trunk/test/Transforms/IndVarSimplify/iv-sext.ll Mon Jul 13 16:35:55 2009<br>
@@ -1,7 +1,6 @@<br>
; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t<br>
; RUN: grep {= sext} %t | count 4<br>
; RUN: grep {phi i64} %t | count 2<br>
-; XFAIL: *<br>
<br>
; Indvars should be able to promote the hiPart induction variable in the<br>
; inner loop to i64.<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>