Revert 54821. It's miscompiling 252.eon and 447.dealII
[oota-llvm.git] / lib / Transforms / Scalar / LoopStrengthReduce.cpp
index 5bbc8322bc67c48ea969ddc503d2f543badab4df..04faa0aa50819d3201fd89ab2348f044a3bd52d3 100644 (file)
@@ -177,7 +177,7 @@ private:
                                   IVStrideUse* &CondUse,
                                   const SCEVHandle* &CondStride);
     void OptimizeIndvars(Loop *L);
-    bool FindIVForUser(ICmpInst *Cond, IVStrideUse *&CondUse,
+    bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
                        const SCEVHandle *&CondStride);
     bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
     unsigned CheckForIVReuse(bool, bool, const SCEVHandle&,
@@ -1453,10 +1453,10 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
   // different starting values, into different PHIs.
 }
 
-/// FindIVForUser - If Cond has an operand that is an expression of an IV,
+/// FindIVUserForCond - If Cond has an operand that is an expression of an IV,
 /// set the IV user and stride information and return true, otherwise return
 /// false.
-bool LoopStrengthReduce::FindIVForUser(ICmpInst *Cond, IVStrideUse *&CondUse,
+bool LoopStrengthReduce::FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
                                        const SCEVHandle *&CondStride) {
   for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e && !CondUse;
        ++Stride) {
@@ -1542,6 +1542,12 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
   Value *NewIncV = NULL;
   int64_t Scale = 1;
 
+  // Check stride constant and the comparision constant signs to detect
+  // overflow.
+  if (ICmpInst::isSignedPredicate(Predicate) &&
+      (CmpVal & SignBit) != (CmpSSInt & SignBit))
+    return Cond;
+
   // Look for a suitable stride / iv as replacement.
   std::stable_sort(StrideOrder.begin(), StrideOrder.end(), StrideCompare());
   for (unsigned i = 0, e = StrideOrder.size(); i != e; ++i) {
@@ -1624,10 +1630,10 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
         continue;
       }
 
-      // If scale is negative, use inverse predicate unless it's testing
+      // If scale is negative, use swapped predicate unless it's testing
       // for equality.
       if (Scale < 0 && !Cond->isEquality())
-        Predicate = ICmpInst::getInversePredicate(Predicate);
+        Predicate = ICmpInst::getSwappedPredicate(Predicate);
 
       NewStride = &StrideOrder[i];
       break;
@@ -1640,11 +1646,12 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
   // before the branch. See
   // test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-*.ll
   // for an example of this situation.
-  if (!Cond->hasOneUse())
+  if (!Cond->hasOneUse()) {
     for (BasicBlock::iterator I = Cond, E = Cond->getParent()->end();
          I != E; ++I)
       if (I == NewIncV)
         return Cond;
+  }
 
   if (NewCmpVal != CmpVal) {
     // Create a new compare instruction using new stride / iv.
@@ -1706,7 +1713,7 @@ void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
   IVStrideUse *CondUse = 0;
   const SCEVHandle *CondStride = 0;
 
-  if (!FindIVForUser(Cond, CondUse, CondStride))
+  if (!FindIVUserForCond(Cond, CondUse, CondStride))
     return; // setcc doesn't use the IV.
 
   // If possible, change stride and operands of the compare instruction to
@@ -1823,6 +1830,7 @@ bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
       // FIXME: this needs to eliminate an induction variable even if it's being
       // compared against some value to decide loop termination.
       if (PN->hasOneUse()) {
+        SmallPtrSet<PHINode *, 2> PHIs;
         for (Instruction *J = dyn_cast<Instruction>(*PN->use_begin());
              J && J->hasOneUse() && !J->mayWriteToMemory();
              J = dyn_cast<Instruction>(*J->use_begin())) {
@@ -1835,6 +1843,10 @@ bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
             Changed = true;
             break;
           }
+          // If we find a PHI more than once, we're on a cycle that
+          // won't prove fruitful.
+          if (isa<PHINode>(J) && !PHIs.insert(cast<PHINode>(J)))
+            break;
         }
       }
     }