From 7ebc16269610c46b795f7d38ee1c853361e8df5d Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Mon, 1 Apr 2019 20:03:16 +0000 Subject: [PATCH] Not all blocks are reachable from entry. Don't assume they are. Fixes a bug in isPotentiallyReachable, noticed by inspection. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357425 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFG.cpp | 15 +++++++++++---- unittests/Analysis/CFGTest.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index d71dd116ce3..6ef36dcad57 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -226,10 +226,17 @@ bool llvm::isPotentiallyReachable(const Instruction *A, const Instruction *B, 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/unittests/Analysis/CFGTest.cpp b/unittests/Analysis/CFGTest.cpp index d2f0d8e13df..aad3aa6d28e 100644 --- a/unittests/Analysis/CFGTest.cpp +++ b/unittests/Analysis/CFGTest.cpp @@ -385,3 +385,43 @@ TEST_F(IsPotentiallyReachableTest, ModifyTest) { 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); +} -- 2.11.0