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&,
// 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) {
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) {
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;
// 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.
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
// 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())) {
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;
}
}
}