xref: /llvm-project/llvm/unittests/MI/LiveIntervalTest.cpp (revision bb3f5e1fed7c6ba733b7f273e93f5d3930976185)
1 #include "llvm/ADT/STLExtras.h"
2 #include "llvm/CodeGen/LiveIntervals.h"
3 #include "llvm/CodeGen/LiveVariables.h"
4 #include "llvm/CodeGen/MIRParser/MIRParser.h"
5 #include "llvm/CodeGen/MachineFunction.h"
6 #include "llvm/CodeGen/MachineModuleInfo.h"
7 #include "llvm/CodeGen/TargetRegisterInfo.h"
8 #include "llvm/CodeGen/TargetSubtargetInfo.h"
9 #include "llvm/IR/LegacyPassManager.h"
10 #include "llvm/IR/Module.h"
11 #include "llvm/InitializePasses.h"
12 #include "llvm/MC/TargetRegistry.h"
13 #include "llvm/Support/MemoryBuffer.h"
14 #include "llvm/Support/SourceMgr.h"
15 #include "llvm/Support/TargetSelect.h"
16 #include "llvm/Target/TargetMachine.h"
17 #include "llvm/Target/TargetOptions.h"
18 #include "gtest/gtest.h"
19 
20 #include "../lib/CodeGen/RegisterCoalescer.h"
21 
22 using namespace llvm;
23 
24 namespace llvm {
25   void initializeTestPassPass(PassRegistry &);
26 }
27 
28 namespace {
29 
30 void initLLVM() {
31   InitializeAllTargets();
32   InitializeAllTargetMCs();
33   InitializeAllAsmPrinters();
34   InitializeAllAsmParsers();
35 
36   PassRegistry *Registry = PassRegistry::getPassRegistry();
37   initializeCore(*Registry);
38   initializeCodeGen(*Registry);
39 }
40 
41 /// Create a TargetMachine. As we lack a dedicated always available target for
42 /// unittests, we go for "AMDGPU" to be able to test normal and subregister
43 /// liveranges.
44 std::unique_ptr<TargetMachine> createTargetMachine() {
45   Triple TargetTriple("amdgcn--");
46   std::string Error;
47   const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
48   if (!T)
49     return nullptr;
50 
51   TargetOptions Options;
52   return std::unique_ptr<TargetMachine>(
53       T->createTargetMachine("AMDGPU", "gfx900", "", Options, std::nullopt,
54                              std::nullopt, CodeGenOptLevel::Aggressive));
55 }
56 
57 std::unique_ptr<Module> parseMIR(LLVMContext &Context,
58                                  legacy::PassManagerBase &PM,
59                                  std::unique_ptr<MIRParser> &MIR,
60                                  const TargetMachine &TM, StringRef MIRCode) {
61   SMDiagnostic Diagnostic;
62   std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
63   MIR = createMIRParser(std::move(MBuffer), Context);
64   if (!MIR)
65     return nullptr;
66 
67   std::unique_ptr<Module> M = MIR->parseIRModule();
68   if (!M)
69     return nullptr;
70 
71   M->setDataLayout(TM.createDataLayout());
72 
73   MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(&TM);
74   if (MIR->parseMachineFunctions(*M, MMIWP->getMMI()))
75     return nullptr;
76   PM.add(MMIWP);
77 
78   return M;
79 }
80 
81 struct TestPass : public MachineFunctionPass {
82   static char ID;
83   TestPass() : MachineFunctionPass(ID) {}
84 };
85 
86 template <typename AnalysisType>
87 struct TestPassT : public TestPass {
88 
89   typedef std::function<void(MachineFunction&,AnalysisType&)> TestFx;
90 
91   TestPassT() {
92     // We should never call this but always use PM.add(new TestPass(...))
93     abort();
94   }
95   TestPassT(TestFx T, bool ShouldPass)
96       : T(T), ShouldPass(ShouldPass) {
97     initializeTestPassPass(*PassRegistry::getPassRegistry());
98   }
99 
100   bool runOnMachineFunction(MachineFunction &MF) override {
101     AnalysisType &A = getAnalysis<AnalysisType>();
102     T(MF, A);
103     EXPECT_EQ(MF.verify(this, /* Banner=*/nullptr,
104                         /*OS=*/nullptr,
105                         /* AbortOnError=*/false),
106               ShouldPass);
107     return true;
108   }
109 
110   void getAnalysisUsage(AnalysisUsage &AU) const override {
111     AU.setPreservesAll();
112     AU.addRequired<AnalysisType>();
113     AU.addPreserved<AnalysisType>();
114     MachineFunctionPass::getAnalysisUsage(AU);
115   }
116 private:
117   TestFx T;
118   bool ShouldPass;
119 };
120 
121 static MachineInstr &getMI(MachineFunction &MF, unsigned At,
122                            unsigned BlockNum) {
123   MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
124 
125   unsigned I = 0;
126   for (MachineInstr &MI : MBB) {
127     if (I == At)
128       return MI;
129     ++I;
130   }
131   llvm_unreachable("Instruction not found");
132 }
133 
134 /**
135  * Move instruction number \p From in front of instruction number \p To and
136  * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
137  */
138 static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
139                            unsigned From, unsigned To, unsigned BlockNum = 0) {
140   MachineInstr &FromInstr = getMI(MF, From, BlockNum);
141   MachineInstr &ToInstr = getMI(MF, To, BlockNum);
142 
143   MachineBasicBlock &MBB = *FromInstr.getParent();
144   MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator());
145   LIS.handleMove(FromInstr, true);
146 }
147 
148 /**
149  * Move instructions numbered \p From inclusive through instruction number
150  * \p To into a newly formed bundle and update affected liveness intervals
151  * with LiveIntervalAnalysis::handleMoveIntoNewBundle().
152  */
153 static void testHandleMoveIntoNewBundle(MachineFunction &MF, LiveIntervals &LIS,
154                                         unsigned From, unsigned To,
155                                         unsigned BlockNum = 0) {
156   MachineInstr &FromInstr = getMI(MF, From, BlockNum);
157   MachineInstr &ToInstr = getMI(MF, To, BlockNum);
158   MachineBasicBlock &MBB = *FromInstr.getParent();
159   MachineBasicBlock::instr_iterator I = FromInstr.getIterator();
160 
161   // Build bundle
162   finalizeBundle(MBB, I, std::next(ToInstr.getIterator()));
163   MF.getProperties().reset(MachineFunctionProperties::Property::IsSSA);
164 
165   // Update LiveIntervals
166   MachineBasicBlock::instr_iterator BundleStart = std::prev(I);
167   LIS.handleMoveIntoNewBundle(*BundleStart, true);
168 }
169 
170 /**
171  * Split block numbered \p BlockNum at instruction \p SplitAt using
172  * MachineBasicBlock::splitAt updating liveness intervals.
173  */
174 static void testSplitAt(MachineFunction &MF, LiveIntervals &LIS,
175                         unsigned SplitAt, unsigned BlockNum) {
176   MachineInstr &SplitInstr = getMI(MF, SplitAt, BlockNum);
177   MachineBasicBlock &MBB = *SplitInstr.getParent();
178 
179   // Split block and update live intervals
180   MBB.splitAt(SplitInstr, false, &LIS);
181 }
182 
183 /**
184  * Helper function to test for interference between a hard register and a
185  * virtual register live ranges.
186  */
187 static bool checkRegUnitInterference(LiveIntervals &LIS,
188                                      const TargetRegisterInfo &TRI,
189                                      const LiveInterval &VirtReg,
190                                      MCRegister PhysReg) {
191   if (VirtReg.empty())
192     return false;
193   CoalescerPair CP(VirtReg.reg(), PhysReg, TRI);
194 
195   for (MCRegUnit Unit : TRI.regunits(PhysReg)) {
196     const LiveRange &UnitRange = LIS.getRegUnit(Unit);
197     if (VirtReg.overlaps(UnitRange, CP, *LIS.getSlotIndexes()))
198       return true;
199   }
200   return false;
201 }
202 
203 template <typename AnalysisType>
204 static void doTest(StringRef MIRFunc,
205                    typename TestPassT<AnalysisType>::TestFx T,
206                    bool ShouldPass = true) {
207   LLVMContext Context;
208   std::unique_ptr<TargetMachine> TM = createTargetMachine();
209   // This test is designed for the X86 backend; stop if it is not available.
210   if (!TM)
211     return;
212 
213   legacy::PassManager PM;
214   std::unique_ptr<MIRParser> MIR;
215   std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRFunc);
216   ASSERT_TRUE(M);
217 
218   PM.add(new TestPassT<AnalysisType>(T, ShouldPass));
219 
220   PM.run(*M);
221 }
222 
223 static void liveIntervalTest(StringRef MIRFunc,
224                              TestPassT<LiveIntervalsWrapperPass>::TestFx T,
225                              bool ShouldPass = true) {
226   SmallString<160> S;
227   StringRef MIRString = (Twine(R"MIR(
228 ---
229 ...
230 name: func
231 registers:
232   - { id: 0, class: sreg_64 }
233 body: |
234   bb.0:
235 )MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
236 
237   doTest<LiveIntervalsWrapperPass>(MIRString, T, ShouldPass);
238 }
239 
240 static void liveVariablesTest(StringRef MIRFunc,
241                               TestPassT<LiveVariablesWrapperPass>::TestFx T,
242                               bool ShouldPass = true) {
243   SmallString<160> S;
244   StringRef MIRString = (Twine(R"MIR(
245 ---
246 ...
247 name: func
248 tracksRegLiveness: true
249 registers:
250   - { id: 0, class: sreg_64 }
251 body: |
252   bb.0:
253 )MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
254   doTest<LiveVariablesWrapperPass>(MIRString, T, ShouldPass);
255 }
256 
257 } // End of anonymous namespace.
258 
259 char TestPass::ID = 0;
260 INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)
261 
262 TEST(LiveIntervalTest, MoveUpDef) {
263   // Value defined.
264   liveIntervalTest(
265       R"MIR(
266     S_NOP 0
267     S_NOP 0
268     early-clobber %0 = IMPLICIT_DEF
269     S_NOP 0, implicit %0
270 )MIR",
271       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
272         testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
273       });
274 }
275 
276 TEST(LiveIntervalTest, MoveUpRedef) {
277   liveIntervalTest(R"MIR(
278     %0 = IMPLICIT_DEF
279     S_NOP 0
280     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
281     S_NOP 0, implicit %0
282 )MIR",
283                    [](MachineFunction &MF, LiveIntervalsWrapperPass &LIS) {
284                      testHandleMove(MF, LIS.getLIS(), 2, 1);
285                    });
286 }
287 
288 TEST(LiveIntervalTest, MoveUpEarlyDef) {
289   liveIntervalTest(
290       R"MIR(
291     S_NOP 0
292     S_NOP 0
293     early-clobber %0 = IMPLICIT_DEF
294     S_NOP 0, implicit %0
295 )MIR",
296       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
297         testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
298       });
299 }
300 
301 TEST(LiveIntervalTest, MoveUpEarlyRedef) {
302   liveIntervalTest(
303       R"MIR(
304     %0 = IMPLICIT_DEF
305     S_NOP 0
306     early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
307     S_NOP 0, implicit %0
308 )MIR",
309       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
310         testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
311       });
312 }
313 
314 TEST(LiveIntervalTest, MoveUpKill) {
315   liveIntervalTest(
316       R"MIR(
317     %0 = IMPLICIT_DEF
318     S_NOP 0
319     S_NOP 0, implicit %0
320 )MIR",
321       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
322         testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
323       });
324 }
325 
326 TEST(LiveIntervalTest, MoveUpKillFollowing) {
327   liveIntervalTest(
328       R"MIR(
329     %0 = IMPLICIT_DEF
330     S_NOP 0
331     S_NOP 0, implicit %0
332     S_NOP 0, implicit %0
333 )MIR",
334       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
335         testHandleMove(MF, LISWrapper.getLIS(), 2, 1);
336       });
337 }
338 
339 // TODO: Construct a situation where we have intervals following a hole
340 // while still having connected components.
341 
342 TEST(LiveIntervalTest, MoveDownDef) {
343   // Value defined.
344   liveIntervalTest(
345       R"MIR(
346     S_NOP 0
347     early-clobber %0 = IMPLICIT_DEF
348     S_NOP 0
349     S_NOP 0, implicit %0
350 )MIR",
351       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
352         testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
353       });
354 }
355 
356 TEST(LiveIntervalTest, MoveDownRedef) {
357   liveIntervalTest(
358       R"MIR(
359     %0 = IMPLICIT_DEF
360     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
361     S_NOP 0
362     S_NOP 0, implicit %0
363 )MIR",
364       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
365         testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
366       });
367 }
368 
369 TEST(LiveIntervalTest, MoveDownEarlyDef) {
370   liveIntervalTest(
371       R"MIR(
372     S_NOP 0
373     early-clobber %0 = IMPLICIT_DEF
374     S_NOP 0
375     S_NOP 0, implicit %0
376 )MIR",
377       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
378         testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
379       });
380 }
381 
382 TEST(LiveIntervalTest, MoveDownEarlyRedef) {
383   liveIntervalTest(
384       R"MIR(
385     %0 = IMPLICIT_DEF
386     early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
387     S_NOP 0
388     S_NOP 0, implicit %0
389 )MIR",
390       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
391         testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
392       });
393 }
394 
395 TEST(LiveIntervalTest, MoveDownKill) {
396   liveIntervalTest(
397       R"MIR(
398     %0 = IMPLICIT_DEF
399     S_NOP 0, implicit %0
400     S_NOP 0
401 )MIR",
402       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
403         testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
404       });
405 }
406 
407 TEST(LiveIntervalTest, MoveDownKillFollowing) {
408   liveIntervalTest(
409       R"MIR(
410     %0 = IMPLICIT_DEF
411     S_NOP 0
412     S_NOP 0, implicit %0
413     S_NOP 0, implicit %0
414 )MIR",
415       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
416         testHandleMove(MF, LISWrapper.getLIS(), 1, 2);
417       });
418 }
419 
420 TEST(LiveIntervalTest, MoveUndefUse) {
421   liveIntervalTest(
422       R"MIR(
423     %0 = IMPLICIT_DEF
424     S_NOP 0, implicit undef %0
425     S_NOP 0, implicit %0
426     S_NOP 0
427 )MIR",
428       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
429         testHandleMove(MF, LISWrapper.getLIS(), 1, 3);
430       });
431 }
432 
433 TEST(LiveIntervalTest, MoveUpValNos) {
434   // handleMoveUp() had a bug where it would reuse the value number of the
435   // destination segment, even though we have no guarantee that this valno
436   // wasn't used in other segments.
437   liveIntervalTest(
438       R"MIR(
439     successors: %bb.1, %bb.2
440     %0 = IMPLICIT_DEF
441     S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
442     S_BRANCH %bb.1
443   bb.2:
444     S_NOP 0, implicit %0
445   bb.1:
446     successors: %bb.2
447     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
448     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
449     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
450     S_BRANCH %bb.2
451 )MIR",
452       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
453         testHandleMove(MF, LISWrapper.getLIS(), 2, 0, 2);
454       });
455 }
456 
457 TEST(LiveIntervalTest, MoveOverUndefUse0) {
458   // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
459   liveIntervalTest(
460       R"MIR(
461     %0 = IMPLICIT_DEF
462     S_NOP 0
463     S_NOP 0, implicit undef %0
464     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
465 )MIR",
466       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
467         testHandleMove(MF, LISWrapper.getLIS(), 3, 1);
468       });
469 }
470 
471 TEST(LiveIntervalTest, MoveOverUndefUse1) {
472   // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
473   liveIntervalTest(
474       R"MIR(
475     $sgpr0 = IMPLICIT_DEF
476     S_NOP 0
477     S_NOP 0, implicit undef $sgpr0
478     $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
479 )MIR",
480       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
481         testHandleMove(MF, LISWrapper.getLIS(), 3, 1);
482       });
483 }
484 
485 TEST(LiveIntervalTest, SubRegMoveDown) {
486   // Subregister ranges can have holes inside a basic block. Check for a
487   // movement of the form 32->150 in a liverange [16, 32) [100,200).
488   liveIntervalTest(
489       R"MIR(
490     successors: %bb.1, %bb.2
491     %0 = IMPLICIT_DEF
492     S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
493     S_BRANCH %bb.1
494   bb.2:
495     successors: %bb.1
496     S_NOP 0, implicit %0.sub0
497     S_NOP 0, implicit %0.sub1
498     S_NOP 0
499     undef %0.sub0 = IMPLICIT_DEF
500     %0.sub1 = IMPLICIT_DEF
501   bb.1:
502     S_NOP 0, implicit %0
503 )MIR",
504       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
505         // Scheduler behaviour: Clear def,read-undef flag and move.
506         MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
507         MI.getOperand(0).setIsUndef(false);
508         testHandleMove(MF, LISWrapper.getLIS(), 1, 4, /*BlockNum=*/1);
509       });
510 }
511 
512 TEST(LiveIntervalTest, SubRegMoveUp) {
513   // handleMoveUp had a bug not updating valno of segment incoming to bb.2
514   // after swapping subreg definitions.
515   liveIntervalTest(
516       R"MIR(
517     successors: %bb.1, %bb.2
518     undef %0.sub0 = IMPLICIT_DEF
519     %0.sub1 = IMPLICIT_DEF
520     S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
521     S_BRANCH %bb.1
522   bb.1:
523     S_NOP 0, implicit %0.sub1
524   bb.2:
525     S_NOP 0, implicit %0.sub1
526 )MIR",
527       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
528         testHandleMove(MF, LISWrapper.getLIS(), 1, 0);
529       });
530 }
531 
532 TEST(LiveIntervalTest, DeadSubRegMoveUp) {
533   // handleMoveUp had a bug where moving a dead subreg def into the middle of
534   // an earlier segment resulted in an invalid live range.
535   liveIntervalTest(
536       R"MIR(
537     undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
538     %125.sub1:vreg_128 = COPY %125.sub0
539     %125.sub2:vreg_128 = COPY %125.sub0
540     undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
541     %51.sub1:vreg_128 = COPY %51.sub0
542     %51.sub2:vreg_128 = COPY %51.sub0
543     %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
544     %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
545     %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
546     %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
547     %60:vgpr_32 = nofpexcept V_MAD_F32_e64 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $mode, implicit $exec
548     %63:vgpr_32 = nofpexcept V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $mode, implicit $exec
549     dead %66:vgpr_32 = nofpexcept V_MAD_F32_e64 0, %60, 0, undef %67:vgpr_32, 0, %125.sub2, 0, 0, implicit $mode, implicit $exec
550     undef %124.sub1:vreg_128 = nofpexcept V_MAD_F32_e64 0, %57, 0, undef %70:vgpr_32, 0, %125.sub1, 0, 0, implicit $mode, implicit $exec
551     %124.sub0:vreg_128 = nofpexcept V_MAD_F32_e64 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $mode, implicit $exec
552     dead undef %125.sub3:vreg_128 = nofpexcept V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $mode, implicit $exec
553 )MIR",
554       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
555         testHandleMove(MF, LISWrapper.getLIS(), 15, 12);
556       });
557 }
558 
559 TEST(LiveIntervalTest, EarlyClobberSubRegMoveUp) {
560   // handleMoveUp had a bug where moving an early-clobber subreg def into the
561   // middle of an earlier segment resulted in an invalid live range.
562   liveIntervalTest(
563       R"MIR(
564     %4:sreg_32 = IMPLICIT_DEF
565     %6:sreg_32 = IMPLICIT_DEF
566     undef early-clobber %9.sub0:sreg_64 = STRICT_WWM %4:sreg_32, implicit $exec
567     %5:sreg_32 = S_FLBIT_I32_B32 %9.sub0:sreg_64
568     early-clobber %9.sub1:sreg_64 = STRICT_WWM %6:sreg_32, implicit $exec
569     %7:sreg_32 = S_FLBIT_I32_B32 %9.sub1:sreg_64
570 )MIR",
571       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
572         testHandleMove(MF, LISWrapper.getLIS(), 4, 3);
573       });
574 }
575 
576 TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) {
577   liveIntervalTest(
578       R"MIR(
579     %1:vreg_64 = IMPLICIT_DEF
580 
581   bb.1:
582     %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
583     %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
584     undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec
585     %1.sub1:vreg_64 = COPY %2
586     S_NOP 0, implicit %1.sub1
587     S_BRANCH %bb.1
588 
589 )MIR",
590       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
591         MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
592         // The scheduler clears undef from subregister defs before moving
593         UndefSubregDef.getOperand(0).setIsUndef(false);
594         testHandleMove(MF, LISWrapper.getLIS(), 3, 1, 1);
595       });
596 }
597 
598 TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDefMulti) {
599   liveIntervalTest(
600       R"MIR(
601     %1:vreg_96 = IMPLICIT_DEF
602 
603   bb.1:
604     %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
605     %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
606     undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec
607     %1.sub1:vreg_96 = COPY %2
608     %1.sub2:vreg_96 = COPY %2
609     S_NOP 0, implicit %1.sub1, implicit %1.sub2
610     S_BRANCH %bb.1
611 
612 )MIR",
613       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
614         MachineInstr &UndefSubregDef = getMI(MF, 2, 1);
615         // The scheduler clears undef from subregister defs before moving
616         UndefSubregDef.getOperand(0).setIsUndef(false);
617         testHandleMove(MF, LISWrapper.getLIS(), 4, 1, 1);
618       });
619 }
620 
621 TEST(LiveIntervalTest, TestMoveSubRegUseAcrossMainRangeHole) {
622   liveIntervalTest(
623       R"MIR(
624     %1:sgpr_128 = IMPLICIT_DEF
625   bb.1:
626     %2:sgpr_32 = COPY %1.sub2
627     %3:sgpr_32 = COPY %1.sub1
628     %1.sub2 = COPY %2
629     undef %1.sub0 = IMPLICIT_DEF
630     %1.sub2 = IMPLICIT_DEF
631     S_CBRANCH_SCC1 %bb.1, implicit undef $scc
632     S_BRANCH %bb.2
633   bb.2:
634 )MIR",
635       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
636         MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1);
637         MI.getOperand(0).setIsUndef(false);
638         testHandleMove(MF, LISWrapper.getLIS(), 4, 3, 1);
639         testHandleMove(MF, LISWrapper.getLIS(), 1, 4, 1);
640       });
641 }
642 
643 TEST(LiveIntervalTest, TestMoveSubRegsOfOneReg) {
644   liveIntervalTest(
645       R"MIR(
646     INLINEASM &"", 0, 1835018, def undef %4.sub0:vreg_64, 1835018, def undef %4.sub1:vreg_64
647     %1:vreg_64 = COPY %4
648     undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec
649     %2.sub1:vreg_64 = COPY %2.sub0
650     %3:vreg_64 = COPY %2
651 )MIR",
652       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
653         testHandleMove(MF, LISWrapper.getLIS(), 1, 4);
654         testHandleMove(MF, LISWrapper.getLIS(), 0, 3);
655       });
656 }
657 
658 TEST(LiveIntervalTest, BundleUse) {
659   liveIntervalTest(
660       R"MIR(
661     %0 = IMPLICIT_DEF
662     S_NOP 0
663     S_NOP 0, implicit %0
664     S_NOP 0
665 )MIR",
666       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
667         testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);
668       });
669 }
670 
671 TEST(LiveIntervalTest, BundleDef) {
672   liveIntervalTest(
673       R"MIR(
674     %0 = IMPLICIT_DEF
675     S_NOP 0
676     S_NOP 0, implicit %0
677     S_NOP 0
678 )MIR",
679       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
680         testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1);
681       });
682 }
683 
684 TEST(LiveIntervalTest, BundleRedef) {
685   liveIntervalTest(
686       R"MIR(
687     %0 = IMPLICIT_DEF
688     S_NOP 0
689     %0 = IMPLICIT_DEF implicit %0(tied-def 0)
690     S_NOP 0, implicit %0
691 )MIR",
692       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
693         testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);
694       });
695 }
696 
697 TEST(LiveIntervalTest, BundleInternalUse) {
698   liveIntervalTest(
699       R"MIR(
700     %0 = IMPLICIT_DEF
701     S_NOP 0
702     S_NOP 0, implicit %0
703     S_NOP 0
704 )MIR",
705       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
706         testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 2);
707       });
708 }
709 
710 TEST(LiveIntervalTest, BundleUndefUse) {
711   liveIntervalTest(
712       R"MIR(
713     %0 = IMPLICIT_DEF
714     S_NOP 0
715     S_NOP 0, implicit undef %0
716     S_NOP 0
717 )MIR",
718       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
719         testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);
720       });
721 }
722 
723 TEST(LiveIntervalTest, BundleSubRegUse) {
724   liveIntervalTest(
725       R"MIR(
726     successors: %bb.1, %bb.2
727     undef %0.sub0 = IMPLICIT_DEF
728     %0.sub1 = IMPLICIT_DEF
729     S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
730     S_BRANCH %bb.1
731   bb.1:
732     S_NOP 0
733     S_NOP 0, implicit %0.sub1
734   bb.2:
735     S_NOP 0, implicit %0.sub1
736 )MIR",
737       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
738         testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1, 1);
739       });
740 }
741 
742 TEST(LiveIntervalTest, BundleSubRegDef) {
743   liveIntervalTest(
744       R"MIR(
745     successors: %bb.1, %bb.2
746     undef %0.sub0 = IMPLICIT_DEF
747     %0.sub1 = IMPLICIT_DEF
748     S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
749     S_BRANCH %bb.1
750   bb.1:
751     S_NOP 0
752     S_NOP 0, implicit %0.sub1
753   bb.2:
754     S_NOP 0, implicit %0.sub1
755 )MIR",
756       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
757         testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1, 0);
758       });
759 }
760 
761 TEST(LiveIntervalTest, SplitAtOneInstruction) {
762   liveIntervalTest(
763       R"MIR(
764     successors: %bb.1
765     %0 = IMPLICIT_DEF
766     S_BRANCH %bb.1
767   bb.1:
768     S_NOP 0
769 )MIR",
770       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
771         testSplitAt(MF, LISWrapper.getLIS(), 1, 0);
772       });
773 }
774 
775 TEST(LiveIntervalTest, SplitAtMultiInstruction) {
776   liveIntervalTest(
777       R"MIR(
778     successors: %bb.1
779     %0 = IMPLICIT_DEF
780     S_NOP 0
781     S_NOP 0
782     S_NOP 0
783     S_NOP 0
784     S_BRANCH %bb.1
785   bb.1:
786     S_NOP 0
787 )MIR",
788       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
789         testSplitAt(MF, LISWrapper.getLIS(), 0, 0);
790       });
791 }
792 
793 TEST(LiveIntervalTest, RepairIntervals) {
794   liveIntervalTest(
795       R"MIR(
796   %1:sgpr_32 = IMPLICIT_DEF
797   dead %2:sgpr_32 = COPY undef %3.sub0:sgpr_128
798   undef %4.sub2:sgpr_128 = COPY %1:sgpr_32
799   %5:sgpr_32 = COPY %4.sub2:sgpr_128
800 )MIR",
801       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
802         auto &LIS = LISWrapper.getLIS();
803         MachineInstr &Instr1 = getMI(MF, 1, 0);
804         MachineInstr &Instr2 = getMI(MF, 2, 0);
805         MachineInstr &Instr3 = getMI(MF, 3, 0);
806         LIS.RemoveMachineInstrFromMaps(Instr2);
807         MachineBasicBlock *MBB = Instr1.getParent();
808         SmallVector<Register> OrigRegs{
809             Instr1.getOperand(0).getReg(),
810             Instr2.getOperand(0).getReg(),
811             Instr2.getOperand(1).getReg(),
812         };
813         LIS.repairIntervalsInRange(MBB, Instr2, Instr3, OrigRegs);
814       });
815 }
816 
817 TEST(LiveIntervalTest, AdjacentIntervals) {
818   liveIntervalTest(
819       R"MIR(
820     successors: %bb.1, %bb.2
821 
822     $vgpr1 = IMPLICIT_DEF
823     S_NOP 0, implicit $vgpr1
824     %1:vgpr_32 = IMPLICIT_DEF
825     %2:vgpr_32 = IMPLICIT_DEF
826     S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
827     S_BRANCH %bb.1
828   bb.1:
829     $vgpr0, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec
830     S_NOP 0, implicit $vgpr0
831     S_BRANCH %bb.3
832   bb.2:
833     $vgpr0 = IMPLICIT_DEF
834     $vgpr1, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec
835     S_NOP 0, implicit $vgpr0, implicit $vgpr1
836     S_BRANCH %bb.3
837   bb.3:
838 )MIR",
839       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
840         auto &LIS = LISWrapper.getLIS();
841         const auto &R1 =
842             LIS.getInterval(getMI(MF, 2, 0).getOperand(0).getReg());
843         const auto &R2 =
844             LIS.getInterval(getMI(MF, 3, 0).getOperand(0).getReg());
845         MCRegister V1 = getMI(MF, 1, 2).getOperand(0).getReg().asMCReg();
846 
847         ASSERT_FALSE(checkRegUnitInterference(
848             LIS, *MF.getSubtarget().getRegisterInfo(), R1, V1));
849         ASSERT_FALSE(checkRegUnitInterference(
850             LIS, *MF.getSubtarget().getRegisterInfo(), R2, V1));
851       });
852 }
853 
854 TEST(LiveIntervalTest, LiveThroughSegments) {
855   liveIntervalTest(
856       R"MIR(
857     %0 = IMPLICIT_DEF
858     S_BRANCH %bb.2
859   bb.1:
860     S_NOP 0, implicit %0
861     S_ENDPGM 0
862   bb.2:
863     S_BRANCH %bb.1
864 )MIR",
865       [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {
866         auto &LIS = LISWrapper.getLIS();
867         MachineInstr &ImpDef = getMI(MF, 0, 0);
868         MachineInstr &Nop = getMI(MF, 0, 1);
869         LiveInterval &LI = LIS.getInterval(ImpDef.getOperand(0).getReg());
870         SlotIndex OrigIdx = LIS.getInstructionIndex(ImpDef).getRegSlot();
871         LiveInterval::iterator FirstSeg = LI.FindSegmentContaining(OrigIdx);
872 
873         // %0 is live through bb.2. Move its def into bb.1 and update LIS but do
874         // not remove the segment for bb.2. This should cause machine
875         // verification to fail.
876         LIS.RemoveMachineInstrFromMaps(ImpDef);
877         ImpDef.moveBefore(&Nop);
878         LIS.InsertMachineInstrInMaps(ImpDef);
879 
880         SlotIndex NewIdx = LIS.getInstructionIndex(ImpDef).getRegSlot();
881         FirstSeg->start = NewIdx;
882         FirstSeg->valno->def = NewIdx;
883       },
884       false);
885 }
886 
887 TEST(LiveVariablesTest, recomputeForSingleDefVirtReg_handle_undef1) {
888   liveVariablesTest(
889       R"MIR(
890     %0 = IMPLICIT_DEF
891     S_NOP 0, implicit %0
892     S_NOP 0, implicit undef %0
893 )MIR",
894       [](MachineFunction &MF, LiveVariablesWrapperPass &LVWrapper) {
895         auto &LV = LVWrapper.getLV();
896         auto &FirstNop = getMI(MF, 1, 0);
897         auto &SecondNop = getMI(MF, 2, 0);
898         EXPECT_TRUE(FirstNop.getOperand(1).isKill());
899         EXPECT_FALSE(SecondNop.getOperand(1).isKill());
900 
901         Register R = Register::index2VirtReg(0);
902         LV.recomputeForSingleDefVirtReg(R);
903 
904         EXPECT_TRUE(FirstNop.getOperand(1).isKill());
905         EXPECT_FALSE(SecondNop.getOperand(1).isKill());
906       });
907 }
908 
909 TEST(LiveVariablesTest, recomputeForSingleDefVirtReg_handle_undef2) {
910   liveVariablesTest(
911       R"MIR(
912     %0 = IMPLICIT_DEF
913     S_NOP 0, implicit %0
914     S_NOP 0, implicit undef %0, implicit %0
915 )MIR",
916       [](MachineFunction &MF, LiveVariablesWrapperPass &LVWrapper) {
917         auto &LV = LVWrapper.getLV();
918         auto &FirstNop = getMI(MF, 1, 0);
919         auto &SecondNop = getMI(MF, 2, 0);
920         EXPECT_FALSE(FirstNop.getOperand(1).isKill());
921         EXPECT_FALSE(SecondNop.getOperand(1).isKill());
922         EXPECT_TRUE(SecondNop.getOperand(2).isKill());
923 
924         Register R = Register::index2VirtReg(0);
925         LV.recomputeForSingleDefVirtReg(R);
926 
927         EXPECT_FALSE(FirstNop.getOperand(1).isKill());
928         EXPECT_FALSE(SecondNop.getOperand(1).isKill());
929         EXPECT_TRUE(SecondNop.getOperand(2).isKill());
930       });
931 }
932 
933 int main(int argc, char **argv) {
934   ::testing::InitGoogleTest(&argc, argv);
935   initLLVM();
936   return RUN_ALL_TESTS();
937 }
938