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/Analysis/LoopInfo.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/IR/Dominators.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/InstIterator.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/LegacyPassManager.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/SourceMgr.h"
21 #include "gtest/gtest.h"
27 // This fixture assists in running the isPotentiallyReachable utility four ways
28 // and ensuring it produces the correct answer each time.
29 class IsPotentiallyReachableTest
: public testing::Test
{
31 void ParseAssembly(const char *Assembly
) {
33 M
= parseAssemblyString(Assembly
, Error
, Context
);
36 raw_string_ostream
os(errMsg
);
39 // A failure here means that the test itself is buggy.
41 report_fatal_error(os
.str().c_str());
43 Function
*F
= M
->getFunction("test");
45 report_fatal_error("Test must have a function named @test");
48 for (inst_iterator I
= inst_begin(F
), E
= inst_end(F
); I
!= E
; ++I
) {
50 if (I
->getName() == "A")
52 else if (I
->getName() == "B")
57 report_fatal_error("@test must have an instruction %A");
59 report_fatal_error("@test must have an instruction %B");
62 void ExpectPath(bool ExpectedResult
) {
64 class IsPotentiallyReachableTestPass
: public FunctionPass
{
66 IsPotentiallyReachableTestPass(bool ExpectedResult
,
67 Instruction
*A
, Instruction
*B
)
68 : FunctionPass(ID
), ExpectedResult(ExpectedResult
), A(A
), B(B
) {}
70 static int initialize() {
71 PassInfo
*PI
= new PassInfo("isPotentiallyReachable testing pass",
72 "", &ID
, nullptr, true, true);
73 PassRegistry::getPassRegistry()->registerPass(*PI
, false);
74 initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
75 initializeDominatorTreeWrapperPassPass(
76 *PassRegistry::getPassRegistry());
80 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
82 AU
.addRequired
<LoopInfoWrapperPass
>();
83 AU
.addRequired
<DominatorTreeWrapperPass
>();
86 bool runOnFunction(Function
&F
) override
{
87 if (!F
.hasName() || F
.getName() != "test")
90 LoopInfo
*LI
= &getAnalysis
<LoopInfoWrapperPass
>().getLoopInfo();
92 &getAnalysis
<DominatorTreeWrapperPass
>().getDomTree();
93 EXPECT_EQ(isPotentiallyReachable(A
, B
, nullptr, nullptr),
95 EXPECT_EQ(isPotentiallyReachable(A
, B
, DT
, nullptr), ExpectedResult
);
96 EXPECT_EQ(isPotentiallyReachable(A
, B
, nullptr, LI
), ExpectedResult
);
97 EXPECT_EQ(isPotentiallyReachable(A
, B
, DT
, LI
), ExpectedResult
);
104 static int initialize
= IsPotentiallyReachableTestPass::initialize();
107 IsPotentiallyReachableTestPass
*P
=
108 new IsPotentiallyReachableTestPass(ExpectedResult
, A
, B
);
109 legacy::PassManager PM
;
115 std::unique_ptr
<Module
> M
;
121 TEST_F(IsPotentiallyReachableTest
, SameBlockNoPath
) {
123 "define void @test() {\n"
125 " bitcast i8 undef to i8\n"
126 " %B = bitcast i8 undef to i8\n"
127 " bitcast i8 undef to i8\n"
128 " bitcast i8 undef to i8\n"
129 " %A = bitcast i8 undef to i8\n"
135 TEST_F(IsPotentiallyReachableTest
, SameBlockPath
) {
137 "define void @test() {\n"
139 " %A = bitcast i8 undef to i8\n"
140 " bitcast i8 undef to i8\n"
141 " bitcast i8 undef to i8\n"
142 " %B = bitcast i8 undef to i8\n"
148 TEST_F(IsPotentiallyReachableTest
, SameBlockNoLoop
) {
150 "define void @test() {\n"
152 " br label %middle\n"
154 " %B = bitcast i8 undef to i8\n"
155 " bitcast i8 undef to i8\n"
156 " bitcast i8 undef to i8\n"
157 " %A = bitcast i8 undef to i8\n"
158 " br label %nextblock\n"
165 TEST_F(IsPotentiallyReachableTest
, StraightNoPath
) {
167 "define void @test() {\n"
169 " %B = bitcast i8 undef to i8\n"
172 " %A = bitcast i8 undef to i8\n"
178 TEST_F(IsPotentiallyReachableTest
, StraightPath
) {
180 "define void @test() {\n"
182 " %A = bitcast i8 undef to i8\n"
185 " %B = bitcast i8 undef to i8\n"
191 TEST_F(IsPotentiallyReachableTest
, DestUnreachable
) {
193 "define void @test() {\n"
195 " br label %midblock\n"
197 " %A = bitcast i8 undef to i8\n"
200 " %B = bitcast i8 undef to i8\n"
201 " br label %midblock\n"
206 TEST_F(IsPotentiallyReachableTest
, BranchToReturn
) {
208 "define void @test(i1 %x) {\n"
210 " %A = bitcast i8 undef to i8\n"
211 " br i1 %x, label %block1, label %block2\n"
215 " %B = bitcast i8 undef to i8\n"
221 TEST_F(IsPotentiallyReachableTest
, SimpleLoop1
) {
223 "declare i1 @switch()\n"
225 "define void @test() {\n"
229 " %B = bitcast i8 undef to i8\n"
230 " %A = bitcast i8 undef to i8\n"
231 " %x = call i1 @switch()\n"
232 " br i1 %x, label %loop, label %exit\n"
239 TEST_F(IsPotentiallyReachableTest
, SimpleLoop2
) {
241 "declare i1 @switch()\n"
243 "define void @test() {\n"
245 " %B = bitcast i8 undef to i8\n"
248 " %A = bitcast i8 undef to i8\n"
249 " %x = call i1 @switch()\n"
250 " br i1 %x, label %loop, label %exit\n"
257 TEST_F(IsPotentiallyReachableTest
, SimpleLoop3
) {
259 "declare i1 @switch()\n"
261 "define void @test() {\n"
265 " %B = bitcast i8 undef to i8\n"
266 " %x = call i1 @switch()\n"
267 " br i1 %x, label %loop, label %exit\n"
269 " %A = bitcast i8 undef to i8\n"
276 TEST_F(IsPotentiallyReachableTest
, OneLoopAfterTheOther1
) {
278 "declare i1 @switch()\n"
280 "define void @test() {\n"
284 " %A = bitcast i8 undef to i8\n"
285 " %x = call i1 @switch()\n"
286 " br i1 %x, label %loop1, label %loop1exit\n"
290 " %B = bitcast i8 undef to i8\n"
291 " %y = call i1 @switch()\n"
292 " br i1 %x, label %loop2, label %loop2exit\n"
299 TEST_F(IsPotentiallyReachableTest
, OneLoopAfterTheOther2
) {
301 "declare i1 @switch()\n"
303 "define void @test() {\n"
307 " %B = bitcast i8 undef to i8\n"
308 " %x = call i1 @switch()\n"
309 " br i1 %x, label %loop1, label %loop1exit\n"
313 " %A = bitcast i8 undef to i8\n"
314 " %y = call i1 @switch()\n"
315 " br i1 %x, label %loop2, label %loop2exit\n"
322 TEST_F(IsPotentiallyReachableTest
, OneLoopAfterTheOtherInsideAThirdLoop
) {
324 "declare i1 @switch()\n"
326 "define void @test() {\n"
328 " br label %outerloop3\n"
330 " br label %innerloop1\n"
332 " %B = bitcast i8 undef to i8\n"
333 " %x = call i1 @switch()\n"
334 " br i1 %x, label %innerloop1, label %innerloop1exit\n"
336 " br label %innerloop2\n"
338 " %A = bitcast i8 undef to i8\n"
339 " %y = call i1 @switch()\n"
340 " br i1 %x, label %innerloop2, label %innerloop2exit\n"
342 " ;; In outer loop3 now.\n"
343 " %z = call i1 @switch()\n"
344 " br i1 %z, label %outerloop3, label %exit\n"
351 static const char *BranchInsideLoopIR
=
352 "declare i1 @switch()\n"
354 "define void @test() {\n"
358 " %x = call i1 @switch()\n"
359 " br i1 %x, label %nextloopblock, label %exit\n"
361 " %y = call i1 @switch()\n"
362 " br i1 %y, label %left, label %right\n"
364 " %A = bitcast i8 undef to i8\n"
367 " %B = bitcast i8 undef to i8\n"
373 TEST_F(IsPotentiallyReachableTest
, BranchInsideLoop
) {
374 ParseAssembly(BranchInsideLoopIR
);
378 TEST_F(IsPotentiallyReachableTest
, ModifyTest
) {
379 ParseAssembly(BranchInsideLoopIR
);
381 succ_iterator S
= succ_begin(&*++M
->getFunction("test")->begin());
382 BasicBlock
*OldBB
= S
[0];