diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h index a36ceb484f1..f2c10c7e6ed 100644 --- a/include/llvm/Analysis/CFG.h +++ b/include/llvm/Analysis/CFG.h @@ -77,9 +77,10 @@ bool isPotentiallyReachable( /// Determine whether there is a path from From to To within a single function. /// Returns false only if we can prove that once 'From' has been reached then /// 'To' can not be executed. Conservatively returns true. -bool isPotentiallyReachable(const BasicBlock *From, const BasicBlock *To, - const DominatorTree *DT = nullptr, - const LoopInfo *LI = nullptr); +bool isPotentiallyReachable( + const BasicBlock *From, const BasicBlock *To, + const SmallPtrSetImpl *ExclusionSet = nullptr, + const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr); /// Determine whether there is at least one path from a block in /// 'Worklist' to 'StopBB', returning true if uncertain. diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 650103fbc61..ec25ee161e2 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -208,16 +208,29 @@ bool llvm::isPotentiallyReachableFromMany( return false; } -bool llvm::isPotentiallyReachable(const BasicBlock *A, const BasicBlock *B, - const DominatorTree *DT, const LoopInfo *LI) { +bool llvm::isPotentiallyReachable( + const BasicBlock *A, const BasicBlock *B, + const SmallPtrSetImpl *ExclusionSet, const DominatorTree *DT, + const LoopInfo *LI) { assert(A->getParent() == B->getParent() && "This analysis is function-local!"); + if (DT) { + if (DT->isReachableFromEntry(A) && !DT->isReachableFromEntry(B)) + return false; + if (!ExclusionSet || ExclusionSet->empty()) { + if (A->isEntryBlock() && DT->isReachableFromEntry(B)) + return true; + if (B->isEntryBlock() && DT->isReachableFromEntry(A)) + return false; + } + } + SmallVector Worklist; Worklist.push_back(const_cast(A)); return isPotentiallyReachableFromMany(Worklist, const_cast(B), - nullptr, DT, LI); + ExclusionSet, DT, LI); } bool llvm::isPotentiallyReachable( @@ -227,8 +240,6 @@ bool llvm::isPotentiallyReachable( assert(A->getParent()->getParent() == B->getParent()->getParent() && "This analysis is function-local!"); - SmallVector Worklist; - if (A->getParent() == B->getParent()) { // The same block case is special because it's the only time we're looking // within a single block to see which instruction comes first. Once we @@ -252,30 +263,18 @@ bool llvm::isPotentiallyReachable( return false; // Otherwise, continue doing the normal per-BB CFG walk. + SmallVector Worklist; Worklist.append(succ_begin(BB), succ_end(BB)); - if (Worklist.empty()) { // We've proven that there's no path! return false; } - } else { - Worklist.push_back(const_cast(A->getParent())); + + return isPotentiallyReachableFromMany( + Worklist, const_cast(B->getParent()), ExclusionSet, + DT, LI); } - if (DT) { - if (DT->isReachableFromEntry(A->getParent()) && - !DT->isReachableFromEntry(B->getParent())) - return false; - if (!ExclusionSet || ExclusionSet->empty()) { - if (A->getParent()->isEntryBlock() && - DT->isReachableFromEntry(B->getParent())) - return true; - if (B->getParent()->isEntryBlock() && - DT->isReachableFromEntry(A->getParent())) - return false; - } - } - - return isPotentiallyReachableFromMany( - Worklist, const_cast(B->getParent()), ExclusionSet, DT, LI); + return isPotentiallyReachable( + A->getParent(), B->getParent(), ExclusionSet, DT, LI); } diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index fc10757dc1e..e5f01ae59f7 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1098,7 +1098,7 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) { // If the incoming non-constant value is in I's block, we will remove one // instruction, but insert another equivalent one, leading to infinite // instcombine. - if (isPotentiallyReachable(I.getParent(), NonConstBB, &DT, LI)) + if (isPotentiallyReachable(I.getParent(), NonConstBB, nullptr, &DT, LI)) return nullptr; }