1 //===- CFGTest.cpp - CFG tests --------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Analysis/CFG.h"
11 #include "llvm/Analysis/LoopInfo.h"
12 #include "llvm/AsmParser/Parser.h"
13 #include "llvm/IR/Dominators.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/InstIterator.h"
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/LegacyPassManager.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Pass.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "gtest/gtest.h"
28 // This fixture assists in running the isPotentiallyReachable utility four ways
29 // and ensuring it produces the correct answer each time.
30 class IsPotentiallyReachableTest : public testing::Test {
32 void ParseAssembly(const char *Assembly) {
34 M = parseAssemblyString(Assembly, Error, Context);
37 raw_string_ostream os(errMsg);
40 // A failure here means that the test itself is buggy.
42 report_fatal_error(os.str().c_str());
44 Function *F = M->getFunction("test");
46 report_fatal_error("Test must have a function named @test");
49 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
51 if (I->getName() == "A")
53 else if (I->getName() == "B")
58 report_fatal_error("@test must have an instruction %A");
60 report_fatal_error("@test must have an instruction %B");
63 void ExpectPath(bool ExpectedResult) {
65 class IsPotentiallyReachableTestPass : public FunctionPass {
67 IsPotentiallyReachableTestPass(bool ExpectedResult,
68 Instruction *A, Instruction *B)
69 : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B) {}
71 static int initialize() {
72 PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass",
73 "", &ID, nullptr, true, true);
74 PassRegistry::getPassRegistry()->registerPass(*PI, false);
75 initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
76 initializeDominatorTreeWrapperPassPass(
77 *PassRegistry::getPassRegistry());
81 void getAnalysisUsage(AnalysisUsage &AU) const override {
83 AU.addRequired<LoopInfoWrapperPass>();
84 AU.addRequired<DominatorTreeWrapperPass>();
87 bool runOnFunction(Function &F) override {
88 if (!F.hasName() || F.getName() != "test")
91 LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
93 &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
94 EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, nullptr),
96 EXPECT_EQ(isPotentiallyReachable(A, B, DT, nullptr), ExpectedResult);
97 EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, LI), ExpectedResult);
98 EXPECT_EQ(isPotentiallyReachable(A, B, DT, LI), ExpectedResult);
105 static int initialize = IsPotentiallyReachableTestPass::initialize();
108 IsPotentiallyReachableTestPass *P =
109 new IsPotentiallyReachableTestPass(ExpectedResult, A, B);
110 legacy::PassManager PM;
116 std::unique_ptr<Module> M;
122 TEST_F(IsPotentiallyReachableTest, SameBlockNoPath) {
124 "define void @test() {\n"
126 " bitcast i8 undef to i8\n"
127 " %B = bitcast i8 undef to i8\n"
128 " bitcast i8 undef to i8\n"
129 " bitcast i8 undef to i8\n"
130 " %A = bitcast i8 undef to i8\n"
136 TEST_F(IsPotentiallyReachableTest, SameBlockPath) {
138 "define void @test() {\n"
140 " %A = bitcast i8 undef to i8\n"
141 " bitcast i8 undef to i8\n"
142 " bitcast i8 undef to i8\n"
143 " %B = bitcast i8 undef to i8\n"
149 TEST_F(IsPotentiallyReachableTest, SameBlockNoLoop) {
151 "define void @test() {\n"
153 " br label %middle\n"
155 " %B = bitcast i8 undef to i8\n"
156 " bitcast i8 undef to i8\n"
157 " bitcast i8 undef to i8\n"
158 " %A = bitcast i8 undef to i8\n"
159 " br label %nextblock\n"
166 TEST_F(IsPotentiallyReachableTest, StraightNoPath) {
168 "define void @test() {\n"
170 " %B = bitcast i8 undef to i8\n"
173 " %A = bitcast i8 undef to i8\n"
179 TEST_F(IsPotentiallyReachableTest, StraightPath) {
181 "define void @test() {\n"
183 " %A = bitcast i8 undef to i8\n"
186 " %B = bitcast i8 undef to i8\n"
192 TEST_F(IsPotentiallyReachableTest, DestUnreachable) {
194 "define void @test() {\n"
196 " br label %midblock\n"
198 " %A = bitcast i8 undef to i8\n"
201 " %B = bitcast i8 undef to i8\n"
202 " br label %midblock\n"
207 TEST_F(IsPotentiallyReachableTest, BranchToReturn) {
209 "define void @test(i1 %x) {\n"
211 " %A = bitcast i8 undef to i8\n"
212 " br i1 %x, label %block1, label %block2\n"
216 " %B = bitcast i8 undef to i8\n"
222 TEST_F(IsPotentiallyReachableTest, SimpleLoop1) {
224 "declare i1 @switch()\n"
226 "define void @test() {\n"
230 " %B = bitcast i8 undef to i8\n"
231 " %A = bitcast i8 undef to i8\n"
232 " %x = call i1 @switch()\n"
233 " br i1 %x, label %loop, label %exit\n"
240 TEST_F(IsPotentiallyReachableTest, SimpleLoop2) {
242 "declare i1 @switch()\n"
244 "define void @test() {\n"
246 " %B = bitcast i8 undef to i8\n"
249 " %A = bitcast i8 undef to i8\n"
250 " %x = call i1 @switch()\n"
251 " br i1 %x, label %loop, label %exit\n"
258 TEST_F(IsPotentiallyReachableTest, SimpleLoop3) {
260 "declare i1 @switch()\n"
262 "define void @test() {\n"
266 " %B = bitcast i8 undef to i8\n"
267 " %x = call i1 @switch()\n"
268 " br i1 %x, label %loop, label %exit\n"
270 " %A = bitcast i8 undef to i8\n"
277 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther1) {
279 "declare i1 @switch()\n"
281 "define void @test() {\n"
285 " %A = bitcast i8 undef to i8\n"
286 " %x = call i1 @switch()\n"
287 " br i1 %x, label %loop1, label %loop1exit\n"
291 " %B = bitcast i8 undef to i8\n"
292 " %y = call i1 @switch()\n"
293 " br i1 %x, label %loop2, label %loop2exit\n"
300 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther2) {
302 "declare i1 @switch()\n"
304 "define void @test() {\n"
308 " %B = bitcast i8 undef to i8\n"
309 " %x = call i1 @switch()\n"
310 " br i1 %x, label %loop1, label %loop1exit\n"
314 " %A = bitcast i8 undef to i8\n"
315 " %y = call i1 @switch()\n"
316 " br i1 %x, label %loop2, label %loop2exit\n"
323 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOtherInsideAThirdLoop) {
325 "declare i1 @switch()\n"
327 "define void @test() {\n"
329 " br label %outerloop3\n"
331 " br label %innerloop1\n"
333 " %B = bitcast i8 undef to i8\n"
334 " %x = call i1 @switch()\n"
335 " br i1 %x, label %innerloop1, label %innerloop1exit\n"
337 " br label %innerloop2\n"
339 " %A = bitcast i8 undef to i8\n"
340 " %y = call i1 @switch()\n"
341 " br i1 %x, label %innerloop2, label %innerloop2exit\n"
343 " ;; In outer loop3 now.\n"
344 " %z = call i1 @switch()\n"
345 " br i1 %z, label %outerloop3, label %exit\n"
352 static const char *BranchInsideLoopIR =
353 "declare i1 @switch()\n"
355 "define void @test() {\n"
359 " %x = call i1 @switch()\n"
360 " br i1 %x, label %nextloopblock, label %exit\n"
362 " %y = call i1 @switch()\n"
363 " br i1 %y, label %left, label %right\n"
365 " %A = bitcast i8 undef to i8\n"
368 " %B = bitcast i8 undef to i8\n"
374 TEST_F(IsPotentiallyReachableTest, BranchInsideLoop) {
375 ParseAssembly(BranchInsideLoopIR);
379 TEST_F(IsPotentiallyReachableTest, ModifyTest) {
380 ParseAssembly(BranchInsideLoopIR);
382 succ_iterator S = succ_begin(&*++M->getFunction("test")->begin());
383 BasicBlock *OldBB = S[0];