annotate llvm/unittests/Analysis/CFGTest.cpp @ 180:680fa57a2f20

fix compile errors.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 30 May 2020 17:44:06 +0900
parents 1d019706d866
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- CFGTest.cpp - CFG tests --------------------------------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "llvm/Analysis/CFG.h"
anatofuz
parents:
diff changeset
10 #include "llvm/ADT/SmallPtrSet.h"
anatofuz
parents:
diff changeset
11 #include "llvm/Analysis/LoopInfo.h"
anatofuz
parents:
diff changeset
12 #include "llvm/AsmParser/Parser.h"
anatofuz
parents:
diff changeset
13 #include "llvm/IR/Dominators.h"
anatofuz
parents:
diff changeset
14 #include "llvm/IR/Function.h"
anatofuz
parents:
diff changeset
15 #include "llvm/IR/InstIterator.h"
anatofuz
parents:
diff changeset
16 #include "llvm/IR/LLVMContext.h"
anatofuz
parents:
diff changeset
17 #include "llvm/IR/LegacyPassManager.h"
anatofuz
parents:
diff changeset
18 #include "llvm/IR/Module.h"
anatofuz
parents:
diff changeset
19 #include "llvm/InitializePasses.h"
anatofuz
parents:
diff changeset
20 #include "llvm/Support/ErrorHandling.h"
anatofuz
parents:
diff changeset
21 #include "llvm/Support/SourceMgr.h"
anatofuz
parents:
diff changeset
22 #include "gtest/gtest.h"
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 using namespace llvm;
anatofuz
parents:
diff changeset
25
anatofuz
parents:
diff changeset
26 namespace {
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 // This fixture assists in running the isPotentiallyReachable utility four ways
anatofuz
parents:
diff changeset
29 // and ensuring it produces the correct answer each time.
anatofuz
parents:
diff changeset
30 class IsPotentiallyReachableTest : public testing::Test {
anatofuz
parents:
diff changeset
31 protected:
anatofuz
parents:
diff changeset
32 void ParseAssembly(const char *Assembly) {
anatofuz
parents:
diff changeset
33 SMDiagnostic Error;
anatofuz
parents:
diff changeset
34 M = parseAssemblyString(Assembly, Error, Context);
anatofuz
parents:
diff changeset
35
anatofuz
parents:
diff changeset
36 std::string errMsg;
anatofuz
parents:
diff changeset
37 raw_string_ostream os(errMsg);
anatofuz
parents:
diff changeset
38 Error.print("", os);
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40 // A failure here means that the test itself is buggy.
anatofuz
parents:
diff changeset
41 if (!M)
anatofuz
parents:
diff changeset
42 report_fatal_error(os.str().c_str());
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 Function *F = M->getFunction("test");
anatofuz
parents:
diff changeset
45 if (F == nullptr)
anatofuz
parents:
diff changeset
46 report_fatal_error("Test must have a function named @test");
anatofuz
parents:
diff changeset
47
anatofuz
parents:
diff changeset
48 A = B = nullptr;
anatofuz
parents:
diff changeset
49 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
anatofuz
parents:
diff changeset
50 if (I->hasName()) {
anatofuz
parents:
diff changeset
51 if (I->getName() == "A")
anatofuz
parents:
diff changeset
52 A = &*I;
anatofuz
parents:
diff changeset
53 else if (I->getName() == "B")
anatofuz
parents:
diff changeset
54 B = &*I;
anatofuz
parents:
diff changeset
55 }
anatofuz
parents:
diff changeset
56 }
anatofuz
parents:
diff changeset
57 if (A == nullptr)
anatofuz
parents:
diff changeset
58 report_fatal_error("@test must have an instruction %A");
anatofuz
parents:
diff changeset
59 if (B == nullptr)
anatofuz
parents:
diff changeset
60 report_fatal_error("@test must have an instruction %B");
anatofuz
parents:
diff changeset
61
anatofuz
parents:
diff changeset
62 assert(ExclusionSet.empty());
anatofuz
parents:
diff changeset
63 for (auto I = F->begin(), E = F->end(); I != E; ++I) {
anatofuz
parents:
diff changeset
64 if (I->hasName() && I->getName().startswith("excluded"))
anatofuz
parents:
diff changeset
65 ExclusionSet.insert(&*I);
anatofuz
parents:
diff changeset
66 }
anatofuz
parents:
diff changeset
67 }
anatofuz
parents:
diff changeset
68
anatofuz
parents:
diff changeset
69 void ExpectPath(bool ExpectedResult) {
anatofuz
parents:
diff changeset
70 static char ID;
anatofuz
parents:
diff changeset
71 class IsPotentiallyReachableTestPass : public FunctionPass {
anatofuz
parents:
diff changeset
72 public:
anatofuz
parents:
diff changeset
73 IsPotentiallyReachableTestPass(bool ExpectedResult, Instruction *A,
anatofuz
parents:
diff changeset
74 Instruction *B,
anatofuz
parents:
diff changeset
75 SmallPtrSet<BasicBlock *, 4> ExclusionSet)
anatofuz
parents:
diff changeset
76 : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B),
anatofuz
parents:
diff changeset
77 ExclusionSet(ExclusionSet) {}
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 static int initialize() {
anatofuz
parents:
diff changeset
80 PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass", "",
anatofuz
parents:
diff changeset
81 &ID, nullptr, true, true);
anatofuz
parents:
diff changeset
82 PassRegistry::getPassRegistry()->registerPass(*PI, false);
anatofuz
parents:
diff changeset
83 initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
anatofuz
parents:
diff changeset
84 initializeDominatorTreeWrapperPassPass(
anatofuz
parents:
diff changeset
85 *PassRegistry::getPassRegistry());
anatofuz
parents:
diff changeset
86 return 0;
anatofuz
parents:
diff changeset
87 }
anatofuz
parents:
diff changeset
88
anatofuz
parents:
diff changeset
89 void getAnalysisUsage(AnalysisUsage &AU) const override {
anatofuz
parents:
diff changeset
90 AU.setPreservesAll();
anatofuz
parents:
diff changeset
91 AU.addRequired<LoopInfoWrapperPass>();
anatofuz
parents:
diff changeset
92 AU.addRequired<DominatorTreeWrapperPass>();
anatofuz
parents:
diff changeset
93 }
anatofuz
parents:
diff changeset
94
anatofuz
parents:
diff changeset
95 bool runOnFunction(Function &F) override {
anatofuz
parents:
diff changeset
96 if (!F.hasName() || F.getName() != "test")
anatofuz
parents:
diff changeset
97 return false;
anatofuz
parents:
diff changeset
98
anatofuz
parents:
diff changeset
99 LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
anatofuz
parents:
diff changeset
100 DominatorTree *DT =
anatofuz
parents:
diff changeset
101 &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
anatofuz
parents:
diff changeset
102 EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, nullptr, nullptr),
anatofuz
parents:
diff changeset
103 ExpectedResult);
anatofuz
parents:
diff changeset
104 EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, DT, nullptr),
anatofuz
parents:
diff changeset
105 ExpectedResult);
anatofuz
parents:
diff changeset
106 EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, nullptr, LI),
anatofuz
parents:
diff changeset
107 ExpectedResult);
anatofuz
parents:
diff changeset
108 EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, DT, LI),
anatofuz
parents:
diff changeset
109 ExpectedResult);
anatofuz
parents:
diff changeset
110 return false;
anatofuz
parents:
diff changeset
111 }
anatofuz
parents:
diff changeset
112 bool ExpectedResult;
anatofuz
parents:
diff changeset
113 Instruction *A, *B;
anatofuz
parents:
diff changeset
114 SmallPtrSet<BasicBlock *, 4> ExclusionSet;
anatofuz
parents:
diff changeset
115 };
anatofuz
parents:
diff changeset
116
anatofuz
parents:
diff changeset
117 static int initialize = IsPotentiallyReachableTestPass::initialize();
anatofuz
parents:
diff changeset
118 (void)initialize;
anatofuz
parents:
diff changeset
119
anatofuz
parents:
diff changeset
120 IsPotentiallyReachableTestPass *P =
anatofuz
parents:
diff changeset
121 new IsPotentiallyReachableTestPass(ExpectedResult, A, B, ExclusionSet);
anatofuz
parents:
diff changeset
122 legacy::PassManager PM;
anatofuz
parents:
diff changeset
123 PM.add(P);
anatofuz
parents:
diff changeset
124 PM.run(*M);
anatofuz
parents:
diff changeset
125 }
anatofuz
parents:
diff changeset
126
anatofuz
parents:
diff changeset
127 LLVMContext Context;
anatofuz
parents:
diff changeset
128 std::unique_ptr<Module> M;
anatofuz
parents:
diff changeset
129 Instruction *A, *B;
anatofuz
parents:
diff changeset
130 SmallPtrSet<BasicBlock *, 4> ExclusionSet;
anatofuz
parents:
diff changeset
131 };
anatofuz
parents:
diff changeset
132
anatofuz
parents:
diff changeset
133 }
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 TEST_F(IsPotentiallyReachableTest, SameBlockNoPath) {
anatofuz
parents:
diff changeset
136 ParseAssembly(
anatofuz
parents:
diff changeset
137 "define void @test() {\n"
anatofuz
parents:
diff changeset
138 "entry:\n"
anatofuz
parents:
diff changeset
139 " bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
140 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
141 " bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
142 " bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
143 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
144 " ret void\n"
anatofuz
parents:
diff changeset
145 "}\n");
anatofuz
parents:
diff changeset
146 ExpectPath(false);
anatofuz
parents:
diff changeset
147 }
anatofuz
parents:
diff changeset
148
anatofuz
parents:
diff changeset
149 TEST_F(IsPotentiallyReachableTest, SameBlockPath) {
anatofuz
parents:
diff changeset
150 ParseAssembly(
anatofuz
parents:
diff changeset
151 "define void @test() {\n"
anatofuz
parents:
diff changeset
152 "entry:\n"
anatofuz
parents:
diff changeset
153 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
154 " bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
155 " bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
156 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
157 " ret void\n"
anatofuz
parents:
diff changeset
158 "}\n");
anatofuz
parents:
diff changeset
159 ExpectPath(true);
anatofuz
parents:
diff changeset
160 }
anatofuz
parents:
diff changeset
161
anatofuz
parents:
diff changeset
162 TEST_F(IsPotentiallyReachableTest, SameBlockNoLoop) {
anatofuz
parents:
diff changeset
163 ParseAssembly(
anatofuz
parents:
diff changeset
164 "define void @test() {\n"
anatofuz
parents:
diff changeset
165 "entry:\n"
anatofuz
parents:
diff changeset
166 " br label %middle\n"
anatofuz
parents:
diff changeset
167 "middle:\n"
anatofuz
parents:
diff changeset
168 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
169 " bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
170 " bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
171 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
172 " br label %nextblock\n"
anatofuz
parents:
diff changeset
173 "nextblock:\n"
anatofuz
parents:
diff changeset
174 " ret void\n"
anatofuz
parents:
diff changeset
175 "}\n");
anatofuz
parents:
diff changeset
176 ExpectPath(false);
anatofuz
parents:
diff changeset
177 }
anatofuz
parents:
diff changeset
178
anatofuz
parents:
diff changeset
179 TEST_F(IsPotentiallyReachableTest, StraightNoPath) {
anatofuz
parents:
diff changeset
180 ParseAssembly(
anatofuz
parents:
diff changeset
181 "define void @test() {\n"
anatofuz
parents:
diff changeset
182 "entry:\n"
anatofuz
parents:
diff changeset
183 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
184 " br label %exit\n"
anatofuz
parents:
diff changeset
185 "exit:\n"
anatofuz
parents:
diff changeset
186 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
187 " ret void\n"
anatofuz
parents:
diff changeset
188 "}");
anatofuz
parents:
diff changeset
189 ExpectPath(false);
anatofuz
parents:
diff changeset
190 }
anatofuz
parents:
diff changeset
191
anatofuz
parents:
diff changeset
192 TEST_F(IsPotentiallyReachableTest, StraightPath) {
anatofuz
parents:
diff changeset
193 ParseAssembly(
anatofuz
parents:
diff changeset
194 "define void @test() {\n"
anatofuz
parents:
diff changeset
195 "entry:\n"
anatofuz
parents:
diff changeset
196 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
197 " br label %exit\n"
anatofuz
parents:
diff changeset
198 "exit:\n"
anatofuz
parents:
diff changeset
199 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
200 " ret void\n"
anatofuz
parents:
diff changeset
201 "}");
anatofuz
parents:
diff changeset
202 ExpectPath(true);
anatofuz
parents:
diff changeset
203 }
anatofuz
parents:
diff changeset
204
anatofuz
parents:
diff changeset
205 TEST_F(IsPotentiallyReachableTest, DestUnreachable) {
anatofuz
parents:
diff changeset
206 ParseAssembly(
anatofuz
parents:
diff changeset
207 "define void @test() {\n"
anatofuz
parents:
diff changeset
208 "entry:\n"
anatofuz
parents:
diff changeset
209 " br label %midblock\n"
anatofuz
parents:
diff changeset
210 "midblock:\n"
anatofuz
parents:
diff changeset
211 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
212 " ret void\n"
anatofuz
parents:
diff changeset
213 "unreachable:\n"
anatofuz
parents:
diff changeset
214 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
215 " br label %midblock\n"
anatofuz
parents:
diff changeset
216 "}");
anatofuz
parents:
diff changeset
217 ExpectPath(false);
anatofuz
parents:
diff changeset
218 }
anatofuz
parents:
diff changeset
219
anatofuz
parents:
diff changeset
220 TEST_F(IsPotentiallyReachableTest, BranchToReturn) {
anatofuz
parents:
diff changeset
221 ParseAssembly(
anatofuz
parents:
diff changeset
222 "define void @test(i1 %x) {\n"
anatofuz
parents:
diff changeset
223 "entry:\n"
anatofuz
parents:
diff changeset
224 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
225 " br i1 %x, label %block1, label %block2\n"
anatofuz
parents:
diff changeset
226 "block1:\n"
anatofuz
parents:
diff changeset
227 " ret void\n"
anatofuz
parents:
diff changeset
228 "block2:\n"
anatofuz
parents:
diff changeset
229 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
230 " ret void\n"
anatofuz
parents:
diff changeset
231 "}");
anatofuz
parents:
diff changeset
232 ExpectPath(true);
anatofuz
parents:
diff changeset
233 }
anatofuz
parents:
diff changeset
234
anatofuz
parents:
diff changeset
235 TEST_F(IsPotentiallyReachableTest, SimpleLoop1) {
anatofuz
parents:
diff changeset
236 ParseAssembly(
anatofuz
parents:
diff changeset
237 "declare i1 @switch()\n"
anatofuz
parents:
diff changeset
238 "\n"
anatofuz
parents:
diff changeset
239 "define void @test() {\n"
anatofuz
parents:
diff changeset
240 "entry:\n"
anatofuz
parents:
diff changeset
241 " br label %loop\n"
anatofuz
parents:
diff changeset
242 "loop:\n"
anatofuz
parents:
diff changeset
243 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
244 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
245 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
246 " br i1 %x, label %loop, label %exit\n"
anatofuz
parents:
diff changeset
247 "exit:\n"
anatofuz
parents:
diff changeset
248 " ret void\n"
anatofuz
parents:
diff changeset
249 "}");
anatofuz
parents:
diff changeset
250 ExpectPath(true);
anatofuz
parents:
diff changeset
251 }
anatofuz
parents:
diff changeset
252
anatofuz
parents:
diff changeset
253 TEST_F(IsPotentiallyReachableTest, SimpleLoop2) {
anatofuz
parents:
diff changeset
254 ParseAssembly(
anatofuz
parents:
diff changeset
255 "declare i1 @switch()\n"
anatofuz
parents:
diff changeset
256 "\n"
anatofuz
parents:
diff changeset
257 "define void @test() {\n"
anatofuz
parents:
diff changeset
258 "entry:\n"
anatofuz
parents:
diff changeset
259 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
260 " br label %loop\n"
anatofuz
parents:
diff changeset
261 "loop:\n"
anatofuz
parents:
diff changeset
262 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
263 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
264 " br i1 %x, label %loop, label %exit\n"
anatofuz
parents:
diff changeset
265 "exit:\n"
anatofuz
parents:
diff changeset
266 " ret void\n"
anatofuz
parents:
diff changeset
267 "}");
anatofuz
parents:
diff changeset
268 ExpectPath(false);
anatofuz
parents:
diff changeset
269 }
anatofuz
parents:
diff changeset
270
anatofuz
parents:
diff changeset
271 TEST_F(IsPotentiallyReachableTest, SimpleLoop3) {
anatofuz
parents:
diff changeset
272 ParseAssembly(
anatofuz
parents:
diff changeset
273 "declare i1 @switch()\n"
anatofuz
parents:
diff changeset
274 "\n"
anatofuz
parents:
diff changeset
275 "define void @test() {\n"
anatofuz
parents:
diff changeset
276 "entry:\n"
anatofuz
parents:
diff changeset
277 " br label %loop\n"
anatofuz
parents:
diff changeset
278 "loop:\n"
anatofuz
parents:
diff changeset
279 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
280 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
281 " br i1 %x, label %loop, label %exit\n"
anatofuz
parents:
diff changeset
282 "exit:\n"
anatofuz
parents:
diff changeset
283 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
284 " ret void\n"
anatofuz
parents:
diff changeset
285 "}");
anatofuz
parents:
diff changeset
286 ExpectPath(false);
anatofuz
parents:
diff changeset
287 }
anatofuz
parents:
diff changeset
288
anatofuz
parents:
diff changeset
289
anatofuz
parents:
diff changeset
290 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther1) {
anatofuz
parents:
diff changeset
291 ParseAssembly(
anatofuz
parents:
diff changeset
292 "declare i1 @switch()\n"
anatofuz
parents:
diff changeset
293 "\n"
anatofuz
parents:
diff changeset
294 "define void @test() {\n"
anatofuz
parents:
diff changeset
295 "entry:\n"
anatofuz
parents:
diff changeset
296 " br label %loop1\n"
anatofuz
parents:
diff changeset
297 "loop1:\n"
anatofuz
parents:
diff changeset
298 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
299 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
300 " br i1 %x, label %loop1, label %loop1exit\n"
anatofuz
parents:
diff changeset
301 "loop1exit:\n"
anatofuz
parents:
diff changeset
302 " br label %loop2\n"
anatofuz
parents:
diff changeset
303 "loop2:\n"
anatofuz
parents:
diff changeset
304 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
305 " %y = call i1 @switch()\n"
anatofuz
parents:
diff changeset
306 " br i1 %x, label %loop2, label %loop2exit\n"
anatofuz
parents:
diff changeset
307 "loop2exit:"
anatofuz
parents:
diff changeset
308 " ret void\n"
anatofuz
parents:
diff changeset
309 "}");
anatofuz
parents:
diff changeset
310 ExpectPath(true);
anatofuz
parents:
diff changeset
311 }
anatofuz
parents:
diff changeset
312
anatofuz
parents:
diff changeset
313 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther2) {
anatofuz
parents:
diff changeset
314 ParseAssembly(
anatofuz
parents:
diff changeset
315 "declare i1 @switch()\n"
anatofuz
parents:
diff changeset
316 "\n"
anatofuz
parents:
diff changeset
317 "define void @test() {\n"
anatofuz
parents:
diff changeset
318 "entry:\n"
anatofuz
parents:
diff changeset
319 " br label %loop1\n"
anatofuz
parents:
diff changeset
320 "loop1:\n"
anatofuz
parents:
diff changeset
321 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
322 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
323 " br i1 %x, label %loop1, label %loop1exit\n"
anatofuz
parents:
diff changeset
324 "loop1exit:\n"
anatofuz
parents:
diff changeset
325 " br label %loop2\n"
anatofuz
parents:
diff changeset
326 "loop2:\n"
anatofuz
parents:
diff changeset
327 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
328 " %y = call i1 @switch()\n"
anatofuz
parents:
diff changeset
329 " br i1 %x, label %loop2, label %loop2exit\n"
anatofuz
parents:
diff changeset
330 "loop2exit:"
anatofuz
parents:
diff changeset
331 " ret void\n"
anatofuz
parents:
diff changeset
332 "}");
anatofuz
parents:
diff changeset
333 ExpectPath(false);
anatofuz
parents:
diff changeset
334 }
anatofuz
parents:
diff changeset
335
anatofuz
parents:
diff changeset
336 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOtherInsideAThirdLoop) {
anatofuz
parents:
diff changeset
337 ParseAssembly(
anatofuz
parents:
diff changeset
338 "declare i1 @switch()\n"
anatofuz
parents:
diff changeset
339 "\n"
anatofuz
parents:
diff changeset
340 "define void @test() {\n"
anatofuz
parents:
diff changeset
341 "entry:\n"
anatofuz
parents:
diff changeset
342 " br label %outerloop3\n"
anatofuz
parents:
diff changeset
343 "outerloop3:\n"
anatofuz
parents:
diff changeset
344 " br label %innerloop1\n"
anatofuz
parents:
diff changeset
345 "innerloop1:\n"
anatofuz
parents:
diff changeset
346 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
347 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
348 " br i1 %x, label %innerloop1, label %innerloop1exit\n"
anatofuz
parents:
diff changeset
349 "innerloop1exit:\n"
anatofuz
parents:
diff changeset
350 " br label %innerloop2\n"
anatofuz
parents:
diff changeset
351 "innerloop2:\n"
anatofuz
parents:
diff changeset
352 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
353 " %y = call i1 @switch()\n"
anatofuz
parents:
diff changeset
354 " br i1 %x, label %innerloop2, label %innerloop2exit\n"
anatofuz
parents:
diff changeset
355 "innerloop2exit:"
anatofuz
parents:
diff changeset
356 " ;; In outer loop3 now.\n"
anatofuz
parents:
diff changeset
357 " %z = call i1 @switch()\n"
anatofuz
parents:
diff changeset
358 " br i1 %z, label %outerloop3, label %exit\n"
anatofuz
parents:
diff changeset
359 "exit:\n"
anatofuz
parents:
diff changeset
360 " ret void\n"
anatofuz
parents:
diff changeset
361 "}");
anatofuz
parents:
diff changeset
362 ExpectPath(true);
anatofuz
parents:
diff changeset
363 }
anatofuz
parents:
diff changeset
364
anatofuz
parents:
diff changeset
365 static const char *BranchInsideLoopIR =
anatofuz
parents:
diff changeset
366 "declare i1 @switch()\n"
anatofuz
parents:
diff changeset
367 "\n"
anatofuz
parents:
diff changeset
368 "define void @test() {\n"
anatofuz
parents:
diff changeset
369 "entry:\n"
anatofuz
parents:
diff changeset
370 " br label %loop\n"
anatofuz
parents:
diff changeset
371 "loop:\n"
anatofuz
parents:
diff changeset
372 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
373 " br i1 %x, label %nextloopblock, label %exit\n"
anatofuz
parents:
diff changeset
374 "nextloopblock:\n"
anatofuz
parents:
diff changeset
375 " %y = call i1 @switch()\n"
anatofuz
parents:
diff changeset
376 " br i1 %y, label %left, label %right\n"
anatofuz
parents:
diff changeset
377 "left:\n"
anatofuz
parents:
diff changeset
378 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
379 " br label %loop\n"
anatofuz
parents:
diff changeset
380 "right:\n"
anatofuz
parents:
diff changeset
381 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
382 " br label %loop\n"
anatofuz
parents:
diff changeset
383 "exit:\n"
anatofuz
parents:
diff changeset
384 " ret void\n"
anatofuz
parents:
diff changeset
385 "}";
anatofuz
parents:
diff changeset
386
anatofuz
parents:
diff changeset
387 TEST_F(IsPotentiallyReachableTest, BranchInsideLoop) {
anatofuz
parents:
diff changeset
388 ParseAssembly(BranchInsideLoopIR);
anatofuz
parents:
diff changeset
389 ExpectPath(true);
anatofuz
parents:
diff changeset
390 }
anatofuz
parents:
diff changeset
391
anatofuz
parents:
diff changeset
392 TEST_F(IsPotentiallyReachableTest, ModifyTest) {
anatofuz
parents:
diff changeset
393 ParseAssembly(BranchInsideLoopIR);
anatofuz
parents:
diff changeset
394
anatofuz
parents:
diff changeset
395 succ_iterator S = succ_begin(&*++M->getFunction("test")->begin());
anatofuz
parents:
diff changeset
396 BasicBlock *OldBB = S[0];
anatofuz
parents:
diff changeset
397 S[0] = S[1];
anatofuz
parents:
diff changeset
398 ExpectPath(false);
anatofuz
parents:
diff changeset
399 S[0] = OldBB;
anatofuz
parents:
diff changeset
400 ExpectPath(true);
anatofuz
parents:
diff changeset
401 }
anatofuz
parents:
diff changeset
402
anatofuz
parents:
diff changeset
403 TEST_F(IsPotentiallyReachableTest, UnreachableFromEntryTest) {
anatofuz
parents:
diff changeset
404 ParseAssembly("define void @test() {\n"
anatofuz
parents:
diff changeset
405 "entry:\n"
anatofuz
parents:
diff changeset
406 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
407 " ret void\n"
anatofuz
parents:
diff changeset
408 "not.reachable:\n"
anatofuz
parents:
diff changeset
409 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
410 " ret void\n"
anatofuz
parents:
diff changeset
411 "}");
anatofuz
parents:
diff changeset
412 ExpectPath(false);
anatofuz
parents:
diff changeset
413 }
anatofuz
parents:
diff changeset
414
anatofuz
parents:
diff changeset
415 TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest1) {
anatofuz
parents:
diff changeset
416 ParseAssembly("define void @test() {\n"
anatofuz
parents:
diff changeset
417 "entry:\n"
anatofuz
parents:
diff changeset
418 " ret void\n"
anatofuz
parents:
diff changeset
419 "not.reachable.1:\n"
anatofuz
parents:
diff changeset
420 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
421 " br label %not.reachable.2\n"
anatofuz
parents:
diff changeset
422 "not.reachable.2:\n"
anatofuz
parents:
diff changeset
423 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
424 " ret void\n"
anatofuz
parents:
diff changeset
425 "}");
anatofuz
parents:
diff changeset
426 ExpectPath(true);
anatofuz
parents:
diff changeset
427 }
anatofuz
parents:
diff changeset
428
anatofuz
parents:
diff changeset
429 TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest2) {
anatofuz
parents:
diff changeset
430 ParseAssembly("define void @test() {\n"
anatofuz
parents:
diff changeset
431 "entry:\n"
anatofuz
parents:
diff changeset
432 " ret void\n"
anatofuz
parents:
diff changeset
433 "not.reachable.1:\n"
anatofuz
parents:
diff changeset
434 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
435 " br label %not.reachable.2\n"
anatofuz
parents:
diff changeset
436 "not.reachable.2:\n"
anatofuz
parents:
diff changeset
437 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
438 " ret void\n"
anatofuz
parents:
diff changeset
439 "}");
anatofuz
parents:
diff changeset
440 ExpectPath(false);
anatofuz
parents:
diff changeset
441 }
anatofuz
parents:
diff changeset
442
anatofuz
parents:
diff changeset
443 TEST_F(IsPotentiallyReachableTest, SimpleExclusionTest) {
anatofuz
parents:
diff changeset
444 ParseAssembly("define void @test() {\n"
anatofuz
parents:
diff changeset
445 "entry:\n"
anatofuz
parents:
diff changeset
446 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
447 " br label %excluded\n"
anatofuz
parents:
diff changeset
448 "excluded:\n"
anatofuz
parents:
diff changeset
449 " br label %exit\n"
anatofuz
parents:
diff changeset
450 "exit:\n"
anatofuz
parents:
diff changeset
451 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
452 " ret void\n"
anatofuz
parents:
diff changeset
453 "}");
anatofuz
parents:
diff changeset
454 ExpectPath(false);
anatofuz
parents:
diff changeset
455 }
anatofuz
parents:
diff changeset
456
anatofuz
parents:
diff changeset
457 TEST_F(IsPotentiallyReachableTest, DiamondExcludedTest) {
anatofuz
parents:
diff changeset
458 ParseAssembly("declare i1 @switch()\n"
anatofuz
parents:
diff changeset
459 "\n"
anatofuz
parents:
diff changeset
460 "define void @test() {\n"
anatofuz
parents:
diff changeset
461 "entry:\n"
anatofuz
parents:
diff changeset
462 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
463 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
464 " br i1 %x, label %excluded.1, label %excluded.2\n"
anatofuz
parents:
diff changeset
465 "excluded.1:\n"
anatofuz
parents:
diff changeset
466 " br label %exit\n"
anatofuz
parents:
diff changeset
467 "excluded.2:\n"
anatofuz
parents:
diff changeset
468 " br label %exit\n"
anatofuz
parents:
diff changeset
469 "exit:\n"
anatofuz
parents:
diff changeset
470 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
471 " ret void\n"
anatofuz
parents:
diff changeset
472 "}");
anatofuz
parents:
diff changeset
473 ExpectPath(false);
anatofuz
parents:
diff changeset
474 }
anatofuz
parents:
diff changeset
475
anatofuz
parents:
diff changeset
476 TEST_F(IsPotentiallyReachableTest, DiamondOneSideExcludedTest) {
anatofuz
parents:
diff changeset
477 ParseAssembly("declare i1 @switch()\n"
anatofuz
parents:
diff changeset
478 "\n"
anatofuz
parents:
diff changeset
479 "define void @test() {\n"
anatofuz
parents:
diff changeset
480 "entry:\n"
anatofuz
parents:
diff changeset
481 " %x = call i1 @switch()\n"
anatofuz
parents:
diff changeset
482 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
483 " br i1 %x, label %excluded, label %diamond\n"
anatofuz
parents:
diff changeset
484 "excluded:\n"
anatofuz
parents:
diff changeset
485 " br label %exit\n"
anatofuz
parents:
diff changeset
486 "diamond:\n"
anatofuz
parents:
diff changeset
487 " br label %exit\n"
anatofuz
parents:
diff changeset
488 "exit:\n"
anatofuz
parents:
diff changeset
489 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
490 " ret void\n"
anatofuz
parents:
diff changeset
491 "}");
anatofuz
parents:
diff changeset
492 ExpectPath(true);
anatofuz
parents:
diff changeset
493 }
anatofuz
parents:
diff changeset
494
anatofuz
parents:
diff changeset
495 TEST_F(IsPotentiallyReachableTest, UnreachableToReachable) {
anatofuz
parents:
diff changeset
496 ParseAssembly("define void @test() {\n"
anatofuz
parents:
diff changeset
497 "entry:\n"
anatofuz
parents:
diff changeset
498 " br label %exit\n"
anatofuz
parents:
diff changeset
499 "unreachableblock:\n"
anatofuz
parents:
diff changeset
500 " %A = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
501 " br label %exit\n"
anatofuz
parents:
diff changeset
502 "exit:\n"
anatofuz
parents:
diff changeset
503 " %B = bitcast i8 undef to i8\n"
anatofuz
parents:
diff changeset
504 " ret void\n"
anatofuz
parents:
diff changeset
505 "}");
anatofuz
parents:
diff changeset
506 ExpectPath(true);
anatofuz
parents:
diff changeset
507 }