Index: llvm/include/llvm/Analysis/ScalarEvolution.h =================================================================== --- llvm/include/llvm/Analysis/ScalarEvolution.h +++ llvm/include/llvm/Analysis/ScalarEvolution.h @@ -803,6 +803,13 @@ /// Cache for \c loopHasNoAbnormalExits. DenseMap LoopHasNoAbnormalExits; + /// Cache for \c loopHasNoSideEffects. + DenseMap LoopHasNoSideEffects; + + /// Returns true if \p L contains no instruction that can have side effects + /// (i.e. via throwing an exception, volatile or atomic access). + bool loopHasNoSideEffects(const Loop *L); + /// Returns true if \p L contains no instruction that can abnormally exit /// the loop (i.e. via throwing an exception, by terminating the thread /// cleanly or by infinite looping in a called function). Strictly Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -4947,6 +4947,28 @@ return LatchControlDependentOnPoison && loopHasNoAbnormalExits(L); } +bool ScalarEvolution::loopHasNoSideEffects(const Loop *L) { + auto Itr = LoopHasNoSideEffects.find(L); + if (Itr == LoopHasNoSideEffects.end()) { + auto NoSideEffectsInBB = [&](BasicBlock *BB) { + return all_of(*BB, [](Instruction &I) { + // Non-atomic, non-volatile stores are ok. + if (auto *SI = dyn_cast(&I)) + return SI->isSimple(); + + return !I.mayHaveSideEffects(); + }); + }; + + auto InsertPair = LoopHasNoSideEffects.insert( + {L, all_of(L->getBlocks(), NoSideEffectsInBB)}); + assert(InsertPair.second && "We just checked!"); + Itr = InsertPair.first; + } + + return Itr->second; +} + bool ScalarEvolution::loopHasNoAbnormalExits(const Loop *L) { auto Itr = LoopHasNoAbnormalExits.find(L); if (Itr == LoopHasNoAbnormalExits.end()) { @@ -5534,6 +5556,7 @@ forgetLoop(I); LoopHasNoAbnormalExits.erase(L); + LoopHasNoSideEffects.erase(L); } void ScalarEvolution::forgetValue(Value *V) { @@ -8686,11 +8709,15 @@ return getCouldNotCompute(); const SCEVAddRecExpr *IV = dyn_cast(LHS); - if (!IV && AllowPredicates) + bool PredicatedIV = false; + + if (!IV && AllowPredicates) { // Try to make this an AddRec using runtime tests, in the first X // iterations of this loop, where X is the SCEV expression found by the // algorithm below. IV = convertSCEVToAddRecWithPredicates(LHS, L, P); + PredicatedIV = true; + } // Avoid weird loops if (!IV || IV->getLoop() != L || !IV->isAffine()) @@ -8701,9 +8728,30 @@ const SCEV *Stride = IV->getStepRecurrence(*this); - // Avoid negative or zero stride values - if (!isKnownPositive(Stride)) - return getCouldNotCompute(); + bool PositiveStride = isKnownPositive(Stride); + + // Avoid negative or zero stride values. + if (!PositiveStride) + // We can compute the correct backedge taken count for loops with unknown + // strides if we can prove that the loop is not an infinite loop with side + // effects. The following checks are used to check the same. Here's an + // example of the loop we are trying to handle here - + // + // for(int i=0; i