diff --git a/llvm/lib/Analysis/CFG.cpp b/llvm/lib/Analysis/CFG.cpp --- a/llvm/lib/Analysis/CFG.cpp +++ b/llvm/lib/Analysis/CFG.cpp @@ -226,10 +226,17 @@ Worklist.push_back(const_cast(A->getParent())); } - if (A->getParent() == &A->getParent()->getParent()->getEntryBlock()) - return true; - if (B->getParent() == &A->getParent()->getParent()->getEntryBlock()) - return false; + if (DT) { + if (DT->isReachableFromEntry(A->getParent()) != + DT->isReachableFromEntry(B->getParent())) + return false; + if (A->getParent() == &A->getParent()->getParent()->getEntryBlock() && + DT->isReachableFromEntry(B->getParent())) + return true; + if (B->getParent() == &A->getParent()->getParent()->getEntryBlock() && + DT->isReachableFromEntry(A->getParent())) + return false; + } return isPotentiallyReachableFromMany( Worklist, const_cast(B->getParent()), DT, LI); diff --git a/llvm/unittests/Analysis/CFGTest.cpp b/llvm/unittests/Analysis/CFGTest.cpp --- a/llvm/unittests/Analysis/CFGTest.cpp +++ b/llvm/unittests/Analysis/CFGTest.cpp @@ -385,3 +385,43 @@ S[0] = OldBB; ExpectPath(true); } + +TEST_F(IsPotentiallyReachableTest, UnreachableFromEntryTest) { + ParseAssembly("define void @test() {\n" + "entry:\n" + " %A = bitcast i8 undef to i8\n" + " ret void\n" + "not.reachable:\n" + " %B = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(false); +} + +TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest1) { + ParseAssembly("define void @test() {\n" + "entry:\n" + " ret void\n" + "not.reachable.1:\n" + " %A = bitcast i8 undef to i8\n" + " br label %not.reachable.2\n" + "not.reachable.2:\n" + " %B = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(true); +} + +TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest2) { + ParseAssembly("define void @test() {\n" + "entry:\n" + " ret void\n" + "not.reachable.1:\n" + " %B = bitcast i8 undef to i8\n" + " br label %not.reachable.2\n" + "not.reachable.2:\n" + " %A = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(false); +}