1 #include "llvm/ADT/STLExtras.h"
2 #include "llvm/CodeGen/LiveIntervals.h"
3 #include "llvm/CodeGen/MIRParser/MIRParser.h"
4 #include "llvm/CodeGen/MachineFunction.h"
5 #include "llvm/CodeGen/MachineModuleInfo.h"
6 #include "llvm/CodeGen/TargetRegisterInfo.h"
7 #include "llvm/IR/LegacyPassManager.h"
8 #include "llvm/InitializePasses.h"
9 #include "llvm/Support/MemoryBuffer.h"
10 #include "llvm/Support/SourceMgr.h"
11 #include "llvm/Support/TargetRegistry.h"
12 #include "llvm/Support/TargetSelect.h"
13 #include "llvm/Target/TargetMachine.h"
14 #include "llvm/Target/TargetOptions.h"
15 #include "gtest/gtest.h"
16
17 using namespace llvm;
18
19 namespace llvm {
20 void initializeTestPassPass(PassRegistry &);
21 }
22
23 namespace {
24
initLLVM()25 void initLLVM() {
26 InitializeAllTargets();
27 InitializeAllTargetMCs();
28 InitializeAllAsmPrinters();
29 InitializeAllAsmParsers();
30
31 PassRegistry *Registry = PassRegistry::getPassRegistry();
32 initializeCore(*Registry);
33 initializeCodeGen(*Registry);
34 }
35
36 /// Create a TargetMachine. As we lack a dedicated always available target for
37 /// unittests, we go for "AMDGPU" to be able to test normal and subregister
38 /// liveranges.
createTargetMachine()39 std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
40 Triple TargetTriple("amdgcn--");
41 std::string Error;
42 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
43 if (!T)
44 return nullptr;
45
46 TargetOptions Options;
47 return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine*>(
48 T->createTargetMachine("AMDGPU", "gfx900", "", Options, None, None,
49 CodeGenOpt::Aggressive)));
50 }
51
parseMIR(LLVMContext & Context,legacy::PassManagerBase & PM,std::unique_ptr<MIRParser> & MIR,const LLVMTargetMachine & TM,StringRef MIRCode,const char * FuncName)52 std::unique_ptr<Module> parseMIR(LLVMContext &Context,
53 legacy::PassManagerBase &PM, std::unique_ptr<MIRParser> &MIR,
54 const LLVMTargetMachine &TM, StringRef MIRCode, const char *FuncName) {
55 SMDiagnostic Diagnostic;
56 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
57 MIR = createMIRParser(std::move(MBuffer), Context);
58 if (!MIR)
59 return nullptr;
60
61 std::unique_ptr<Module> M = MIR->parseIRModule();
62 if (!M)
63 return nullptr;
64
65 M->setDataLayout(TM.createDataLayout());
66
67 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(&TM);
68 if (MIR->parseMachineFunctions(*M, MMIWP->getMMI()))
69 return nullptr;
70 PM.add(MMIWP);
71
72 return M;
73 }
74
75 typedef std::function<void(MachineFunction&,LiveIntervals&)> LiveIntervalTest;
76
77 struct TestPass : public MachineFunctionPass {
78 static char ID;
TestPass__anon6ea183bf0111::TestPass79 TestPass() : MachineFunctionPass(ID) {
80 // We should never call this but always use PM.add(new TestPass(...))
81 abort();
82 }
TestPass__anon6ea183bf0111::TestPass83 TestPass(LiveIntervalTest T) : MachineFunctionPass(ID), T(T) {
84 initializeTestPassPass(*PassRegistry::getPassRegistry());
85 }
86
runOnMachineFunction__anon6ea183bf0111::TestPass87 bool runOnMachineFunction(MachineFunction &MF) override {
88 LiveIntervals &LIS = getAnalysis<LiveIntervals>();
89 T(MF, LIS);
90 EXPECT_TRUE(MF.verify(this));
91 return true;
92 }
93
getAnalysisUsage__anon6ea183bf0111::TestPass94 void getAnalysisUsage(AnalysisUsage &AU) const override {
95 AU.setPreservesAll();
96 AU.addRequired<LiveIntervals>();
97 AU.addPreserved<LiveIntervals>();
98 MachineFunctionPass::getAnalysisUsage(AU);
99 }
100 private:
101 LiveIntervalTest T;
102 };
103
getMI(MachineFunction & MF,unsigned At,unsigned BlockNum)104 static MachineInstr &getMI(MachineFunction &MF, unsigned At,
105 unsigned BlockNum) {
106 MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
107
108 unsigned I = 0;
109 for (MachineInstr &MI : MBB) {
110 if (I == At)
111 return MI;
112 ++I;
113 }
114 llvm_unreachable("Instruction not found");
115 }
116
117 /**
118 * Move instruction number \p From in front of instruction number \p To and
119 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
120 */
testHandleMove(MachineFunction & MF,LiveIntervals & LIS,unsigned From,unsigned To,unsigned BlockNum=0)121 static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
122 unsigned From, unsigned To, unsigned BlockNum = 0) {
123 MachineInstr &FromInstr = getMI(MF, From, BlockNum);
124 MachineInstr &ToInstr = getMI(MF, To, BlockNum);
125
126 MachineBasicBlock &MBB = *FromInstr.getParent();
127 MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator());
128 LIS.handleMove(FromInstr, true);
129 }
130
131 /**
132 * Move instructions numbered \p From inclusive through instruction number
133 * \p To into a newly formed bundle and update affected liveness intervals
134 * with LiveIntervalAnalysis::handleMoveIntoNewBundle().
135 */
testHandleMoveIntoNewBundle(MachineFunction & MF,LiveIntervals & LIS,unsigned From,unsigned To,unsigned BlockNum=0)136 static void testHandleMoveIntoNewBundle(MachineFunction &MF, LiveIntervals &LIS,
137 unsigned From, unsigned To,
138 unsigned BlockNum = 0) {
139 MachineInstr &FromInstr = getMI(MF, From, BlockNum);
140 MachineInstr &ToInstr = getMI(MF, To, BlockNum);
141 MachineBasicBlock &MBB = *FromInstr.getParent();
142 MachineBasicBlock::instr_iterator I = FromInstr.getIterator();
143
144 // Build bundle
145 finalizeBundle(MBB, I, std::next(ToInstr.getIterator()));
146
147 // Update LiveIntervals
148 MachineBasicBlock::instr_iterator BundleStart = std::prev(I);
149 LIS.handleMoveIntoNewBundle(*BundleStart, true);
150 }
151
liveIntervalTest(StringRef MIRFunc,LiveIntervalTest T)152 static void liveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) {
153 LLVMContext Context;
154 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
155 // This test is designed for the X86 backend; stop if it is not available.
156 if (!TM)
157 return;
158
159 legacy::PassManager PM;
160
161 SmallString<160> S;
162 StringRef MIRString = (Twine(R"MIR(
163 ---
164 ...
165 name: func
166 registers:
167 - { id: 0, class: sreg_64 }
168 body: |
169 bb.0:
170 )MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
171 std::unique_ptr<MIRParser> MIR;
172 std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRString,
173 "func");
174 ASSERT_TRUE(M);
175
176 PM.add(new TestPass(T));
177
178 PM.run(*M);
179 }
180
181 } // End of anonymous namespace.
182
183 char TestPass::ID = 0;
184 INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)
185
TEST(LiveIntervalTest,MoveUpDef)186 TEST(LiveIntervalTest, MoveUpDef) {
187 // Value defined.
188 liveIntervalTest(R"MIR(
189 S_NOP 0
190 S_NOP 0
191 early-clobber %0 = IMPLICIT_DEF
192 S_NOP 0, implicit %0
193 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
194 testHandleMove(MF, LIS, 2, 1);
195 });
196 }
197
TEST(LiveIntervalTest,MoveUpRedef)198 TEST(LiveIntervalTest, MoveUpRedef) {
199 liveIntervalTest(R"MIR(
200 %0 = IMPLICIT_DEF
201 S_NOP 0
202 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
203 S_NOP 0, implicit %0
204 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
205 testHandleMove(MF, LIS, 2, 1);
206 });
207 }
208
TEST(LiveIntervalTest,MoveUpEarlyDef)209 TEST(LiveIntervalTest, MoveUpEarlyDef) {
210 liveIntervalTest(R"MIR(
211 S_NOP 0
212 S_NOP 0
213 early-clobber %0 = IMPLICIT_DEF
214 S_NOP 0, implicit %0
215 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
216 testHandleMove(MF, LIS, 2, 1);
217 });
218 }
219
TEST(LiveIntervalTest,MoveUpEarlyRedef)220 TEST(LiveIntervalTest, MoveUpEarlyRedef) {
221 liveIntervalTest(R"MIR(
222 %0 = IMPLICIT_DEF
223 S_NOP 0
224 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
225 S_NOP 0, implicit %0
226 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
227 testHandleMove(MF, LIS, 2, 1);
228 });
229 }
230
TEST(LiveIntervalTest,MoveUpKill)231 TEST(LiveIntervalTest, MoveUpKill) {
232 liveIntervalTest(R"MIR(
233 %0 = IMPLICIT_DEF
234 S_NOP 0
235 S_NOP 0, implicit %0
236 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
237 testHandleMove(MF, LIS, 2, 1);
238 });
239 }
240
TEST(LiveIntervalTest,MoveUpKillFollowing)241 TEST(LiveIntervalTest, MoveUpKillFollowing) {
242 liveIntervalTest(R"MIR(
243 %0 = IMPLICIT_DEF
244 S_NOP 0
245 S_NOP 0, implicit %0
246 S_NOP 0, implicit %0
247 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
248 testHandleMove(MF, LIS, 2, 1);
249 });
250 }
251
252 // TODO: Construct a situation where we have intervals following a hole
253 // while still having connected components.
254
TEST(LiveIntervalTest,MoveDownDef)255 TEST(LiveIntervalTest, MoveDownDef) {
256 // Value defined.
257 liveIntervalTest(R"MIR(
258 S_NOP 0
259 early-clobber %0 = IMPLICIT_DEF
260 S_NOP 0
261 S_NOP 0, implicit %0
262 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
263 testHandleMove(MF, LIS, 1, 2);
264 });
265 }
266
TEST(LiveIntervalTest,MoveDownRedef)267 TEST(LiveIntervalTest, MoveDownRedef) {
268 liveIntervalTest(R"MIR(
269 %0 = IMPLICIT_DEF
270 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
271 S_NOP 0
272 S_NOP 0, implicit %0
273 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
274 testHandleMove(MF, LIS, 1, 2);
275 });
276 }
277
TEST(LiveIntervalTest,MoveDownEarlyDef)278 TEST(LiveIntervalTest, MoveDownEarlyDef) {
279 liveIntervalTest(R"MIR(
280 S_NOP 0
281 early-clobber %0 = IMPLICIT_DEF
282 S_NOP 0
283 S_NOP 0, implicit %0
284 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
285 testHandleMove(MF, LIS, 1, 2);
286 });
287 }
288
TEST(LiveIntervalTest,MoveDownEarlyRedef)289 TEST(LiveIntervalTest, MoveDownEarlyRedef) {
290 liveIntervalTest(R"MIR(
291 %0 = IMPLICIT_DEF
292 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
293 S_NOP 0
294 S_NOP 0, implicit %0
295 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
296 testHandleMove(MF, LIS, 1, 2);
297 });
298 }
299
TEST(LiveIntervalTest,MoveDownKill)300 TEST(LiveIntervalTest, MoveDownKill) {
301 liveIntervalTest(R"MIR(
302 %0 = IMPLICIT_DEF
303 S_NOP 0, implicit %0
304 S_NOP 0
305 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
306 testHandleMove(MF, LIS, 1, 2);
307 });
308 }
309
TEST(LiveIntervalTest,MoveDownKillFollowing)310 TEST(LiveIntervalTest, MoveDownKillFollowing) {
311 liveIntervalTest(R"MIR(
312 %0 = IMPLICIT_DEF
313 S_NOP 0
314 S_NOP 0, implicit %0
315 S_NOP 0, implicit %0
316 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
317 testHandleMove(MF, LIS, 1, 2);
318 });
319 }
320
TEST(LiveIntervalTest,MoveUndefUse)321 TEST(LiveIntervalTest, MoveUndefUse) {
322 liveIntervalTest(R"MIR(
323 %0 = IMPLICIT_DEF
324 S_NOP 0, implicit undef %0
325 S_NOP 0, implicit %0
326 S_NOP 0
327 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
328 testHandleMove(MF, LIS, 1, 3);
329 });
330 }
331
TEST(LiveIntervalTest,MoveUpValNos)332 TEST(LiveIntervalTest, MoveUpValNos) {
333 // handleMoveUp() had a bug where it would reuse the value number of the
334 // destination segment, even though we have no guarantee that this valno
335 // wasn't used in other segments.
336 liveIntervalTest(R"MIR(
337 successors: %bb.1, %bb.2
338 %0 = IMPLICIT_DEF
339 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
340 S_BRANCH %bb.1
341 bb.2:
342 S_NOP 0, implicit %0
343 bb.1:
344 successors: %bb.2
345 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
346 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
347 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
348 S_BRANCH %bb.2
349 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
350 testHandleMove(MF, LIS, 2, 0, 2);
351 });
352 }
353
TEST(LiveIntervalTest,MoveOverUndefUse0)354 TEST(LiveIntervalTest, MoveOverUndefUse0) {
355 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
356 liveIntervalTest(R"MIR(
357 %0 = IMPLICIT_DEF
358 S_NOP 0
359 S_NOP 0, implicit undef %0
360 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
361 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
362 testHandleMove(MF, LIS, 3, 1);
363 });
364 }
365
TEST(LiveIntervalTest,MoveOverUndefUse1)366 TEST(LiveIntervalTest, MoveOverUndefUse1) {
367 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
368 liveIntervalTest(R"MIR(
369 $sgpr0 = IMPLICIT_DEF
370 S_NOP 0
371 S_NOP 0, implicit undef $sgpr0
372 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
373 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
374 testHandleMove(MF, LIS, 3, 1);
375 });
376 }
377
TEST(LiveIntervalTest,SubRegMoveDown)378 TEST(LiveIntervalTest, SubRegMoveDown) {
379 // Subregister ranges can have holes inside a basic block. Check for a
380 // movement of the form 32->150 in a liverange [16, 32) [100,200).
381 liveIntervalTest(R"MIR(
382 successors: %bb.1, %bb.2
383 %0 = IMPLICIT_DEF
384 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
385 S_BRANCH %bb.1
386 bb.2:
387 successors: %bb.1
388 S_NOP 0, implicit %0.sub0
389 S_NOP 0, implicit %0.sub1
390 S_NOP 0
391 undef %0.sub0 = IMPLICIT_DEF
392 %0.sub1 = IMPLICIT_DEF
393 bb.1:
394 S_NOP 0, implicit %0
395 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
396 // Scheduler behaviour: Clear def,read-undef flag and move.
397 MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
398 MI.getOperand(0).setIsUndef(false);
399 testHandleMove(MF, LIS, 1, 4, /*BlockNum=*/1);
400 });
401 }
402
TEST(LiveIntervalTest,SubRegMoveUp)403 TEST(LiveIntervalTest, SubRegMoveUp) {
404 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
405 // after swapping subreg definitions.
406 liveIntervalTest(R"MIR(
407 successors: %bb.1, %bb.2
408 undef %0.sub0 = IMPLICIT_DEF
409 %0.sub1 = IMPLICIT_DEF
410 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
411 S_BRANCH %bb.1
412 bb.1:
413 S_NOP 0, implicit %0.sub1
414 bb.2:
415 S_NOP 0, implicit %0.sub1
416 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
417 testHandleMove(MF, LIS, 1, 0);
418 });
419 }
420
TEST(LiveIntervalTest,DeadSubRegMoveUp)421 TEST(LiveIntervalTest, DeadSubRegMoveUp) {
422 // handleMoveUp had a bug where moving a dead subreg def into the middle of
423 // an earlier segment resulted in an invalid live range.
424 liveIntervalTest(R"MIR(
425 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
426 %125.sub1:vreg_128 = COPY %125.sub0
427 %125.sub2:vreg_128 = COPY %125.sub0
428 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
429 %51.sub1:vreg_128 = COPY %51.sub0
430 %51.sub2:vreg_128 = COPY %51.sub0
431 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
432 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
433 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
434 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
435 %60:vgpr_32 = nofpexcept V_MAD_F32 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $mode, implicit $exec
436 %63:vgpr_32 = nofpexcept V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $mode, implicit $exec
437 dead %66:vgpr_32 = nofpexcept V_MAD_F32 0, %60, 0, undef %67:vgpr_32, 0, %125.sub2, 0, 0, implicit $mode, implicit $exec
438 undef %124.sub1:vreg_128 = nofpexcept V_MAD_F32 0, %57, 0, undef %70:vgpr_32, 0, %125.sub1, 0, 0, implicit $mode, implicit $exec
439 %124.sub0:vreg_128 = nofpexcept V_MAD_F32 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $mode, implicit $exec
440 dead undef %125.sub3:vreg_128 = nofpexcept V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $mode, implicit $exec
441 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
442 testHandleMove(MF, LIS, 15, 12);
443 });
444 }
445
TEST(LiveIntervalTest,EarlyClobberSubRegMoveUp)446 TEST(LiveIntervalTest, EarlyClobberSubRegMoveUp) {
447 // handleMoveUp had a bug where moving an early-clobber subreg def into the
448 // middle of an earlier segment resulted in an invalid live range.
449 liveIntervalTest(R"MIR(
450 %4:sreg_32 = IMPLICIT_DEF
451 %6:sreg_32 = IMPLICIT_DEF
452 undef early-clobber %9.sub0:sreg_64 = WWM %4:sreg_32, implicit $exec
453 %5:sreg_32 = S_FLBIT_I32_B32 %9.sub0:sreg_64
454 early-clobber %9.sub1:sreg_64 = WWM %6:sreg_32, implicit $exec
455 %7:sreg_32 = S_FLBIT_I32_B32 %9.sub1:sreg_64
456 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
457 testHandleMove(MF, LIS, 4, 3);
458 });
459 }
460
TEST(LiveIntervalTest,TestMoveSubRegDefAcrossUseDef)461 TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) {
462 liveIntervalTest(R"MIR(
463 %1:vreg_64 = IMPLICIT_DEF
464
465 bb.1:
466 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
467 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
468 undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec
469 %1.sub1:vreg_64 = COPY %2
470 S_NOP 0, implicit %1.sub1
471 S_BRANCH %bb.1
472
473 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
474 MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
475 // The scheduler clears undef from subregister defs before moving
476 UndefSubregDef.getOperand(0).setIsUndef(false);
477 testHandleMove(MF, LIS, 3, 1, 1);
478 });
479 }
480
TEST(LiveIntervalTest,TestMoveSubRegDefAcrossUseDefMulti)481 TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDefMulti) {
482 liveIntervalTest(R"MIR(
483 %1:vreg_96 = IMPLICIT_DEF
484
485 bb.1:
486 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
487 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
488 undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec
489 %1.sub1:vreg_96 = COPY %2
490 %1.sub2:vreg_96 = COPY %2
491 S_NOP 0, implicit %1.sub1, implicit %1.sub2
492 S_BRANCH %bb.1
493
494 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
495 MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
496 // The scheduler clears undef from subregister defs before moving
497 UndefSubregDef.getOperand(0).setIsUndef(false);
498 testHandleMove(MF, LIS, 4, 1, 1);
499 });
500 }
501
TEST(LiveIntervalTest,TestMoveSubRegUseAcrossMainRangeHole)502 TEST(LiveIntervalTest, TestMoveSubRegUseAcrossMainRangeHole) {
503 liveIntervalTest(R"MIR(
504 %1:sgpr_128 = IMPLICIT_DEF
505 bb.1:
506 %2:sgpr_32 = COPY %1.sub2
507 %3:sgpr_32 = COPY %1.sub1
508 %1.sub2 = COPY %2
509 undef %1.sub0 = IMPLICIT_DEF
510 %1.sub2 = IMPLICIT_DEF
511 S_CBRANCH_SCC1 %bb.1, implicit undef $scc
512 S_BRANCH %bb.2
513 bb.2:
514 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
515 MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
516 MI.getOperand(0).setIsUndef(false);
517 testHandleMove(MF, LIS, 4, 3, 1);
518 testHandleMove(MF, LIS, 1, 4, 1);
519 });
520 }
521
TEST(LiveIntervalTest,BundleUse)522 TEST(LiveIntervalTest, BundleUse) {
523 liveIntervalTest(R"MIR(
524 %0 = IMPLICIT_DEF
525 S_NOP 0
526 S_NOP 0, implicit %0
527 S_NOP 0
528 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
529 testHandleMoveIntoNewBundle(MF, LIS, 1, 2);
530 });
531 }
532
TEST(LiveIntervalTest,BundleDef)533 TEST(LiveIntervalTest, BundleDef) {
534 liveIntervalTest(R"MIR(
535 %0 = IMPLICIT_DEF
536 S_NOP 0
537 S_NOP 0, implicit %0
538 S_NOP 0
539 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
540 testHandleMoveIntoNewBundle(MF, LIS, 0, 1);
541 });
542 }
543
TEST(LiveIntervalTest,BundleRedef)544 TEST(LiveIntervalTest, BundleRedef) {
545 liveIntervalTest(R"MIR(
546 %0 = IMPLICIT_DEF
547 S_NOP 0
548 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
549 S_NOP 0, implicit %0
550 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
551 testHandleMoveIntoNewBundle(MF, LIS, 1, 2);
552 });
553 }
554
TEST(LiveIntervalTest,BundleInternalUse)555 TEST(LiveIntervalTest, BundleInternalUse) {
556 liveIntervalTest(R"MIR(
557 %0 = IMPLICIT_DEF
558 S_NOP 0
559 S_NOP 0, implicit %0
560 S_NOP 0
561 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
562 testHandleMoveIntoNewBundle(MF, LIS, 0, 2);
563 });
564 }
565
TEST(LiveIntervalTest,BundleUndefUse)566 TEST(LiveIntervalTest, BundleUndefUse) {
567 liveIntervalTest(R"MIR(
568 %0 = IMPLICIT_DEF
569 S_NOP 0
570 S_NOP 0, implicit undef %0
571 S_NOP 0
572 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
573 testHandleMoveIntoNewBundle(MF, LIS, 1, 2);
574 });
575 }
576
TEST(LiveIntervalTest,BundleSubRegUse)577 TEST(LiveIntervalTest, BundleSubRegUse) {
578 liveIntervalTest(R"MIR(
579 successors: %bb.1, %bb.2
580 undef %0.sub0 = IMPLICIT_DEF
581 %0.sub1 = IMPLICIT_DEF
582 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
583 S_BRANCH %bb.1
584 bb.1:
585 S_NOP 0
586 S_NOP 0, implicit %0.sub1
587 bb.2:
588 S_NOP 0, implicit %0.sub1
589 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
590 testHandleMoveIntoNewBundle(MF, LIS, 0, 1, 1);
591 });
592 }
593
TEST(LiveIntervalTest,BundleSubRegDef)594 TEST(LiveIntervalTest, BundleSubRegDef) {
595 liveIntervalTest(R"MIR(
596 successors: %bb.1, %bb.2
597 undef %0.sub0 = IMPLICIT_DEF
598 %0.sub1 = IMPLICIT_DEF
599 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
600 S_BRANCH %bb.1
601 bb.1:
602 S_NOP 0
603 S_NOP 0, implicit %0.sub1
604 bb.2:
605 S_NOP 0, implicit %0.sub1
606 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
607 testHandleMoveIntoNewBundle(MF, LIS, 0, 1, 0);
608 });
609 }
610
main(int argc,char ** argv)611 int main(int argc, char **argv) {
612 ::testing::InitGoogleTest(&argc, argv);
613 initLLVM();
614 return RUN_ALL_TESTS();
615 }
616