1*9880d681SAndroid Build Coastguard Worker //===- CFGTest.cpp - CFG tests --------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/CFG.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopInfo.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/AsmParser/Parser.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Dominators.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InstIterator.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
22*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker namespace {
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker // This fixture assists in running the isPotentiallyReachable utility four ways
29*9880d681SAndroid Build Coastguard Worker // and ensuring it produces the correct answer each time.
30*9880d681SAndroid Build Coastguard Worker class IsPotentiallyReachableTest : public testing::Test {
31*9880d681SAndroid Build Coastguard Worker protected:
ParseAssembly(const char * Assembly)32*9880d681SAndroid Build Coastguard Worker void ParseAssembly(const char *Assembly) {
33*9880d681SAndroid Build Coastguard Worker SMDiagnostic Error;
34*9880d681SAndroid Build Coastguard Worker M = parseAssemblyString(Assembly, Error, Context);
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker std::string errMsg;
37*9880d681SAndroid Build Coastguard Worker raw_string_ostream os(errMsg);
38*9880d681SAndroid Build Coastguard Worker Error.print("", os);
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker // A failure here means that the test itself is buggy.
41*9880d681SAndroid Build Coastguard Worker if (!M)
42*9880d681SAndroid Build Coastguard Worker report_fatal_error(os.str().c_str());
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker Function *F = M->getFunction("test");
45*9880d681SAndroid Build Coastguard Worker if (F == nullptr)
46*9880d681SAndroid Build Coastguard Worker report_fatal_error("Test must have a function named @test");
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker A = B = nullptr;
49*9880d681SAndroid Build Coastguard Worker for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
50*9880d681SAndroid Build Coastguard Worker if (I->hasName()) {
51*9880d681SAndroid Build Coastguard Worker if (I->getName() == "A")
52*9880d681SAndroid Build Coastguard Worker A = &*I;
53*9880d681SAndroid Build Coastguard Worker else if (I->getName() == "B")
54*9880d681SAndroid Build Coastguard Worker B = &*I;
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker }
57*9880d681SAndroid Build Coastguard Worker if (A == nullptr)
58*9880d681SAndroid Build Coastguard Worker report_fatal_error("@test must have an instruction %A");
59*9880d681SAndroid Build Coastguard Worker if (B == nullptr)
60*9880d681SAndroid Build Coastguard Worker report_fatal_error("@test must have an instruction %B");
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker
ExpectPath(bool ExpectedResult)63*9880d681SAndroid Build Coastguard Worker void ExpectPath(bool ExpectedResult) {
64*9880d681SAndroid Build Coastguard Worker static char ID;
65*9880d681SAndroid Build Coastguard Worker class IsPotentiallyReachableTestPass : public FunctionPass {
66*9880d681SAndroid Build Coastguard Worker public:
67*9880d681SAndroid Build Coastguard Worker IsPotentiallyReachableTestPass(bool ExpectedResult,
68*9880d681SAndroid Build Coastguard Worker Instruction *A, Instruction *B)
69*9880d681SAndroid Build Coastguard Worker : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B) {}
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker static int initialize() {
72*9880d681SAndroid Build Coastguard Worker PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass",
73*9880d681SAndroid Build Coastguard Worker "", &ID, nullptr, true, true);
74*9880d681SAndroid Build Coastguard Worker PassRegistry::getPassRegistry()->registerPass(*PI, false);
75*9880d681SAndroid Build Coastguard Worker initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
76*9880d681SAndroid Build Coastguard Worker initializeDominatorTreeWrapperPassPass(
77*9880d681SAndroid Build Coastguard Worker *PassRegistry::getPassRegistry());
78*9880d681SAndroid Build Coastguard Worker return 0;
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
82*9880d681SAndroid Build Coastguard Worker AU.setPreservesAll();
83*9880d681SAndroid Build Coastguard Worker AU.addRequired<LoopInfoWrapperPass>();
84*9880d681SAndroid Build Coastguard Worker AU.addRequired<DominatorTreeWrapperPass>();
85*9880d681SAndroid Build Coastguard Worker }
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker bool runOnFunction(Function &F) override {
88*9880d681SAndroid Build Coastguard Worker if (!F.hasName() || F.getName() != "test")
89*9880d681SAndroid Build Coastguard Worker return false;
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
92*9880d681SAndroid Build Coastguard Worker DominatorTree *DT =
93*9880d681SAndroid Build Coastguard Worker &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
94*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, nullptr),
95*9880d681SAndroid Build Coastguard Worker ExpectedResult);
96*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(isPotentiallyReachable(A, B, DT, nullptr), ExpectedResult);
97*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, LI), ExpectedResult);
98*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(isPotentiallyReachable(A, B, DT, LI), ExpectedResult);
99*9880d681SAndroid Build Coastguard Worker return false;
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker bool ExpectedResult;
102*9880d681SAndroid Build Coastguard Worker Instruction *A, *B;
103*9880d681SAndroid Build Coastguard Worker };
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker static int initialize = IsPotentiallyReachableTestPass::initialize();
106*9880d681SAndroid Build Coastguard Worker (void)initialize;
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker IsPotentiallyReachableTestPass *P =
109*9880d681SAndroid Build Coastguard Worker new IsPotentiallyReachableTestPass(ExpectedResult, A, B);
110*9880d681SAndroid Build Coastguard Worker legacy::PassManager PM;
111*9880d681SAndroid Build Coastguard Worker PM.add(P);
112*9880d681SAndroid Build Coastguard Worker PM.run(*M);
113*9880d681SAndroid Build Coastguard Worker }
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker LLVMContext Context;
116*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> M;
117*9880d681SAndroid Build Coastguard Worker Instruction *A, *B;
118*9880d681SAndroid Build Coastguard Worker };
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker }
121*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,SameBlockNoPath)122*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, SameBlockNoPath) {
123*9880d681SAndroid Build Coastguard Worker ParseAssembly(
124*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
125*9880d681SAndroid Build Coastguard Worker "entry:\n"
126*9880d681SAndroid Build Coastguard Worker " bitcast i8 undef to i8\n"
127*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
128*9880d681SAndroid Build Coastguard Worker " bitcast i8 undef to i8\n"
129*9880d681SAndroid Build Coastguard Worker " bitcast i8 undef to i8\n"
130*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
131*9880d681SAndroid Build Coastguard Worker " ret void\n"
132*9880d681SAndroid Build Coastguard Worker "}\n");
133*9880d681SAndroid Build Coastguard Worker ExpectPath(false);
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,SameBlockPath)136*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, SameBlockPath) {
137*9880d681SAndroid Build Coastguard Worker ParseAssembly(
138*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
139*9880d681SAndroid Build Coastguard Worker "entry:\n"
140*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
141*9880d681SAndroid Build Coastguard Worker " bitcast i8 undef to i8\n"
142*9880d681SAndroid Build Coastguard Worker " bitcast i8 undef to i8\n"
143*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
144*9880d681SAndroid Build Coastguard Worker " ret void\n"
145*9880d681SAndroid Build Coastguard Worker "}\n");
146*9880d681SAndroid Build Coastguard Worker ExpectPath(true);
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,SameBlockNoLoop)149*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, SameBlockNoLoop) {
150*9880d681SAndroid Build Coastguard Worker ParseAssembly(
151*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
152*9880d681SAndroid Build Coastguard Worker "entry:\n"
153*9880d681SAndroid Build Coastguard Worker " br label %middle\n"
154*9880d681SAndroid Build Coastguard Worker "middle:\n"
155*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
156*9880d681SAndroid Build Coastguard Worker " bitcast i8 undef to i8\n"
157*9880d681SAndroid Build Coastguard Worker " bitcast i8 undef to i8\n"
158*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
159*9880d681SAndroid Build Coastguard Worker " br label %nextblock\n"
160*9880d681SAndroid Build Coastguard Worker "nextblock:\n"
161*9880d681SAndroid Build Coastguard Worker " ret void\n"
162*9880d681SAndroid Build Coastguard Worker "}\n");
163*9880d681SAndroid Build Coastguard Worker ExpectPath(false);
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,StraightNoPath)166*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, StraightNoPath) {
167*9880d681SAndroid Build Coastguard Worker ParseAssembly(
168*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
169*9880d681SAndroid Build Coastguard Worker "entry:\n"
170*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
171*9880d681SAndroid Build Coastguard Worker " br label %exit\n"
172*9880d681SAndroid Build Coastguard Worker "exit:\n"
173*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
174*9880d681SAndroid Build Coastguard Worker " ret void\n"
175*9880d681SAndroid Build Coastguard Worker "}");
176*9880d681SAndroid Build Coastguard Worker ExpectPath(false);
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,StraightPath)179*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, StraightPath) {
180*9880d681SAndroid Build Coastguard Worker ParseAssembly(
181*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
182*9880d681SAndroid Build Coastguard Worker "entry:\n"
183*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
184*9880d681SAndroid Build Coastguard Worker " br label %exit\n"
185*9880d681SAndroid Build Coastguard Worker "exit:\n"
186*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
187*9880d681SAndroid Build Coastguard Worker " ret void\n"
188*9880d681SAndroid Build Coastguard Worker "}");
189*9880d681SAndroid Build Coastguard Worker ExpectPath(true);
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,DestUnreachable)192*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, DestUnreachable) {
193*9880d681SAndroid Build Coastguard Worker ParseAssembly(
194*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
195*9880d681SAndroid Build Coastguard Worker "entry:\n"
196*9880d681SAndroid Build Coastguard Worker " br label %midblock\n"
197*9880d681SAndroid Build Coastguard Worker "midblock:\n"
198*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
199*9880d681SAndroid Build Coastguard Worker " ret void\n"
200*9880d681SAndroid Build Coastguard Worker "unreachable:\n"
201*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
202*9880d681SAndroid Build Coastguard Worker " br label %midblock\n"
203*9880d681SAndroid Build Coastguard Worker "}");
204*9880d681SAndroid Build Coastguard Worker ExpectPath(false);
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,BranchToReturn)207*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, BranchToReturn) {
208*9880d681SAndroid Build Coastguard Worker ParseAssembly(
209*9880d681SAndroid Build Coastguard Worker "define void @test(i1 %x) {\n"
210*9880d681SAndroid Build Coastguard Worker "entry:\n"
211*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
212*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %block1, label %block2\n"
213*9880d681SAndroid Build Coastguard Worker "block1:\n"
214*9880d681SAndroid Build Coastguard Worker " ret void\n"
215*9880d681SAndroid Build Coastguard Worker "block2:\n"
216*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
217*9880d681SAndroid Build Coastguard Worker " ret void\n"
218*9880d681SAndroid Build Coastguard Worker "}");
219*9880d681SAndroid Build Coastguard Worker ExpectPath(true);
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,SimpleLoop1)222*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, SimpleLoop1) {
223*9880d681SAndroid Build Coastguard Worker ParseAssembly(
224*9880d681SAndroid Build Coastguard Worker "declare i1 @switch()\n"
225*9880d681SAndroid Build Coastguard Worker "\n"
226*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
227*9880d681SAndroid Build Coastguard Worker "entry:\n"
228*9880d681SAndroid Build Coastguard Worker " br label %loop\n"
229*9880d681SAndroid Build Coastguard Worker "loop:\n"
230*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
231*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
232*9880d681SAndroid Build Coastguard Worker " %x = call i1 @switch()\n"
233*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %loop, label %exit\n"
234*9880d681SAndroid Build Coastguard Worker "exit:\n"
235*9880d681SAndroid Build Coastguard Worker " ret void\n"
236*9880d681SAndroid Build Coastguard Worker "}");
237*9880d681SAndroid Build Coastguard Worker ExpectPath(true);
238*9880d681SAndroid Build Coastguard Worker }
239*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,SimpleLoop2)240*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, SimpleLoop2) {
241*9880d681SAndroid Build Coastguard Worker ParseAssembly(
242*9880d681SAndroid Build Coastguard Worker "declare i1 @switch()\n"
243*9880d681SAndroid Build Coastguard Worker "\n"
244*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
245*9880d681SAndroid Build Coastguard Worker "entry:\n"
246*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
247*9880d681SAndroid Build Coastguard Worker " br label %loop\n"
248*9880d681SAndroid Build Coastguard Worker "loop:\n"
249*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
250*9880d681SAndroid Build Coastguard Worker " %x = call i1 @switch()\n"
251*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %loop, label %exit\n"
252*9880d681SAndroid Build Coastguard Worker "exit:\n"
253*9880d681SAndroid Build Coastguard Worker " ret void\n"
254*9880d681SAndroid Build Coastguard Worker "}");
255*9880d681SAndroid Build Coastguard Worker ExpectPath(false);
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,SimpleLoop3)258*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, SimpleLoop3) {
259*9880d681SAndroid Build Coastguard Worker ParseAssembly(
260*9880d681SAndroid Build Coastguard Worker "declare i1 @switch()\n"
261*9880d681SAndroid Build Coastguard Worker "\n"
262*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
263*9880d681SAndroid Build Coastguard Worker "entry:\n"
264*9880d681SAndroid Build Coastguard Worker " br label %loop\n"
265*9880d681SAndroid Build Coastguard Worker "loop:\n"
266*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
267*9880d681SAndroid Build Coastguard Worker " %x = call i1 @switch()\n"
268*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %loop, label %exit\n"
269*9880d681SAndroid Build Coastguard Worker "exit:\n"
270*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
271*9880d681SAndroid Build Coastguard Worker " ret void\n"
272*9880d681SAndroid Build Coastguard Worker "}");
273*9880d681SAndroid Build Coastguard Worker ExpectPath(false);
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,OneLoopAfterTheOther1)277*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther1) {
278*9880d681SAndroid Build Coastguard Worker ParseAssembly(
279*9880d681SAndroid Build Coastguard Worker "declare i1 @switch()\n"
280*9880d681SAndroid Build Coastguard Worker "\n"
281*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
282*9880d681SAndroid Build Coastguard Worker "entry:\n"
283*9880d681SAndroid Build Coastguard Worker " br label %loop1\n"
284*9880d681SAndroid Build Coastguard Worker "loop1:\n"
285*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
286*9880d681SAndroid Build Coastguard Worker " %x = call i1 @switch()\n"
287*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %loop1, label %loop1exit\n"
288*9880d681SAndroid Build Coastguard Worker "loop1exit:\n"
289*9880d681SAndroid Build Coastguard Worker " br label %loop2\n"
290*9880d681SAndroid Build Coastguard Worker "loop2:\n"
291*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
292*9880d681SAndroid Build Coastguard Worker " %y = call i1 @switch()\n"
293*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %loop2, label %loop2exit\n"
294*9880d681SAndroid Build Coastguard Worker "loop2exit:"
295*9880d681SAndroid Build Coastguard Worker " ret void\n"
296*9880d681SAndroid Build Coastguard Worker "}");
297*9880d681SAndroid Build Coastguard Worker ExpectPath(true);
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,OneLoopAfterTheOther2)300*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther2) {
301*9880d681SAndroid Build Coastguard Worker ParseAssembly(
302*9880d681SAndroid Build Coastguard Worker "declare i1 @switch()\n"
303*9880d681SAndroid Build Coastguard Worker "\n"
304*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
305*9880d681SAndroid Build Coastguard Worker "entry:\n"
306*9880d681SAndroid Build Coastguard Worker " br label %loop1\n"
307*9880d681SAndroid Build Coastguard Worker "loop1:\n"
308*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
309*9880d681SAndroid Build Coastguard Worker " %x = call i1 @switch()\n"
310*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %loop1, label %loop1exit\n"
311*9880d681SAndroid Build Coastguard Worker "loop1exit:\n"
312*9880d681SAndroid Build Coastguard Worker " br label %loop2\n"
313*9880d681SAndroid Build Coastguard Worker "loop2:\n"
314*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
315*9880d681SAndroid Build Coastguard Worker " %y = call i1 @switch()\n"
316*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %loop2, label %loop2exit\n"
317*9880d681SAndroid Build Coastguard Worker "loop2exit:"
318*9880d681SAndroid Build Coastguard Worker " ret void\n"
319*9880d681SAndroid Build Coastguard Worker "}");
320*9880d681SAndroid Build Coastguard Worker ExpectPath(false);
321*9880d681SAndroid Build Coastguard Worker }
322*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,OneLoopAfterTheOtherInsideAThirdLoop)323*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOtherInsideAThirdLoop) {
324*9880d681SAndroid Build Coastguard Worker ParseAssembly(
325*9880d681SAndroid Build Coastguard Worker "declare i1 @switch()\n"
326*9880d681SAndroid Build Coastguard Worker "\n"
327*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
328*9880d681SAndroid Build Coastguard Worker "entry:\n"
329*9880d681SAndroid Build Coastguard Worker " br label %outerloop3\n"
330*9880d681SAndroid Build Coastguard Worker "outerloop3:\n"
331*9880d681SAndroid Build Coastguard Worker " br label %innerloop1\n"
332*9880d681SAndroid Build Coastguard Worker "innerloop1:\n"
333*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
334*9880d681SAndroid Build Coastguard Worker " %x = call i1 @switch()\n"
335*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %innerloop1, label %innerloop1exit\n"
336*9880d681SAndroid Build Coastguard Worker "innerloop1exit:\n"
337*9880d681SAndroid Build Coastguard Worker " br label %innerloop2\n"
338*9880d681SAndroid Build Coastguard Worker "innerloop2:\n"
339*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
340*9880d681SAndroid Build Coastguard Worker " %y = call i1 @switch()\n"
341*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %innerloop2, label %innerloop2exit\n"
342*9880d681SAndroid Build Coastguard Worker "innerloop2exit:"
343*9880d681SAndroid Build Coastguard Worker " ;; In outer loop3 now.\n"
344*9880d681SAndroid Build Coastguard Worker " %z = call i1 @switch()\n"
345*9880d681SAndroid Build Coastguard Worker " br i1 %z, label %outerloop3, label %exit\n"
346*9880d681SAndroid Build Coastguard Worker "exit:\n"
347*9880d681SAndroid Build Coastguard Worker " ret void\n"
348*9880d681SAndroid Build Coastguard Worker "}");
349*9880d681SAndroid Build Coastguard Worker ExpectPath(true);
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker static const char *BranchInsideLoopIR =
353*9880d681SAndroid Build Coastguard Worker "declare i1 @switch()\n"
354*9880d681SAndroid Build Coastguard Worker "\n"
355*9880d681SAndroid Build Coastguard Worker "define void @test() {\n"
356*9880d681SAndroid Build Coastguard Worker "entry:\n"
357*9880d681SAndroid Build Coastguard Worker " br label %loop\n"
358*9880d681SAndroid Build Coastguard Worker "loop:\n"
359*9880d681SAndroid Build Coastguard Worker " %x = call i1 @switch()\n"
360*9880d681SAndroid Build Coastguard Worker " br i1 %x, label %nextloopblock, label %exit\n"
361*9880d681SAndroid Build Coastguard Worker "nextloopblock:\n"
362*9880d681SAndroid Build Coastguard Worker " %y = call i1 @switch()\n"
363*9880d681SAndroid Build Coastguard Worker " br i1 %y, label %left, label %right\n"
364*9880d681SAndroid Build Coastguard Worker "left:\n"
365*9880d681SAndroid Build Coastguard Worker " %A = bitcast i8 undef to i8\n"
366*9880d681SAndroid Build Coastguard Worker " br label %loop\n"
367*9880d681SAndroid Build Coastguard Worker "right:\n"
368*9880d681SAndroid Build Coastguard Worker " %B = bitcast i8 undef to i8\n"
369*9880d681SAndroid Build Coastguard Worker " br label %loop\n"
370*9880d681SAndroid Build Coastguard Worker "exit:\n"
371*9880d681SAndroid Build Coastguard Worker " ret void\n"
372*9880d681SAndroid Build Coastguard Worker "}";
373*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,BranchInsideLoop)374*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, BranchInsideLoop) {
375*9880d681SAndroid Build Coastguard Worker ParseAssembly(BranchInsideLoopIR);
376*9880d681SAndroid Build Coastguard Worker ExpectPath(true);
377*9880d681SAndroid Build Coastguard Worker }
378*9880d681SAndroid Build Coastguard Worker
TEST_F(IsPotentiallyReachableTest,ModifyTest)379*9880d681SAndroid Build Coastguard Worker TEST_F(IsPotentiallyReachableTest, ModifyTest) {
380*9880d681SAndroid Build Coastguard Worker ParseAssembly(BranchInsideLoopIR);
381*9880d681SAndroid Build Coastguard Worker
382*9880d681SAndroid Build Coastguard Worker succ_iterator S = succ_begin(&*++M->getFunction("test")->begin());
383*9880d681SAndroid Build Coastguard Worker BasicBlock *OldBB = S[0];
384*9880d681SAndroid Build Coastguard Worker S[0] = S[1];
385*9880d681SAndroid Build Coastguard Worker ExpectPath(false);
386*9880d681SAndroid Build Coastguard Worker S[0] = OldBB;
387*9880d681SAndroid Build Coastguard Worker ExpectPath(true);
388*9880d681SAndroid Build Coastguard Worker }
389