Index: llvm/include/llvm/Analysis/ScalarEvolution.h =================================================================== --- llvm/include/llvm/Analysis/ScalarEvolution.h +++ llvm/include/llvm/Analysis/ScalarEvolution.h @@ -677,6 +677,13 @@ bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS); + /// Test whether entry to the basic block is protected by a conditional + /// between LHS + /// and RHS. + bool isBasicBlockEntryGuardedByCond(const BasicBlock *BB, + ICmpInst::Predicate Pred, const SCEV *LHS, + const SCEV *RHS); + /// Test whether the backedge of the loop is protected by a conditional /// between LHS and RHS. This is used to eliminate casts. bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -9451,24 +9451,14 @@ return false; } -bool -ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, - ICmpInst::Predicate Pred, - const SCEV *LHS, const SCEV *RHS) { - // Interpret a null as meaning no loop, where there is obviously no guard - // (interprocedural conditions notwithstanding). - if (!L) return false; - +bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB, + ICmpInst::Predicate Pred, + const SCEV *LHS, + const SCEV *RHS) { if (VerifyIR) - assert(!verifyFunction(*L->getHeader()->getParent(), &dbgs()) && + assert(!verifyFunction(*BB->getParent(), &dbgs()) && "This cannot be done on broken IR!"); - // Both LHS and RHS must be available at loop entry. - assert(isAvailableAtLoopEntry(LHS, L) && - "LHS is not available at Loop Entry"); - assert(isAvailableAtLoopEntry(RHS, L) && - "RHS is not available at Loop Entry"); - if (isKnownViaNonRecursiveReasoning(Pred, LHS, RHS)) return true; @@ -9525,13 +9515,17 @@ return false; }; - // Starting at the loop predecessor, climb up the predecessor chain, as long + // Starting at the block's predecessor, climb up the predecessor chain, as long // as there are predecessors that can be found that have unique successors - // leading to the original header. - for (std::pair Pair( - L->getLoopPredecessor(), L->getHeader()); + // leading to the original block. + const Loop *ContainingLoop = LI.getLoopFor(BB); + const BasicBlock *PredBB; + if (ContainingLoop && ContainingLoop->getHeader() == BB) + PredBB = ContainingLoop->getLoopPredecessor(); + else + PredBB = BB->getSinglePredecessor(); + for (std::pair Pair(PredBB, BB); Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) { - if (ProveViaGuard(Pair.first)) return true; @@ -9551,7 +9545,7 @@ if (!AssumeVH) continue; auto *CI = cast(AssumeVH); - if (!DT.dominates(CI, L->getHeader())) + if (!DT.dominates(CI, BB)) continue; if (ProveViaCond(CI->getArgOperand(0), false)) @@ -9561,6 +9555,23 @@ return false; } +bool ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, + ICmpInst::Predicate Pred, + const SCEV *LHS, + const SCEV *RHS) { + // Interpret a null as meaning no loop, where there is obviously no guard + // (interprocedural conditions notwithstanding). + if (!L) + return false; + + // Both LHS and RHS must be available at loop entry. + assert(isAvailableAtLoopEntry(LHS, L) && + "LHS is not available at Loop Entry"); + assert(isAvailableAtLoopEntry(RHS, L) && + "RHS is not available at Loop Entry"); + return isBasicBlockEntryGuardedByCond(L->getHeader(), Pred, LHS, RHS); +} + bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Value *FoundCondValue, bool Inverse) {