1 //===- CFGTest.cpp - CFG tests --------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Analysis/CFG.h"
10 #include "llvm/ADT/SmallPtrSet.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/InitializePasses.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(errMsg
.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");
62 assert(ExclusionSet
.empty());
63 for (auto I
= F
->begin(), E
= F
->end(); I
!= E
; ++I
) {
64 if (I
->hasName() && I
->getName().starts_with("excluded"))
65 ExclusionSet
.insert(&*I
);
69 void ExpectPath(bool ExpectedResult
) {
71 class IsPotentiallyReachableTestPass
: public FunctionPass
{
73 IsPotentiallyReachableTestPass(bool ExpectedResult
, Instruction
*A
,
75 SmallPtrSet
<BasicBlock
*, 4> ExclusionSet
)
76 : FunctionPass(ID
), ExpectedResult(ExpectedResult
), A(A
), B(B
),
77 ExclusionSet(ExclusionSet
) {}
79 static int initialize() {
80 PassInfo
*PI
= new PassInfo("isPotentiallyReachable testing pass", "",
81 &ID
, nullptr, true, true);
82 PassRegistry::getPassRegistry()->registerPass(*PI
, true);
83 initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
84 initializeDominatorTreeWrapperPassPass(
85 *PassRegistry::getPassRegistry());
89 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
91 AU
.addRequired
<LoopInfoWrapperPass
>();
92 AU
.addRequired
<DominatorTreeWrapperPass
>();
95 bool runOnFunction(Function
&F
) override
{
96 if (!F
.hasName() || F
.getName() != "test")
99 LoopInfo
*LI
= &getAnalysis
<LoopInfoWrapperPass
>().getLoopInfo();
101 &getAnalysis
<DominatorTreeWrapperPass
>().getDomTree();
102 EXPECT_EQ(isPotentiallyReachable(A
, B
, &ExclusionSet
, nullptr, nullptr),
104 EXPECT_EQ(isPotentiallyReachable(A
, B
, &ExclusionSet
, DT
, nullptr),
106 EXPECT_EQ(isPotentiallyReachable(A
, B
, &ExclusionSet
, nullptr, LI
),
108 EXPECT_EQ(isPotentiallyReachable(A
, B
, &ExclusionSet
, DT
, LI
),
114 SmallPtrSet
<BasicBlock
*, 4> ExclusionSet
;
117 static int initialize
= IsPotentiallyReachableTestPass::initialize();
120 IsPotentiallyReachableTestPass
*P
=
121 new IsPotentiallyReachableTestPass(ExpectedResult
, A
, B
, ExclusionSet
);
122 legacy::PassManager PM
;
128 std::unique_ptr
<Module
> M
;
130 SmallPtrSet
<BasicBlock
*, 4> ExclusionSet
;
135 TEST_F(IsPotentiallyReachableTest
, SameBlockNoPath
) {
137 "define void @test() {\n"
139 " bitcast i8 undef to i8\n"
140 " %B = bitcast i8 undef to i8\n"
141 " bitcast i8 undef to i8\n"
142 " bitcast i8 undef to i8\n"
143 " %A = bitcast i8 undef to i8\n"
149 TEST_F(IsPotentiallyReachableTest
, SameBlockPath
) {
151 "define void @test() {\n"
153 " %A = bitcast i8 undef to i8\n"
154 " bitcast i8 undef to i8\n"
155 " bitcast i8 undef to i8\n"
156 " %B = bitcast i8 undef to i8\n"
162 TEST_F(IsPotentiallyReachableTest
, SameBlockNoLoop
) {
164 "define void @test() {\n"
166 " br label %middle\n"
168 " %B = bitcast i8 undef to i8\n"
169 " bitcast i8 undef to i8\n"
170 " bitcast i8 undef to i8\n"
171 " %A = bitcast i8 undef to i8\n"
172 " br label %nextblock\n"
179 TEST_F(IsPotentiallyReachableTest
, StraightNoPath
) {
181 "define void @test() {\n"
183 " %B = bitcast i8 undef to i8\n"
186 " %A = bitcast i8 undef to i8\n"
192 TEST_F(IsPotentiallyReachableTest
, StraightPath
) {
194 "define void @test() {\n"
196 " %A = bitcast i8 undef to i8\n"
199 " %B = bitcast i8 undef to i8\n"
205 TEST_F(IsPotentiallyReachableTest
, DestUnreachable
) {
207 "define void @test() {\n"
209 " br label %midblock\n"
211 " %A = bitcast i8 undef to i8\n"
214 " %B = bitcast i8 undef to i8\n"
215 " br label %midblock\n"
220 TEST_F(IsPotentiallyReachableTest
, BranchToReturn
) {
222 "define void @test(i1 %x) {\n"
224 " %A = bitcast i8 undef to i8\n"
225 " br i1 %x, label %block1, label %block2\n"
229 " %B = bitcast i8 undef to i8\n"
235 TEST_F(IsPotentiallyReachableTest
, SimpleLoop1
) {
237 "declare i1 @switch()\n"
239 "define void @test() {\n"
243 " %B = bitcast i8 undef to i8\n"
244 " %A = bitcast i8 undef to i8\n"
245 " %x = call i1 @switch()\n"
246 " br i1 %x, label %loop, label %exit\n"
253 TEST_F(IsPotentiallyReachableTest
, SimpleLoop2
) {
255 "declare i1 @switch()\n"
257 "define void @test() {\n"
259 " %B = bitcast i8 undef to i8\n"
262 " %A = bitcast i8 undef to i8\n"
263 " %x = call i1 @switch()\n"
264 " br i1 %x, label %loop, label %exit\n"
271 TEST_F(IsPotentiallyReachableTest
, SimpleLoop3
) {
273 "declare i1 @switch()\n"
275 "define void @test() {\n"
279 " %B = bitcast i8 undef to i8\n"
280 " %x = call i1 @switch()\n"
281 " br i1 %x, label %loop, label %exit\n"
283 " %A = bitcast i8 undef to i8\n"
290 TEST_F(IsPotentiallyReachableTest
, OneLoopAfterTheOther1
) {
292 "declare i1 @switch()\n"
294 "define void @test() {\n"
298 " %A = bitcast i8 undef to i8\n"
299 " %x = call i1 @switch()\n"
300 " br i1 %x, label %loop1, label %loop1exit\n"
304 " %B = bitcast i8 undef to i8\n"
305 " %y = call i1 @switch()\n"
306 " br i1 %x, label %loop2, label %loop2exit\n"
313 TEST_F(IsPotentiallyReachableTest
, OneLoopAfterTheOther2
) {
315 "declare i1 @switch()\n"
317 "define void @test() {\n"
321 " %B = bitcast i8 undef to i8\n"
322 " %x = call i1 @switch()\n"
323 " br i1 %x, label %loop1, label %loop1exit\n"
327 " %A = bitcast i8 undef to i8\n"
328 " %y = call i1 @switch()\n"
329 " br i1 %x, label %loop2, label %loop2exit\n"
336 TEST_F(IsPotentiallyReachableTest
, OneLoopAfterTheOtherInsideAThirdLoop
) {
338 "declare i1 @switch()\n"
340 "define void @test() {\n"
342 " br label %outerloop3\n"
344 " br label %innerloop1\n"
346 " %B = bitcast i8 undef to i8\n"
347 " %x = call i1 @switch()\n"
348 " br i1 %x, label %innerloop1, label %innerloop1exit\n"
350 " br label %innerloop2\n"
352 " %A = bitcast i8 undef to i8\n"
353 " %y = call i1 @switch()\n"
354 " br i1 %x, label %innerloop2, label %innerloop2exit\n"
356 " ;; In outer loop3 now.\n"
357 " %z = call i1 @switch()\n"
358 " br i1 %z, label %outerloop3, label %exit\n"
365 static const char *BranchInsideLoopIR
=
366 "declare i1 @switch()\n"
368 "define void @test() {\n"
372 " %x = call i1 @switch()\n"
373 " br i1 %x, label %nextloopblock, label %exit\n"
375 " %y = call i1 @switch()\n"
376 " br i1 %y, label %left, label %right\n"
378 " %A = bitcast i8 undef to i8\n"
381 " %B = bitcast i8 undef to i8\n"
387 TEST_F(IsPotentiallyReachableTest
, BranchInsideLoop
) {
388 ParseAssembly(BranchInsideLoopIR
);
392 TEST_F(IsPotentiallyReachableTest
, ModifyTest
) {
393 ParseAssembly(BranchInsideLoopIR
);
395 succ_iterator S
= succ_begin(&*++M
->getFunction("test")->begin());
396 BasicBlock
*OldBB
= S
[0];
403 TEST_F(IsPotentiallyReachableTest
, UnreachableFromEntryTest
) {
404 ParseAssembly("define void @test() {\n"
406 " %A = bitcast i8 undef to i8\n"
409 " %B = bitcast i8 undef to i8\n"
415 TEST_F(IsPotentiallyReachableTest
, UnreachableBlocksTest1
) {
416 ParseAssembly("define void @test() {\n"
420 " %A = bitcast i8 undef to i8\n"
421 " br label %not.reachable.2\n"
423 " %B = bitcast i8 undef to i8\n"
429 TEST_F(IsPotentiallyReachableTest
, UnreachableBlocksTest2
) {
430 ParseAssembly("define void @test() {\n"
434 " %B = bitcast i8 undef to i8\n"
435 " br label %not.reachable.2\n"
437 " %A = bitcast i8 undef to i8\n"
443 TEST_F(IsPotentiallyReachableTest
, SimpleExclusionTest
) {
444 ParseAssembly("define void @test() {\n"
446 " %A = bitcast i8 undef to i8\n"
447 " br label %excluded\n"
451 " %B = bitcast i8 undef to i8\n"
457 TEST_F(IsPotentiallyReachableTest
, DiamondExcludedTest
) {
458 ParseAssembly("declare i1 @switch()\n"
460 "define void @test() {\n"
462 " %x = call i1 @switch()\n"
463 " %A = bitcast i8 undef to i8\n"
464 " br i1 %x, label %excluded.1, label %excluded.2\n"
470 " %B = bitcast i8 undef to i8\n"
476 TEST_F(IsPotentiallyReachableTest
, DiamondOneSideExcludedTest
) {
477 ParseAssembly("declare i1 @switch()\n"
479 "define void @test() {\n"
481 " %x = call i1 @switch()\n"
482 " %A = bitcast i8 undef to i8\n"
483 " br i1 %x, label %excluded, label %diamond\n"
489 " %B = bitcast i8 undef to i8\n"
495 TEST_F(IsPotentiallyReachableTest
, UnreachableToReachable
) {
496 ParseAssembly("define void @test() {\n"
499 "unreachableblock:\n"
500 " %A = bitcast i8 undef to i8\n"
503 " %B = bitcast i8 undef to i8\n"