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>