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