blob: 498e111a31f6eee9f27babd88c1440a5b4290069 [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
Chandler Carruth5ad5f152014-01-13 09:26:24 +000010#include "llvm/IR/Dominators.h"
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"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000014#include "llvm/IR/Instructions.h"
15#include "llvm/IR/LLVMContext.h"
16#include "llvm/IR/Module.h"
Chandler Carruth30d69c22015-02-13 10:01:29 +000017#include "llvm/IR/LegacyPassManager.h"
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000018#include "llvm/Support/SourceMgr.h"
19#include "gtest/gtest.h"
20
21using namespace llvm;
22
23namespace llvm {
24 void initializeDPassPass(PassRegistry&);
25
26 namespace {
27 struct DPass : public FunctionPass {
28 static char ID;
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000029 bool runOnFunction(Function &F) override {
Chandler Carruth73523022014-01-13 13:07:17 +000030 DominatorTree *DT =
31 &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
Hongbin Zheng3f978402016-02-25 17:54:07 +000032 PostDominatorTree *PDT =
33 &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000034 Function::iterator FI = F.begin();
35
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000036 BasicBlock *BB0 = &*FI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000037 BasicBlock::iterator BBI = BB0->begin();
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000038 Instruction *Y1 = &*BBI++;
39 Instruction *Y2 = &*BBI++;
40 Instruction *Y3 = &*BBI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000041
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000042 BasicBlock *BB1 = &*FI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000043 BBI = BB1->begin();
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000044 Instruction *Y4 = &*BBI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000045
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000046 BasicBlock *BB2 = &*FI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000047 BBI = BB2->begin();
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000048 Instruction *Y5 = &*BBI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000049
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000050 BasicBlock *BB3 = &*FI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000051 BBI = BB3->begin();
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000052 Instruction *Y6 = &*BBI++;
53 Instruction *Y7 = &*BBI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000054
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000055 BasicBlock *BB4 = &*FI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000056 BBI = BB4->begin();
Duncan P. N. Exon Smithc8925b12015-10-20 18:30:20 +000057 Instruction *Y8 = &*BBI++;
58 Instruction *Y9 = &*BBI++;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000059
60 // Reachability
61 EXPECT_TRUE(DT->isReachableFromEntry(BB0));
62 EXPECT_TRUE(DT->isReachableFromEntry(BB1));
63 EXPECT_TRUE(DT->isReachableFromEntry(BB2));
64 EXPECT_FALSE(DT->isReachableFromEntry(BB3));
65 EXPECT_TRUE(DT->isReachableFromEntry(BB4));
66
67 // BB dominance
68 EXPECT_TRUE(DT->dominates(BB0, BB0));
69 EXPECT_TRUE(DT->dominates(BB0, BB1));
70 EXPECT_TRUE(DT->dominates(BB0, BB2));
71 EXPECT_TRUE(DT->dominates(BB0, BB3));
72 EXPECT_TRUE(DT->dominates(BB0, BB4));
73
74 EXPECT_FALSE(DT->dominates(BB1, BB0));
75 EXPECT_TRUE(DT->dominates(BB1, BB1));
76 EXPECT_FALSE(DT->dominates(BB1, BB2));
77 EXPECT_TRUE(DT->dominates(BB1, BB3));
78 EXPECT_FALSE(DT->dominates(BB1, BB4));
79
80 EXPECT_FALSE(DT->dominates(BB2, BB0));
81 EXPECT_FALSE(DT->dominates(BB2, BB1));
82 EXPECT_TRUE(DT->dominates(BB2, BB2));
83 EXPECT_TRUE(DT->dominates(BB2, BB3));
84 EXPECT_FALSE(DT->dominates(BB2, BB4));
85
86 EXPECT_FALSE(DT->dominates(BB3, BB0));
87 EXPECT_FALSE(DT->dominates(BB3, BB1));
88 EXPECT_FALSE(DT->dominates(BB3, BB2));
89 EXPECT_TRUE(DT->dominates(BB3, BB3));
90 EXPECT_FALSE(DT->dominates(BB3, BB4));
91
92 // BB proper dominance
93 EXPECT_FALSE(DT->properlyDominates(BB0, BB0));
94 EXPECT_TRUE(DT->properlyDominates(BB0, BB1));
95 EXPECT_TRUE(DT->properlyDominates(BB0, BB2));
96 EXPECT_TRUE(DT->properlyDominates(BB0, BB3));
97
98 EXPECT_FALSE(DT->properlyDominates(BB1, BB0));
99 EXPECT_FALSE(DT->properlyDominates(BB1, BB1));
100 EXPECT_FALSE(DT->properlyDominates(BB1, BB2));
101 EXPECT_TRUE(DT->properlyDominates(BB1, BB3));
102
103 EXPECT_FALSE(DT->properlyDominates(BB2, BB0));
104 EXPECT_FALSE(DT->properlyDominates(BB2, BB1));
105 EXPECT_FALSE(DT->properlyDominates(BB2, BB2));
106 EXPECT_TRUE(DT->properlyDominates(BB2, BB3));
107
108 EXPECT_FALSE(DT->properlyDominates(BB3, BB0));
109 EXPECT_FALSE(DT->properlyDominates(BB3, BB1));
110 EXPECT_FALSE(DT->properlyDominates(BB3, BB2));
111 EXPECT_FALSE(DT->properlyDominates(BB3, BB3));
112
113 // Instruction dominance in the same reachable BB
114 EXPECT_FALSE(DT->dominates(Y1, Y1));
115 EXPECT_TRUE(DT->dominates(Y1, Y2));
116 EXPECT_FALSE(DT->dominates(Y2, Y1));
117 EXPECT_FALSE(DT->dominates(Y2, Y2));
118
119 // Instruction dominance in the same unreachable BB
120 EXPECT_TRUE(DT->dominates(Y6, Y6));
121 EXPECT_TRUE(DT->dominates(Y6, Y7));
122 EXPECT_TRUE(DT->dominates(Y7, Y6));
123 EXPECT_TRUE(DT->dominates(Y7, Y7));
124
125 // Invoke
126 EXPECT_TRUE(DT->dominates(Y3, Y4));
127 EXPECT_FALSE(DT->dominates(Y3, Y5));
128
129 // Phi
130 EXPECT_TRUE(DT->dominates(Y2, Y9));
131 EXPECT_FALSE(DT->dominates(Y3, Y9));
132 EXPECT_FALSE(DT->dominates(Y8, Y9));
133
134 // Anything dominates unreachable
135 EXPECT_TRUE(DT->dominates(Y1, Y6));
136 EXPECT_TRUE(DT->dominates(Y3, Y6));
137
138 // Unreachable doesn't dominate reachable
139 EXPECT_FALSE(DT->dominates(Y6, Y1));
140
141 // Instruction, BB dominance
142 EXPECT_FALSE(DT->dominates(Y1, BB0));
143 EXPECT_TRUE(DT->dominates(Y1, BB1));
144 EXPECT_TRUE(DT->dominates(Y1, BB2));
145 EXPECT_TRUE(DT->dominates(Y1, BB3));
146 EXPECT_TRUE(DT->dominates(Y1, BB4));
147
148 EXPECT_FALSE(DT->dominates(Y3, BB0));
149 EXPECT_TRUE(DT->dominates(Y3, BB1));
150 EXPECT_FALSE(DT->dominates(Y3, BB2));
151 EXPECT_TRUE(DT->dominates(Y3, BB3));
152 EXPECT_FALSE(DT->dominates(Y3, BB4));
153
154 EXPECT_TRUE(DT->dominates(Y6, BB3));
155
Diego Novilloee592422013-12-02 14:08:27 +0000156 // Post dominance.
157 EXPECT_TRUE(PDT->dominates(BB0, BB0));
158 EXPECT_FALSE(PDT->dominates(BB1, BB0));
159 EXPECT_FALSE(PDT->dominates(BB2, BB0));
160 EXPECT_FALSE(PDT->dominates(BB3, BB0));
161 EXPECT_TRUE(PDT->dominates(BB4, BB1));
162
163 // Dominance descendants.
164 SmallVector<BasicBlock *, 8> DominatedBBs, PostDominatedBBs;
165
166 DT->getDescendants(BB0, DominatedBBs);
167 PDT->getDescendants(BB0, PostDominatedBBs);
168 EXPECT_EQ(DominatedBBs.size(), 4UL);
169 EXPECT_EQ(PostDominatedBBs.size(), 1UL);
170
171 // BB3 is unreachable. It should have no dominators nor postdominators.
172 DominatedBBs.clear();
173 PostDominatedBBs.clear();
174 DT->getDescendants(BB3, DominatedBBs);
175 DT->getDescendants(BB3, PostDominatedBBs);
176 EXPECT_EQ(DominatedBBs.size(), 0UL);
177 EXPECT_EQ(PostDominatedBBs.size(), 0UL);
178
Daniel Berlin8f8174c2015-04-14 19:49:26 +0000179 // Check DFS Numbers before
180 EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
181 EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 7UL);
182 EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
183 EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 2UL);
184 EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 5UL);
185 EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 6UL);
186 EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 3UL);
187 EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 4UL);
188
189 // Reattach block 3 to block 1 and recalculate
190 BB1->getTerminator()->eraseFromParent();
191 BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getContext()), BB1);
192 DT->recalculate(F);
193
194 // Check DFS Numbers after
195 EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
196 EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 9UL);
197 EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
198 EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 4UL);
199 EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 7UL);
200 EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 8UL);
201 EXPECT_EQ(DT->getNode(BB3)->getDFSNumIn(), 2UL);
202 EXPECT_EQ(DT->getNode(BB3)->getDFSNumOut(), 3UL);
203 EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 5UL);
204 EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 6UL);
205
Serge Pavlov0668cd22017-01-10 02:50:47 +0000206 // Change root node
207 DT->verifyDomTree();
208 BasicBlock *NewEntry = BasicBlock::Create(F.getContext(), "new_entry",
209 &F, BB0);
210 BranchInst::Create(BB0, NewEntry);
211 EXPECT_EQ(F.begin()->getName(), NewEntry->getName());
212 EXPECT_TRUE(&F.getEntryBlock() == NewEntry);
213 DT->setNewRoot(NewEntry);
214 DT->verifyDomTree();
215
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000216 return false;
217 }
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000218 void getAnalysisUsage(AnalysisUsage &AU) const override {
Chandler Carruth73523022014-01-13 13:07:17 +0000219 AU.addRequired<DominatorTreeWrapperPass>();
Hongbin Zheng3f978402016-02-25 17:54:07 +0000220 AU.addRequired<PostDominatorTreeWrapperPass>();
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000221 }
222 DPass() : FunctionPass(ID) {
223 initializeDPassPass(*PassRegistry::getPassRegistry());
224 }
225 };
226 char DPass::ID = 0;
227
Mehdi Amini03b42e42016-04-14 21:59:01 +0000228 std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context, DPass *P) {
Xin Tong1028bbd2017-05-20 19:40:24 +0000229 const char *ModuleString =
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000230 "declare i32 @g()\n" \
David Majnemer7fddecc2015-06-17 20:52:32 +0000231 "define void @f(i32 %x) personality i32 ()* @g {\n" \
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000232 "bb0:\n" \
233 " %y1 = add i32 %x, 1\n" \
234 " %y2 = add i32 %x, 1\n" \
235 " %y3 = invoke i32 @g() to label %bb1 unwind label %bb2\n" \
236 "bb1:\n" \
237 " %y4 = add i32 %x, 1\n" \
238 " br label %bb4\n" \
239 "bb2:\n" \
David Majnemer7fddecc2015-06-17 20:52:32 +0000240 " %y5 = landingpad i32\n" \
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000241 " cleanup\n" \
242 " br label %bb4\n" \
243 "bb3:\n" \
244 " %y6 = add i32 %x, 1\n" \
245 " %y7 = add i32 %x, 1\n" \
246 " ret void\n" \
247 "bb4:\n" \
248 " %y8 = phi i32 [0, %bb2], [%y4, %bb1]\n"
249 " %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n"
250 " ret void\n" \
251 "}\n";
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000252 SMDiagnostic Err;
Xin Tong1028bbd2017-05-20 19:40:24 +0000253 return parseAssemblyString(ModuleString, Err, Context);
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000254 }
255
256 TEST(DominatorTree, Unreachable) {
257 DPass *P = new DPass();
Mehdi Amini03b42e42016-04-14 21:59:01 +0000258 LLVMContext Context;
259 std::unique_ptr<Module> M = makeLLVMModule(Context, P);
Chandler Carruth30d69c22015-02-13 10:01:29 +0000260 legacy::PassManager Passes;
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000261 Passes.add(P);
262 Passes.run(*M);
263 }
264 }
265}
266
267INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false)
Chandler Carruth73523022014-01-13 13:07:17 +0000268INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
Hongbin Zheng3f978402016-02-25 17:54:07 +0000269INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
Rafael Espindolaa53c46a2012-03-30 16:46:21 +0000270INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false)