blob: 5856d5539a09ddb306d8dc71f032b91ecfd73b25 [file] [log] [blame]
NAKAMURA Takumiafda71e2013-01-23 08:30:10 +00001//===- llvm/unittests/IR/DominatorTreeTest.cpp - Constants unit tests -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Jakub Kuderski23497b42017-07-14 22:24:15 +000010#include <random>
Diego Novilloee592422013-12-02 14:08:27 +000011#include "llvm/Analysis/PostDominators.h"
Chandler Carruth9aca9182014-01-07 12:34:26 +000012#include "llvm/AsmParser/Parser.h"
Daniel Berlin8f8174c2015-04-14 19:49:26 +000013#include "llvm/IR/Constants.h"
Adam Nemet7fa6dee2017-05-27 04:05:50 +000014#include "llvm/IR/Dominators.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000015#include "llvm/IR/Instructions.h"
16#include "llvm/IR/LLVMContext.h"
Adam Nemet7fa6dee2017-05-27 04:05:50 +000017#include "llvm/IR/Module.h"
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000018#include "llvm/Support/SourceMgr.h"
Jakub Kuderski13e9ef12017-07-14 21:17:33 +000019#include "CFGBuilder.h"
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000020#include "gtest/gtest.h"
21
22using namespace llvm;
23
Jakub Kuderskib292c222017-07-14 18:26:09 +000024struct PostDomTree : PostDomTreeBase<BasicBlock> {
25 PostDomTree(Function &F) { recalculate(F); }
26};
27
Adam Nemet147ede92017-05-27 04:05:52 +000028/// Build the dominator tree for the function and run the Test.
Jakub Kuderskib292c222017-07-14 18:26:09 +000029static void runWithDomTree(
30 Module &M, StringRef FuncName,
31 function_ref<void(Function &F, DominatorTree *DT, PostDomTree *PDT)> Test) {
Adam Nemet147ede92017-05-27 04:05:52 +000032 auto *F = M.getFunction(FuncName);
33 ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
34 // Compute the dominator tree for the function.
35 DominatorTree DT(*F);
Jakub Kuderskib292c222017-07-14 18:26:09 +000036 PostDomTree PDT(*F);
Adam Nemet147ede92017-05-27 04:05:52 +000037 Test(*F, &DT, &PDT);
38}
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000039
Adam Nemet147ede92017-05-27 04:05:52 +000040static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
41 StringRef ModuleStr) {
42 SMDiagnostic Err;
43 std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context);
44 assert(M && "Bad assembly?");
45 return M;
46}
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000047
Adam Nemet147ede92017-05-27 04:05:52 +000048TEST(DominatorTree, Unreachable) {
49 StringRef ModuleString =
Adam Nemet7fa6dee2017-05-27 04:05:50 +000050 "declare i32 @g()\n"
51 "define void @f(i32 %x) personality i32 ()* @g {\n"
52 "bb0:\n"
53 " %y1 = add i32 %x, 1\n"
54 " %y2 = add i32 %x, 1\n"
55 " %y3 = invoke i32 @g() to label %bb1 unwind label %bb2\n"
56 "bb1:\n"
57 " %y4 = add i32 %x, 1\n"
58 " br label %bb4\n"
59 "bb2:\n"
60 " %y5 = landingpad i32\n"
61 " cleanup\n"
62 " br label %bb4\n"
63 "bb3:\n"
64 " %y6 = add i32 %x, 1\n"
65 " %y7 = add i32 %x, 1\n"
66 " ret void\n"
67 "bb4:\n"
68 " %y8 = phi i32 [0, %bb2], [%y4, %bb1]\n"
69 " %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n"
70 " ret void\n"
71 "}\n";
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000072
Adam Nemet147ede92017-05-27 04:05:52 +000073 // Parse the module.
Adam Nemet7fa6dee2017-05-27 04:05:50 +000074 LLVMContext Context;
Adam Nemet147ede92017-05-27 04:05:52 +000075 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
Adam Nemet7fa6dee2017-05-27 04:05:50 +000076
Adam Nemet147ede92017-05-27 04:05:52 +000077 runWithDomTree(
Jakub Kuderskib292c222017-07-14 18:26:09 +000078 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
Adam Nemet147ede92017-05-27 04:05:52 +000079 Function::iterator FI = F.begin();
80
81 BasicBlock *BB0 = &*FI++;
82 BasicBlock::iterator BBI = BB0->begin();
83 Instruction *Y1 = &*BBI++;
84 Instruction *Y2 = &*BBI++;
85 Instruction *Y3 = &*BBI++;
86
87 BasicBlock *BB1 = &*FI++;
88 BBI = BB1->begin();
89 Instruction *Y4 = &*BBI++;
90
91 BasicBlock *BB2 = &*FI++;
92 BBI = BB2->begin();
93 Instruction *Y5 = &*BBI++;
94
95 BasicBlock *BB3 = &*FI++;
96 BBI = BB3->begin();
97 Instruction *Y6 = &*BBI++;
98 Instruction *Y7 = &*BBI++;
99
100 BasicBlock *BB4 = &*FI++;
101 BBI = BB4->begin();
102 Instruction *Y8 = &*BBI++;
103 Instruction *Y9 = &*BBI++;
104
105 // Reachability
106 EXPECT_TRUE(DT->isReachableFromEntry(BB0));
107 EXPECT_TRUE(DT->isReachableFromEntry(BB1));
108 EXPECT_TRUE(DT->isReachableFromEntry(BB2));
109 EXPECT_FALSE(DT->isReachableFromEntry(BB3));
110 EXPECT_TRUE(DT->isReachableFromEntry(BB4));
111
112 // BB dominance
113 EXPECT_TRUE(DT->dominates(BB0, BB0));
114 EXPECT_TRUE(DT->dominates(BB0, BB1));
115 EXPECT_TRUE(DT->dominates(BB0, BB2));
116 EXPECT_TRUE(DT->dominates(BB0, BB3));
117 EXPECT_TRUE(DT->dominates(BB0, BB4));
118
119 EXPECT_FALSE(DT->dominates(BB1, BB0));
120 EXPECT_TRUE(DT->dominates(BB1, BB1));
121 EXPECT_FALSE(DT->dominates(BB1, BB2));
122 EXPECT_TRUE(DT->dominates(BB1, BB3));
123 EXPECT_FALSE(DT->dominates(BB1, BB4));
124
125 EXPECT_FALSE(DT->dominates(BB2, BB0));
126 EXPECT_FALSE(DT->dominates(BB2, BB1));
127 EXPECT_TRUE(DT->dominates(BB2, BB2));
128 EXPECT_TRUE(DT->dominates(BB2, BB3));
129 EXPECT_FALSE(DT->dominates(BB2, BB4));
130
131 EXPECT_FALSE(DT->dominates(BB3, BB0));
132 EXPECT_FALSE(DT->dominates(BB3, BB1));
133 EXPECT_FALSE(DT->dominates(BB3, BB2));
134 EXPECT_TRUE(DT->dominates(BB3, BB3));
135 EXPECT_FALSE(DT->dominates(BB3, BB4));
136
137 // BB proper dominance
138 EXPECT_FALSE(DT->properlyDominates(BB0, BB0));
139 EXPECT_TRUE(DT->properlyDominates(BB0, BB1));
140 EXPECT_TRUE(DT->properlyDominates(BB0, BB2));
141 EXPECT_TRUE(DT->properlyDominates(BB0, BB3));
142
143 EXPECT_FALSE(DT->properlyDominates(BB1, BB0));
144 EXPECT_FALSE(DT->properlyDominates(BB1, BB1));
145 EXPECT_FALSE(DT->properlyDominates(BB1, BB2));
146 EXPECT_TRUE(DT->properlyDominates(BB1, BB3));
147
148 EXPECT_FALSE(DT->properlyDominates(BB2, BB0));
149 EXPECT_FALSE(DT->properlyDominates(BB2, BB1));
150 EXPECT_FALSE(DT->properlyDominates(BB2, BB2));
151 EXPECT_TRUE(DT->properlyDominates(BB2, BB3));
152
153 EXPECT_FALSE(DT->properlyDominates(BB3, BB0));
154 EXPECT_FALSE(DT->properlyDominates(BB3, BB1));
155 EXPECT_FALSE(DT->properlyDominates(BB3, BB2));
156 EXPECT_FALSE(DT->properlyDominates(BB3, BB3));
157
158 // Instruction dominance in the same reachable BB
159 EXPECT_FALSE(DT->dominates(Y1, Y1));
160 EXPECT_TRUE(DT->dominates(Y1, Y2));
161 EXPECT_FALSE(DT->dominates(Y2, Y1));
162 EXPECT_FALSE(DT->dominates(Y2, Y2));
163
164 // Instruction dominance in the same unreachable BB
165 EXPECT_TRUE(DT->dominates(Y6, Y6));
166 EXPECT_TRUE(DT->dominates(Y6, Y7));
167 EXPECT_TRUE(DT->dominates(Y7, Y6));
168 EXPECT_TRUE(DT->dominates(Y7, Y7));
169
170 // Invoke
171 EXPECT_TRUE(DT->dominates(Y3, Y4));
172 EXPECT_FALSE(DT->dominates(Y3, Y5));
173
174 // Phi
175 EXPECT_TRUE(DT->dominates(Y2, Y9));
176 EXPECT_FALSE(DT->dominates(Y3, Y9));
177 EXPECT_FALSE(DT->dominates(Y8, Y9));
178
179 // Anything dominates unreachable
180 EXPECT_TRUE(DT->dominates(Y1, Y6));
181 EXPECT_TRUE(DT->dominates(Y3, Y6));
182
183 // Unreachable doesn't dominate reachable
184 EXPECT_FALSE(DT->dominates(Y6, Y1));
185
186 // Instruction, BB dominance
187 EXPECT_FALSE(DT->dominates(Y1, BB0));
188 EXPECT_TRUE(DT->dominates(Y1, BB1));
189 EXPECT_TRUE(DT->dominates(Y1, BB2));
190 EXPECT_TRUE(DT->dominates(Y1, BB3));
191 EXPECT_TRUE(DT->dominates(Y1, BB4));
192
193 EXPECT_FALSE(DT->dominates(Y3, BB0));
194 EXPECT_TRUE(DT->dominates(Y3, BB1));
195 EXPECT_FALSE(DT->dominates(Y3, BB2));
196 EXPECT_TRUE(DT->dominates(Y3, BB3));
197 EXPECT_FALSE(DT->dominates(Y3, BB4));
198
199 EXPECT_TRUE(DT->dominates(Y6, BB3));
200
201 // Post dominance.
202 EXPECT_TRUE(PDT->dominates(BB0, BB0));
203 EXPECT_FALSE(PDT->dominates(BB1, BB0));
204 EXPECT_FALSE(PDT->dominates(BB2, BB0));
205 EXPECT_FALSE(PDT->dominates(BB3, BB0));
206 EXPECT_TRUE(PDT->dominates(BB4, BB1));
207
208 // Dominance descendants.
209 SmallVector<BasicBlock *, 8> DominatedBBs, PostDominatedBBs;
210
211 DT->getDescendants(BB0, DominatedBBs);
212 PDT->getDescendants(BB0, PostDominatedBBs);
213 EXPECT_EQ(DominatedBBs.size(), 4UL);
214 EXPECT_EQ(PostDominatedBBs.size(), 1UL);
215
216 // BB3 is unreachable. It should have no dominators nor postdominators.
217 DominatedBBs.clear();
218 PostDominatedBBs.clear();
219 DT->getDescendants(BB3, DominatedBBs);
220 DT->getDescendants(BB3, PostDominatedBBs);
221 EXPECT_EQ(DominatedBBs.size(), 0UL);
222 EXPECT_EQ(PostDominatedBBs.size(), 0UL);
223
224 // Check DFS Numbers before
Jakub Kuderski837755c2017-06-30 01:28:21 +0000225 DT->updateDFSNumbers();
Adam Nemet147ede92017-05-27 04:05:52 +0000226 EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
227 EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 7UL);
228 EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
229 EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 2UL);
230 EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 5UL);
231 EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 6UL);
232 EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 3UL);
233 EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 4UL);
234
Jakub Kuderski604a22b2017-07-01 00:23:01 +0000235 // Check levels before
236 EXPECT_EQ(DT->getNode(BB0)->getLevel(), 0U);
237 EXPECT_EQ(DT->getNode(BB1)->getLevel(), 1U);
238 EXPECT_EQ(DT->getNode(BB2)->getLevel(), 1U);
239 EXPECT_EQ(DT->getNode(BB4)->getLevel(), 1U);
240
Adam Nemet147ede92017-05-27 04:05:52 +0000241 // Reattach block 3 to block 1 and recalculate
242 BB1->getTerminator()->eraseFromParent();
243 BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getContext()), BB1);
244 DT->recalculate(F);
245
246 // Check DFS Numbers after
Jakub Kuderski837755c2017-06-30 01:28:21 +0000247 DT->updateDFSNumbers();
Adam Nemet147ede92017-05-27 04:05:52 +0000248 EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
249 EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 9UL);
250 EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
251 EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 4UL);
252 EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 7UL);
253 EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 8UL);
254 EXPECT_EQ(DT->getNode(BB3)->getDFSNumIn(), 2UL);
255 EXPECT_EQ(DT->getNode(BB3)->getDFSNumOut(), 3UL);
256 EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 5UL);
257 EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 6UL);
258
Jakub Kuderski604a22b2017-07-01 00:23:01 +0000259 // Check levels after
260 EXPECT_EQ(DT->getNode(BB0)->getLevel(), 0U);
261 EXPECT_EQ(DT->getNode(BB1)->getLevel(), 1U);
262 EXPECT_EQ(DT->getNode(BB2)->getLevel(), 1U);
263 EXPECT_EQ(DT->getNode(BB3)->getLevel(), 2U);
264 EXPECT_EQ(DT->getNode(BB4)->getLevel(), 1U);
265
Adam Nemet147ede92017-05-27 04:05:52 +0000266 // Change root node
267 DT->verifyDomTree();
268 BasicBlock *NewEntry =
269 BasicBlock::Create(F.getContext(), "new_entry", &F, BB0);
270 BranchInst::Create(BB0, NewEntry);
271 EXPECT_EQ(F.begin()->getName(), NewEntry->getName());
272 EXPECT_TRUE(&F.getEntryBlock() == NewEntry);
273 DT->setNewRoot(NewEntry);
274 DT->verifyDomTree();
275 });
276}
Adam Nemet4ef096b2017-06-05 16:27:09 +0000277
278TEST(DominatorTree, NonUniqueEdges) {
279 StringRef ModuleString =
280 "define i32 @f(i32 %i, i32 *%p) {\n"
281 "bb0:\n"
282 " store i32 %i, i32 *%p\n"
283 " switch i32 %i, label %bb2 [\n"
284 " i32 0, label %bb1\n"
285 " i32 1, label %bb1\n"
286 " ]\n"
287 " bb1:\n"
288 " ret i32 1\n"
289 " bb2:\n"
290 " ret i32 4\n"
291 "}\n";
292
293 // Parse the module.
294 LLVMContext Context;
295 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
296
297 runWithDomTree(
Jakub Kuderskib292c222017-07-14 18:26:09 +0000298 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
Adam Nemet4ef096b2017-06-05 16:27:09 +0000299 Function::iterator FI = F.begin();
300
301 BasicBlock *BB0 = &*FI++;
302 BasicBlock *BB1 = &*FI++;
303 BasicBlock *BB2 = &*FI++;
304
305 const TerminatorInst *TI = BB0->getTerminator();
306 assert(TI->getNumSuccessors() == 3 && "Switch has three successors");
307
308 BasicBlockEdge Edge_BB0_BB2(BB0, TI->getSuccessor(0));
309 assert(Edge_BB0_BB2.getEnd() == BB2 &&
310 "Default label is the 1st successor");
311
312 BasicBlockEdge Edge_BB0_BB1_a(BB0, TI->getSuccessor(1));
313 assert(Edge_BB0_BB1_a.getEnd() == BB1 && "BB1 is the 2nd successor");
314
315 BasicBlockEdge Edge_BB0_BB1_b(BB0, TI->getSuccessor(2));
316 assert(Edge_BB0_BB1_b.getEnd() == BB1 && "BB1 is the 3rd successor");
317
318 EXPECT_TRUE(DT->dominates(Edge_BB0_BB2, BB2));
319 EXPECT_FALSE(DT->dominates(Edge_BB0_BB2, BB1));
320
321 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_a, BB1));
322 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_b, BB1));
323
324 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_a, BB2));
325 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_b, BB2));
326 });
327}
Jakub Kuderski13e9ef12017-07-14 21:17:33 +0000328
Tobias Grosser3d0ba4b02017-08-01 14:40:55 +0000329// Verify that the PDT is correctly updated in case an edge removal results
330// in a new unreachable CFG node.
331//
332// For the following input code and initial PDT:
333//
334// CFG PDT
335//
336// A Exit
337// | |
338// _B D
339// / | \ |
340// ^ v \ B
341// \ / D / \
342// C \ C A
343// v
344// Exit
345//
346// we verify that CFG' and PDT-updated is obtained after removal of edge C -> B.
347//
348// CFG' PDT-updated
349//
350// A Exit
351// | |
352// B D
353// | \ |
354// v \ B
355// / D \
356// C \ A
357// | v
358// unreachable Exit
359//
360// WARNING: PDT-updated is inconsistent with PDT-recalculated, which is
361// constructed from CFG' when recalculating the PDT from scratch.
362//
363// PDT-recalculated
364//
365// Exit
366// / | \
367// C B D
368// |
369// A
370//
371// TODO: document the wanted behavior after resolving this inconsistency.
372TEST(DominatorTree, DeletingEdgesIntroducesUnreachables) {
373 StringRef ModuleString =
374 "define void @f() {\n"
375 "A:\n"
376 " br label %B\n"
377 "B:\n"
378 " br i1 undef, label %D, label %C\n"
379 "C:\n"
380 " br label %B\n"
381 "D:\n"
382 " ret void\n"
383 "}\n";
384
385 // Parse the module.
386 LLVMContext Context;
387 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
388
389 runWithDomTree(
390 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
391 Function::iterator FI = F.begin();
392
393 FI++;
394 BasicBlock *B = &*FI++;
395 BasicBlock *C = &*FI++;
396 BasicBlock *D = &*FI++;
397
398 assert(PDT->dominates(PDT->getNode(D), PDT->getNode(B)));
399
400 C->getTerminator()->eraseFromParent();
401 new UnreachableInst(C->getContext(), C);
402
403 DT->deleteEdge(C, B);
404 PDT->deleteEdge(C, B);
405
406 EXPECT_TRUE(PDT->dominates(PDT->getNode(D), PDT->getNode(B)));
407 EXPECT_EQ(PDT->getNode(C), nullptr);
408
409 PDT->recalculate(F);
410
411 EXPECT_FALSE(PDT->dominates(PDT->getNode(D), PDT->getNode(B)));
412 EXPECT_NE(PDT->getNode(C), nullptr);
413 });
414}
415
416// Verify that the PDT is correctly updated in case an edge removal results
417// in an infinite loop.
418//
419// Test case:
420//
421// CFG PDT
422//
423// A Exit
424// | |
425// _B D
426// / | \ |
427// ^ v \ B
428// \ / D / \
429// C \ C A
430// / \ v
431// ^ v Exit
432// \_/
433//
434// After deleting the edge C->B, C is part of an infinite reverse-unreachable
435// loop:
436//
437// CFG' PDT'
438//
439// A Exit
440// | |
441// B D
442// | \ |
443// v \ B
444// / D \
445// C \ A
446// / \ v
447// ^ v Exit
448// \_/
449//
450// In PDT, D post-dominates B. We verify that this post-dominance
451// relation is preserved _after_ deleting the edge C->B from CFG.
452//
453// As C now becomes reverse-unreachable, it is not anymore part of the
454// PDT. We also verify this property.
455//
456// TODO: Can we change the PDT definition such that C remains part of the
457// CFG, at best without loosing the dominance relation D postdom B.
458TEST(DominatorTree, DeletingEdgesIntroducesInfiniteLoop) {
459 StringRef ModuleString =
460 "define void @f() {\n"
461 "A:\n"
462 " br label %B\n"
463 "B:\n"
464 " br i1 undef, label %D, label %C\n"
465 "C:\n"
466 " switch i32 undef, label %C [\n"
467 " i32 0, label %B\n"
468 " ]\n"
469 "D:\n"
470 " ret void\n"
471 "}\n";
472
473 // Parse the module.
474 LLVMContext Context;
475 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
476
477 runWithDomTree(
478 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
479 Function::iterator FI = F.begin();
480
481 FI++;
482 BasicBlock *B = &*FI++;
483 BasicBlock *C = &*FI++;
484 BasicBlock *D = &*FI++;
485
486 assert(PDT->dominates(PDT->getNode(D), PDT->getNode(B)));
487
488 auto SwitchC = cast<SwitchInst>(C->getTerminator());
489 SwitchC->removeCase(SwitchC->case_begin());
490 DT->deleteEdge(C, B);
491 PDT->deleteEdge(C, B);
492
493 EXPECT_TRUE(PDT->dominates(PDT->getNode(D), PDT->getNode(B)));
494 EXPECT_EQ(PDT->getNode(C), nullptr);
495
496 PDT->recalculate(F);
497
498 EXPECT_TRUE(PDT->dominates(PDT->getNode(D), PDT->getNode(B)));
499 EXPECT_EQ(PDT->getNode(C), nullptr);
500 });
501}
502
503// Verify that the PDT is correctly updated in case an edge removal results
504// in an infinite loop.
505//
506// Test case:
507//
508// CFG PDT
509//
510// A Exit
511// | / | \
512// B-- C B D
513// | \ |
514// v \ A
515// / D
516// C--C2 \
517// / \ \ v
518// ^ v --Exit
519// \_/
520//
521// After deleting the edge C->E, C is part of an infinite reverse-unreachable
522// loop:
523//
524// CFG' PDT'
525//
526// A Exit
527// | |
528// B D
529// | \ |
530// v \ B
531// / D \
532// C \ A
533// / \ v
534// ^ v Exit
535// \_/
536//
537// In PDT, D does not post-dominate B. After the edge C->E is removed, a new
538// post-dominance relation is introduced.
539//
540// As C now becomes reverse-unreachable, it is not anymore part of the
541// PDT. We also verify this property.
542//
543// TODO: Can we change the PDT definition such that C remains part of the
544// CFG, at best without loosing the dominance relation D postdom B.
545TEST(DominatorTree, DeletingEdgesIntroducesInfiniteLoop2) {
546 StringRef ModuleString =
547 "define void @f() {\n"
548 "A:\n"
549 " br label %B\n"
550 "B:\n"
551 " br i1 undef, label %D, label %C\n"
552 "C:\n"
553 " switch i32 undef, label %C [\n"
554 " i32 0, label %C2\n"
555 " ]\n"
556 "C2:\n"
557 " ret void\n"
558 "D:\n"
559 " ret void\n"
560 "}\n";
561
562 // Parse the module.
563 LLVMContext Context;
564 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
565
566 runWithDomTree(
567 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
568 Function::iterator FI = F.begin();
569
570 FI++;
571 BasicBlock *B = &*FI++;
572 BasicBlock *C = &*FI++;
573 BasicBlock *C2 = &*FI++;
574 BasicBlock *D = &*FI++;
575
576 auto SwitchC = cast<SwitchInst>(C->getTerminator());
577 SwitchC->removeCase(SwitchC->case_begin());
578 DT->deleteEdge(C, C2);
579 PDT->deleteEdge(C, C2);
580 C2->eraseFromParent();
581
582 EXPECT_EQ(DT->getNode(C2), nullptr);
583 PDT->eraseNode(C2);
584
585 EXPECT_TRUE(PDT->dominates(PDT->getNode(D), PDT->getNode(B)));
586 EXPECT_EQ(PDT->getNode(C), nullptr);
587 EXPECT_EQ(PDT->getNode(C2), nullptr);
588
589 PDT->recalculate(F);
590
591 EXPECT_TRUE(PDT->dominates(PDT->getNode(D), PDT->getNode(B)));
592 EXPECT_EQ(PDT->getNode(C), nullptr);
593 EXPECT_EQ(PDT->getNode(C2), nullptr);
594 });
595}
596
Jakub Kuderski13e9ef12017-07-14 21:17:33 +0000597namespace {
598const auto Insert = CFGBuilder::ActionKind::Insert;
Jakub Kuderskieb59ff22017-07-14 21:58:53 +0000599const auto Delete = CFGBuilder::ActionKind::Delete;
Jakub Kuderski13e9ef12017-07-14 21:17:33 +0000600
601bool CompUpdates(const CFGBuilder::Update &A, const CFGBuilder::Update &B) {
602 return std::tie(A.Action, A.Edge.From, A.Edge.To) <
603 std::tie(B.Action, B.Edge.From, B.Edge.To);
Jakub Kuderski23497b42017-07-14 22:24:15 +0000604}
Jakub Kuderski13e9ef12017-07-14 21:17:33 +0000605} // namespace
606
607TEST(DominatorTree, InsertReachable) {
608 CFGHolder Holder;
609 std::vector<CFGBuilder::Arc> Arcs = {
610 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
611 {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
612
613 std::vector<CFGBuilder::Update> Updates = {{Insert, {"12", "10"}},
614 {Insert, {"10", "9"}},
615 {Insert, {"7", "6"}},
616 {Insert, {"7", "5"}}};
617 CFGBuilder B(Holder.F, Arcs, Updates);
618 DominatorTree DT(*Holder.F);
619 EXPECT_TRUE(DT.verify());
620 PostDomTree PDT(*Holder.F);
621 EXPECT_TRUE(PDT.verify());
622
623 Optional<CFGBuilder::Update> LastUpdate;
624 while ((LastUpdate = B.applyUpdate())) {
625 EXPECT_EQ(LastUpdate->Action, Insert);
626 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
627 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
628 DT.insertEdge(From, To);
629 EXPECT_TRUE(DT.verify());
630 PDT.insertEdge(From, To);
631 EXPECT_TRUE(PDT.verify());
632 }
633}
634
Jakub Kuderski66360342017-07-15 01:27:16 +0000635TEST(DominatorTree, InsertReachable2) {
636 CFGHolder Holder;
637 std::vector<CFGBuilder::Arc> Arcs = {
638 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
639 {"7", "5"}, {"2", "8"}, {"8", "11"}, {"11", "12"}, {"12", "10"},
640 {"10", "9"}, {"9", "10"}};
641
642 std::vector<CFGBuilder::Update> Updates = {{Insert, {"10", "7"}}};
643 CFGBuilder B(Holder.F, Arcs, Updates);
644 DominatorTree DT(*Holder.F);
645 EXPECT_TRUE(DT.verify());
646 PostDomTree PDT(*Holder.F);
647 EXPECT_TRUE(PDT.verify());
648
649 Optional<CFGBuilder::Update> LastUpdate = B.applyUpdate();
650 EXPECT_TRUE(LastUpdate);
651
652 EXPECT_EQ(LastUpdate->Action, Insert);
653 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
654 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
655 DT.insertEdge(From, To);
656 EXPECT_TRUE(DT.verify());
657 PDT.insertEdge(From, To);
658 EXPECT_TRUE(PDT.verify());
659}
660
Jakub Kuderski13e9ef12017-07-14 21:17:33 +0000661TEST(DominatorTree, InsertUnreachable) {
662 CFGHolder Holder;
663 std::vector<CFGBuilder::Arc> Arcs = {{"1", "2"}, {"2", "3"}, {"3", "4"},
664 {"5", "6"}, {"5", "7"}, {"3", "8"},
665 {"9", "10"}, {"11", "12"}};
666
667 std::vector<CFGBuilder::Update> Updates = {{Insert, {"4", "5"}},
668 {Insert, {"8", "9"}},
669 {Insert, {"10", "12"}},
670 {Insert, {"10", "11"}}};
671 CFGBuilder B(Holder.F, Arcs, Updates);
672 DominatorTree DT(*Holder.F);
673 EXPECT_TRUE(DT.verify());
674 PostDomTree PDT(*Holder.F);
675 EXPECT_TRUE(PDT.verify());
676
677 Optional<CFGBuilder::Update> LastUpdate;
678 while ((LastUpdate = B.applyUpdate())) {
679 EXPECT_EQ(LastUpdate->Action, Insert);
680 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
681 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
682 DT.insertEdge(From, To);
683 EXPECT_TRUE(DT.verify());
684 PDT.insertEdge(From, To);
685 EXPECT_TRUE(PDT.verify());
686 }
687}
688
689TEST(DominatorTree, InsertMixed) {
690 CFGHolder Holder;
691 std::vector<CFGBuilder::Arc> Arcs = {
692 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"5", "6"}, {"5", "7"},
693 {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}, {"7", "3"}};
694
695 std::vector<CFGBuilder::Update> Updates = {
696 {Insert, {"4", "5"}}, {Insert, {"2", "5"}}, {Insert, {"10", "9"}},
697 {Insert, {"12", "10"}}, {Insert, {"12", "10"}}, {Insert, {"7", "8"}},
698 {Insert, {"7", "5"}}};
699 CFGBuilder B(Holder.F, Arcs, Updates);
700 DominatorTree DT(*Holder.F);
701 EXPECT_TRUE(DT.verify());
702 PostDomTree PDT(*Holder.F);
703 EXPECT_TRUE(PDT.verify());
704
705 Optional<CFGBuilder::Update> LastUpdate;
706 while ((LastUpdate = B.applyUpdate())) {
707 EXPECT_EQ(LastUpdate->Action, Insert);
708 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
709 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
710 DT.insertEdge(From, To);
711 EXPECT_TRUE(DT.verify());
712 PDT.insertEdge(From, To);
713 EXPECT_TRUE(PDT.verify());
714 }
715}
716
717TEST(DominatorTree, InsertPermut) {
718 std::vector<CFGBuilder::Arc> Arcs = {
719 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"5", "6"}, {"5", "7"},
720 {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}, {"7", "3"}};
721
722 std::vector<CFGBuilder::Update> Updates = {{Insert, {"4", "5"}},
723 {Insert, {"2", "5"}},
724 {Insert, {"10", "9"}},
725 {Insert, {"12", "10"}}};
726
727 while (std::next_permutation(Updates.begin(), Updates.end(), CompUpdates)) {
728 CFGHolder Holder;
729 CFGBuilder B(Holder.F, Arcs, Updates);
730 DominatorTree DT(*Holder.F);
731 EXPECT_TRUE(DT.verify());
732 PostDomTree PDT(*Holder.F);
733 EXPECT_TRUE(PDT.verify());
734
735 Optional<CFGBuilder::Update> LastUpdate;
736 while ((LastUpdate = B.applyUpdate())) {
737 EXPECT_EQ(LastUpdate->Action, Insert);
738 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
739 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
740 DT.insertEdge(From, To);
741 EXPECT_TRUE(DT.verify());
742 PDT.insertEdge(From, To);
743 EXPECT_TRUE(PDT.verify());
744 }
745 }
746}
Jakub Kuderskieb59ff22017-07-14 21:58:53 +0000747
748TEST(DominatorTree, DeleteReachable) {
749 CFGHolder Holder;
750 std::vector<CFGBuilder::Arc> Arcs = {
751 {"1", "2"}, {"2", "3"}, {"2", "4"}, {"3", "4"}, {"4", "5"}, {"5", "6"},
752 {"5", "7"}, {"7", "8"}, {"3", "8"}, {"8", "9"}, {"9", "10"}, {"10", "2"}};
753
754 std::vector<CFGBuilder::Update> Updates = {
755 {Delete, {"2", "4"}}, {Delete, {"7", "8"}}, {Delete, {"10", "2"}}};
756 CFGBuilder B(Holder.F, Arcs, Updates);
757 DominatorTree DT(*Holder.F);
758 EXPECT_TRUE(DT.verify());
759 PostDomTree PDT(*Holder.F);
760 EXPECT_TRUE(PDT.verify());
761
762 Optional<CFGBuilder::Update> LastUpdate;
763 while ((LastUpdate = B.applyUpdate())) {
764 EXPECT_EQ(LastUpdate->Action, Delete);
765 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
766 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
767 DT.deleteEdge(From, To);
768 EXPECT_TRUE(DT.verify());
769 PDT.deleteEdge(From, To);
770 EXPECT_TRUE(PDT.verify());
771 }
772}
773
774TEST(DominatorTree, DeleteUnreachable) {
775 CFGHolder Holder;
776 std::vector<CFGBuilder::Arc> Arcs = {
777 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
778 {"7", "8"}, {"3", "8"}, {"8", "9"}, {"9", "10"}, {"10", "2"}};
779
780 std::vector<CFGBuilder::Update> Updates = {
781 {Delete, {"8", "9"}}, {Delete, {"7", "8"}}, {Delete, {"3", "4"}}};
782 CFGBuilder B(Holder.F, Arcs, Updates);
783 DominatorTree DT(*Holder.F);
784 EXPECT_TRUE(DT.verify());
785 PostDomTree PDT(*Holder.F);
786 EXPECT_TRUE(PDT.verify());
787
788 Optional<CFGBuilder::Update> LastUpdate;
789 while ((LastUpdate = B.applyUpdate())) {
790 EXPECT_EQ(LastUpdate->Action, Delete);
791 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
792 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
793 DT.deleteEdge(From, To);
794 EXPECT_TRUE(DT.verify());
795 PDT.deleteEdge(From, To);
796 EXPECT_TRUE(PDT.verify());
797 }
798}
799
800TEST(DominatorTree, InsertDelete) {
801 std::vector<CFGBuilder::Arc> Arcs = {
802 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
803 {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
804
805 std::vector<CFGBuilder::Update> Updates = {
806 {Insert, {"2", "4"}}, {Insert, {"12", "10"}}, {Insert, {"10", "9"}},
807 {Insert, {"7", "6"}}, {Insert, {"7", "5"}}, {Delete, {"3", "8"}},
808 {Insert, {"10", "7"}}, {Insert, {"2", "8"}}, {Delete, {"3", "4"}},
809 {Delete, {"8", "9"}}, {Delete, {"11", "12"}}};
810
811 CFGHolder Holder;
812 CFGBuilder B(Holder.F, Arcs, Updates);
813 DominatorTree DT(*Holder.F);
814 EXPECT_TRUE(DT.verify());
815 PostDomTree PDT(*Holder.F);
816 EXPECT_TRUE(PDT.verify());
817
818 Optional<CFGBuilder::Update> LastUpdate;
819 while ((LastUpdate = B.applyUpdate())) {
820 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
821 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
822 if (LastUpdate->Action == Insert) {
823 DT.insertEdge(From, To);
824 PDT.insertEdge(From, To);
825 } else {
826 DT.deleteEdge(From, To);
827 PDT.deleteEdge(From, To);
828 }
829
830 EXPECT_TRUE(DT.verify());
831 EXPECT_TRUE(PDT.verify());
832 }
833}
834
Jakub Kuderski66360342017-07-15 01:27:16 +0000835TEST(DominatorTree, InsertDeleteExhaustive) {
Jakub Kuderskieb59ff22017-07-14 21:58:53 +0000836 std::vector<CFGBuilder::Arc> Arcs = {
837 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
838 {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
839
840 std::vector<CFGBuilder::Update> Updates = {
841 {Insert, {"2", "4"}}, {Insert, {"12", "10"}}, {Insert, {"10", "9"}},
842 {Insert, {"7", "6"}}, {Insert, {"7", "5"}}, {Delete, {"3", "8"}},
843 {Insert, {"10", "7"}}, {Insert, {"2", "8"}}, {Delete, {"3", "4"}},
844 {Delete, {"8", "9"}}, {Delete, {"11", "12"}}};
845
846 std::mt19937 Generator(0);
847 for (unsigned i = 0; i < 16; ++i) {
848 std::shuffle(Updates.begin(), Updates.end(), Generator);
849 CFGHolder Holder;
850 CFGBuilder B(Holder.F, Arcs, Updates);
851 DominatorTree DT(*Holder.F);
852 EXPECT_TRUE(DT.verify());
853 PostDomTree PDT(*Holder.F);
854 EXPECT_TRUE(PDT.verify());
855
856 Optional<CFGBuilder::Update> LastUpdate;
857 while ((LastUpdate = B.applyUpdate())) {
858 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
859 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
860 if (LastUpdate->Action == Insert) {
861 DT.insertEdge(From, To);
862 PDT.insertEdge(From, To);
863 } else {
864 DT.deleteEdge(From, To);
865 PDT.deleteEdge(From, To);
866 }
867
868 EXPECT_TRUE(DT.verify());
869 EXPECT_TRUE(PDT.verify());
870 }
871 }
872}