blob: a39fd7f73cf4349117f9f85099276f2dff96ddd0 [file] [log] [blame]
Matthias Braun3199c4e2016-05-02 23:05:48 +00001#include "llvm/ADT/STLExtras.h"
Matthias Braunf8422972017-12-13 02:51:04 +00002#include "llvm/CodeGen/LiveIntervals.h"
Matthias Braun3199c4e2016-05-02 23:05:48 +00003#include "llvm/CodeGen/MIRParser/MIRParser.h"
4#include "llvm/CodeGen/MachineFunction.h"
Matthias Braun7938eee2016-05-10 03:03:55 +00005#include "llvm/CodeGen/MachineModuleInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +00006#include "llvm/CodeGen/TargetRegisterInfo.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +00007#include "llvm/IR/LegacyPassManager.h"
Matthias Braun3199c4e2016-05-02 23:05:48 +00008#include "llvm/Support/MemoryBuffer.h"
9#include "llvm/Support/SourceMgr.h"
10#include "llvm/Support/TargetRegistry.h"
11#include "llvm/Support/TargetSelect.h"
12#include "llvm/Target/TargetMachine.h"
13#include "llvm/Target/TargetOptions.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +000014#include "gtest/gtest.h"
NAKAMURA Takumic1857d12016-02-18 07:37:17 +000015
Matthias Braun3199c4e2016-05-02 23:05:48 +000016using namespace llvm;
17
18namespace llvm {
19 void initializeTestPassPass(PassRegistry &);
20}
21
22namespace {
23
24void initLLVM() {
25 InitializeAllTargets();
26 InitializeAllTargetMCs();
27 InitializeAllAsmPrinters();
28 InitializeAllAsmParsers();
29
30 PassRegistry *Registry = PassRegistry::getPassRegistry();
31 initializeCore(*Registry);
32 initializeCodeGen(*Registry);
33}
34
35/// Create a TargetMachine. As we lack a dedicated always available target for
Matthias Braun3865b1d2016-07-26 03:57:45 +000036/// unittests, we go for "AMDGPU" to be able to test normal and subregister
37/// liveranges.
Matthias Braun3199c4e2016-05-02 23:05:48 +000038std::unique_ptr<TargetMachine> createTargetMachine() {
Matthias Braun3865b1d2016-07-26 03:57:45 +000039 Triple TargetTriple("amdgcn--");
Matthias Braun3199c4e2016-05-02 23:05:48 +000040 std::string Error;
41 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
42 if (!T)
43 return nullptr;
44
45 TargetOptions Options;
Rafael Espindola79e238a2017-08-03 02:16:21 +000046 return std::unique_ptr<TargetMachine>(T->createTargetMachine(
47 "AMDGPU", "", "", Options, None, None, CodeGenOpt::Aggressive));
Matthias Braun3199c4e2016-05-02 23:05:48 +000048}
49
50std::unique_ptr<Module> parseMIR(LLVMContext &Context,
51 legacy::PassManagerBase &PM, std::unique_ptr<MIRParser> &MIR,
52 const TargetMachine &TM, StringRef MIRCode, const char *FuncName) {
53 SMDiagnostic Diagnostic;
54 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
55 MIR = createMIRParser(std::move(MBuffer), Context);
56 if (!MIR)
57 return nullptr;
58
Matthias Braun7bda1952017-06-06 00:44:35 +000059 std::unique_ptr<Module> M = MIR->parseIRModule();
Matthias Braun3199c4e2016-05-02 23:05:48 +000060 if (!M)
61 return nullptr;
62
63 M->setDataLayout(TM.createDataLayout());
64
Matthias Braun733fe362016-08-24 01:52:46 +000065 MachineModuleInfo *MMI = new MachineModuleInfo(&TM);
Matthias Braun7bda1952017-06-06 00:44:35 +000066 if (MIR->parseMachineFunctions(*M, *MMI))
67 return nullptr;
Matthias Braun733fe362016-08-24 01:52:46 +000068 PM.add(MMI);
Matthias Braun3199c4e2016-05-02 23:05:48 +000069
70 return M;
71}
72
73typedef std::function<void(MachineFunction&,LiveIntervals&)> LiveIntervalTest;
74
75struct TestPass : public MachineFunctionPass {
76 static char ID;
77 TestPass() : MachineFunctionPass(ID) {
78 // We should never call this but always use PM.add(new TestPass(...))
79 abort();
80 }
81 TestPass(LiveIntervalTest T) : MachineFunctionPass(ID), T(T) {
82 initializeTestPassPass(*PassRegistry::getPassRegistry());
83 }
84
85 bool runOnMachineFunction(MachineFunction &MF) override {
86 LiveIntervals &LIS = getAnalysis<LiveIntervals>();
87 T(MF, LIS);
88 EXPECT_TRUE(MF.verify(this));
89 return true;
90 }
91
92 void getAnalysisUsage(AnalysisUsage &AU) const override {
93 AU.setPreservesAll();
94 AU.addRequired<LiveIntervals>();
95 AU.addPreserved<LiveIntervals>();
96 MachineFunctionPass::getAnalysisUsage(AU);
97 }
98private:
99 LiveIntervalTest T;
100};
101
Matthias Braun3865b1d2016-07-26 03:57:45 +0000102static MachineInstr &getMI(MachineFunction &MF, unsigned At,
103 unsigned BlockNum) {
104 MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
105
106 unsigned I = 0;
107 for (MachineInstr &MI : MBB) {
108 if (I == At)
109 return MI;
110 ++I;
111 }
112 llvm_unreachable("Instruction not found");
113}
114
Matthias Braun3199c4e2016-05-02 23:05:48 +0000115/**
116 * Move instruction number \p From in front of instruction number \p To and
117 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
118 */
119static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000120 unsigned From, unsigned To, unsigned BlockNum = 0) {
Matthias Braun3865b1d2016-07-26 03:57:45 +0000121 MachineInstr &FromInstr = getMI(MF, From, BlockNum);
122 MachineInstr &ToInstr = getMI(MF, To, BlockNum);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000123
Matthias Braun3865b1d2016-07-26 03:57:45 +0000124 MachineBasicBlock &MBB = *FromInstr.getParent();
125 MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator());
126 LIS.handleMove(FromInstr, true);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000127}
128
129static void liveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) {
130 LLVMContext Context;
131 std::unique_ptr<TargetMachine> TM = createTargetMachine();
132 // This test is designed for the X86 backend; stop if it is not available.
133 if (!TM)
134 return;
135
136 legacy::PassManager PM;
137
138 SmallString<160> S;
Matthias Braun1cba1402017-02-23 01:09:01 +0000139 StringRef MIRString = (Twine(R"MIR(
140---
141...
142name: func
143registers:
144 - { id: 0, class: sreg_64 }
145body: |
146 bb.0:
147)MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000148 std::unique_ptr<MIRParser> MIR;
149 std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRString,
150 "func");
Matthias Braun531f3a92017-06-15 22:50:57 +0000151 ASSERT_TRUE(M);
Matthias Braun3199c4e2016-05-02 23:05:48 +0000152
153 PM.add(new TestPass(T));
154
155 PM.run(*M);
156}
157
158} // End of anonymous namespace.
159
160char TestPass::ID = 0;
161INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)
162
163TEST(LiveIntervalTest, MoveUpDef) {
164 // Value defined.
Matthias Braun1cba1402017-02-23 01:09:01 +0000165 liveIntervalTest(R"MIR(
166 S_NOP 0
167 S_NOP 0
168 early-clobber %0 = IMPLICIT_DEF
169 S_NOP 0, implicit %0
170)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000171 testHandleMove(MF, LIS, 2, 1);
172 });
173}
174
175TEST(LiveIntervalTest, MoveUpRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000176 liveIntervalTest(R"MIR(
177 %0 = IMPLICIT_DEF
178 S_NOP 0
179 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
180 S_NOP 0, implicit %0
181)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000182 testHandleMove(MF, LIS, 2, 1);
183 });
184}
185
186TEST(LiveIntervalTest, MoveUpEarlyDef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000187 liveIntervalTest(R"MIR(
188 S_NOP 0
189 S_NOP 0
190 early-clobber %0 = IMPLICIT_DEF
191 S_NOP 0, implicit %0
192)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000193 testHandleMove(MF, LIS, 2, 1);
194 });
195}
196
197TEST(LiveIntervalTest, MoveUpEarlyRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000198 liveIntervalTest(R"MIR(
199 %0 = IMPLICIT_DEF
200 S_NOP 0
201 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
202 S_NOP 0, implicit %0
203)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000204 testHandleMove(MF, LIS, 2, 1);
205 });
206}
207
208TEST(LiveIntervalTest, MoveUpKill) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000209 liveIntervalTest(R"MIR(
210 %0 = IMPLICIT_DEF
211 S_NOP 0
212 S_NOP 0, implicit %0
213)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000214 testHandleMove(MF, LIS, 2, 1);
215 });
216}
217
218TEST(LiveIntervalTest, MoveUpKillFollowing) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000219 liveIntervalTest(R"MIR(
220 %0 = IMPLICIT_DEF
221 S_NOP 0
222 S_NOP 0, implicit %0
223 S_NOP 0, implicit %0
224)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000225 testHandleMove(MF, LIS, 2, 1);
226 });
227}
228
229// TODO: Construct a situation where we have intervals following a hole
230// while still having connected components.
231
232TEST(LiveIntervalTest, MoveDownDef) {
233 // Value defined.
Matthias Braun1cba1402017-02-23 01:09:01 +0000234 liveIntervalTest(R"MIR(
235 S_NOP 0
236 early-clobber %0 = IMPLICIT_DEF
237 S_NOP 0
238 S_NOP 0, implicit %0
239)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000240 testHandleMove(MF, LIS, 1, 2);
241 });
242}
243
244TEST(LiveIntervalTest, MoveDownRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000245 liveIntervalTest(R"MIR(
246 %0 = IMPLICIT_DEF
247 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
248 S_NOP 0
249 S_NOP 0, implicit %0
250)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000251 testHandleMove(MF, LIS, 1, 2);
252 });
253}
254
255TEST(LiveIntervalTest, MoveDownEarlyDef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000256 liveIntervalTest(R"MIR(
257 S_NOP 0
258 early-clobber %0 = IMPLICIT_DEF
259 S_NOP 0
260 S_NOP 0, implicit %0
261)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000262 testHandleMove(MF, LIS, 1, 2);
263 });
264}
265
266TEST(LiveIntervalTest, MoveDownEarlyRedef) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000267 liveIntervalTest(R"MIR(
268 %0 = IMPLICIT_DEF
269 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
270 S_NOP 0
271 S_NOP 0, implicit %0
272)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000273 testHandleMove(MF, LIS, 1, 2);
274 });
275}
276
277TEST(LiveIntervalTest, MoveDownKill) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000278 liveIntervalTest(R"MIR(
279 %0 = IMPLICIT_DEF
280 S_NOP 0, implicit %0
281 S_NOP 0
282)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000283 testHandleMove(MF, LIS, 1, 2);
284 });
285}
286
287TEST(LiveIntervalTest, MoveDownKillFollowing) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000288 liveIntervalTest(R"MIR(
289 %0 = IMPLICIT_DEF
290 S_NOP 0
291 S_NOP 0, implicit %0
292 S_NOP 0, implicit %0
293)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3199c4e2016-05-02 23:05:48 +0000294 testHandleMove(MF, LIS, 1, 2);
295 });
296}
297
Matthias Braun71474e82016-05-06 21:47:41 +0000298TEST(LiveIntervalTest, MoveUndefUse) {
Matthias Braun1cba1402017-02-23 01:09:01 +0000299 liveIntervalTest(R"MIR(
300 %0 = IMPLICIT_DEF
301 S_NOP 0, implicit undef %0
302 S_NOP 0, implicit %0
303 S_NOP 0
304)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun71474e82016-05-06 21:47:41 +0000305 testHandleMove(MF, LIS, 1, 3);
306 });
307}
308
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000309TEST(LiveIntervalTest, MoveUpValNos) {
310 // handleMoveUp() had a bug where it would reuse the value number of the
311 // destination segment, even though we have no guarntee that this valno wasn't
312 // used in other segments.
Matthias Braun1cba1402017-02-23 01:09:01 +0000313 liveIntervalTest(R"MIR(
314 successors: %bb.1, %bb.2
315 %0 = IMPLICIT_DEF
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000316 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
Matthias Braun1cba1402017-02-23 01:09:01 +0000317 S_BRANCH %bb.1
318 bb.2:
319 S_NOP 0, implicit %0
320 bb.1:
321 successors: %bb.2
322 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
323 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
324 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
325 S_BRANCH %bb.2
326)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braunfc4c8a12016-05-24 21:54:01 +0000327 testHandleMove(MF, LIS, 2, 0, 2);
328 });
329}
330
Matthias Braun959a8c92016-06-11 00:31:28 +0000331TEST(LiveIntervalTest, MoveOverUndefUse0) {
332 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
Matthias Braun1cba1402017-02-23 01:09:01 +0000333 liveIntervalTest(R"MIR(
334 %0 = IMPLICIT_DEF
335 S_NOP 0
336 S_NOP 0, implicit undef %0
337 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
338)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun959a8c92016-06-11 00:31:28 +0000339 testHandleMove(MF, LIS, 3, 1);
340 });
341}
342
343TEST(LiveIntervalTest, MoveOverUndefUse1) {
344 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
Matthias Braun1cba1402017-02-23 01:09:01 +0000345 liveIntervalTest(R"MIR(
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000346 $sgpr0 = IMPLICIT_DEF
Matthias Braun1cba1402017-02-23 01:09:01 +0000347 S_NOP 0
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000348 S_NOP 0, implicit undef $sgpr0
349 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
Matthias Braun1cba1402017-02-23 01:09:01 +0000350)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun959a8c92016-06-11 00:31:28 +0000351 testHandleMove(MF, LIS, 3, 1);
352 });
353}
354
Matthias Braun3865b1d2016-07-26 03:57:45 +0000355TEST(LiveIntervalTest, SubRegMoveDown) {
356 // Subregister ranges can have holes inside a basic block. Check for a
357 // movement of the form 32->150 in a liverange [16, 32) [100,200).
Matthias Braun1cba1402017-02-23 01:09:01 +0000358 liveIntervalTest(R"MIR(
359 successors: %bb.1, %bb.2
360 %0 = IMPLICIT_DEF
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000361 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
Matthias Braun1cba1402017-02-23 01:09:01 +0000362 S_BRANCH %bb.1
363 bb.2:
364 successors: %bb.1
365 S_NOP 0, implicit %0.sub0
366 S_NOP 0, implicit %0.sub1
367 S_NOP 0
368 undef %0.sub0 = IMPLICIT_DEF
369 %0.sub1 = IMPLICIT_DEF
370 bb.1:
371 S_NOP 0, implicit %0
372)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
Matthias Braun3865b1d2016-07-26 03:57:45 +0000373 // Scheduler behaviour: Clear def,read-undef flag and move.
374 MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
375 MI.getOperand(0).setIsUndef(false);
376 testHandleMove(MF, LIS, 1, 4, /*BlockNum=*/1);
377 });
378}
379
Stanislav Mekhanoshinb546174b2017-03-11 00:14:52 +0000380TEST(LiveIntervalTest, SubRegMoveUp) {
381 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
382 // after swapping subreg definitions.
383 liveIntervalTest(R"MIR(
384 successors: %bb.1, %bb.2
385 undef %0.sub0 = IMPLICIT_DEF
386 %0.sub1 = IMPLICIT_DEF
Puyan Lotfi43e94b12018-01-31 22:04:26 +0000387 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
Stanislav Mekhanoshinb546174b2017-03-11 00:14:52 +0000388 S_BRANCH %bb.1
389 bb.1:
390 S_NOP 0, implicit %0.sub1
391 bb.2:
392 S_NOP 0, implicit %0.sub1
393)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
394 testHandleMove(MF, LIS, 1, 0);
395 });
396}
397
Tim Renouff40707a2018-02-26 14:42:13 +0000398TEST(LiveIntervalTest, DeadSubRegMoveUp) {
399 // handleMoveUp had a bug where moving a dead subreg def into the middle of
400 // an earlier segment resulted in an invalid live range.
401 liveIntervalTest(R"MIR(
402 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
403 %125.sub1:vreg_128 = COPY %125.sub0
404 %125.sub2:vreg_128 = COPY %125.sub0
405 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
406 %51.sub1:vreg_128 = COPY %51.sub0
407 %51.sub2:vreg_128 = COPY %51.sub0
408 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
409 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
410 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
411 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
412 %60:vgpr_32 = V_MAD_F32 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $exec
413 %63:vgpr_32 = V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $exec
414 dead %66:vgpr_32 = V_MAD_F32 0, %60, 0, undef %67:vgpr_32, 0, %125.sub2, 0, 0, implicit $exec
415 undef %124.sub1:vreg_128 = V_MAD_F32 0, %57, 0, undef %70:vgpr_32, 0, %125.sub1, 0, 0, implicit $exec
416 %124.sub0:vreg_128 = V_MAD_F32 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $exec
417 dead undef %125.sub3:vreg_128 = V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $exec
418)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
419 testHandleMove(MF, LIS, 15, 12);
420 });
421}
422
Matthias Braun3199c4e2016-05-02 23:05:48 +0000423int main(int argc, char **argv) {
424 ::testing::InitGoogleTest(&argc, argv);
425 initLLVM();
426 return RUN_ALL_TESTS();
NAKAMURA Takumic1857d12016-02-18 07:37:17 +0000427}