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/MC/TargetRegistry.h"
10 #include "llvm/Support/MemoryBuffer.h"
11 #include "llvm/Support/SourceMgr.h"
12 #include "llvm/Support/TargetSelect.h"
13 #include "llvm/Target/TargetMachine.h"
14 #include "llvm/Target/TargetOptions.h"
15 #include "gtest/gtest.h"
20 void initializeTestPassPass(PassRegistry
&);
26 InitializeAllTargets();
27 InitializeAllTargetMCs();
28 InitializeAllAsmPrinters();
29 InitializeAllAsmParsers();
31 PassRegistry
*Registry
= PassRegistry::getPassRegistry();
32 initializeCore(*Registry
);
33 initializeCodeGen(*Registry
);
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
39 std::unique_ptr
<LLVMTargetMachine
> createTargetMachine() {
40 Triple
TargetTriple("amdgcn--");
42 const Target
*T
= TargetRegistry::lookupTarget("", TargetTriple
, Error
);
46 TargetOptions Options
;
47 return std::unique_ptr
<LLVMTargetMachine
>(static_cast<LLVMTargetMachine
*>(
48 T
->createTargetMachine("AMDGPU", "gfx900", "", Options
, None
, None
,
49 CodeGenOpt::Aggressive
)));
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
);
61 std::unique_ptr
<Module
> M
= MIR
->parseIRModule();
65 M
->setDataLayout(TM
.createDataLayout());
67 MachineModuleInfoWrapperPass
*MMIWP
= new MachineModuleInfoWrapperPass(&TM
);
68 if (MIR
->parseMachineFunctions(*M
, MMIWP
->getMMI()))
75 typedef std::function
<void(MachineFunction
&,LiveIntervals
&)> LiveIntervalTest
;
77 struct TestPass
: public MachineFunctionPass
{
79 TestPass() : MachineFunctionPass(ID
) {
80 // We should never call this but always use PM.add(new TestPass(...))
83 TestPass(LiveIntervalTest T
) : MachineFunctionPass(ID
), T(T
) {
84 initializeTestPassPass(*PassRegistry::getPassRegistry());
87 bool runOnMachineFunction(MachineFunction
&MF
) override
{
88 LiveIntervals
&LIS
= getAnalysis
<LiveIntervals
>();
90 EXPECT_TRUE(MF
.verify(this));
94 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
96 AU
.addRequired
<LiveIntervals
>();
97 AU
.addPreserved
<LiveIntervals
>();
98 MachineFunctionPass::getAnalysisUsage(AU
);
104 static MachineInstr
&getMI(MachineFunction
&MF
, unsigned At
,
106 MachineBasicBlock
&MBB
= *MF
.getBlockNumbered(BlockNum
);
109 for (MachineInstr
&MI
: MBB
) {
114 llvm_unreachable("Instruction not found");
118 * Move instruction number \p From in front of instruction number \p To and
119 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
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
);
126 MachineBasicBlock
&MBB
= *FromInstr
.getParent();
127 MBB
.splice(ToInstr
.getIterator(), &MBB
, FromInstr
.getIterator());
128 LIS
.handleMove(FromInstr
, true);
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().
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();
145 finalizeBundle(MBB
, I
, std::next(ToInstr
.getIterator()));
147 // Update LiveIntervals
148 MachineBasicBlock::instr_iterator BundleStart
= std::prev(I
);
149 LIS
.handleMoveIntoNewBundle(*BundleStart
, true);
153 * Split block numbered \p BlockNum at instruction \p SplitAt using
154 * MachineBasicBlock::splitAt updating liveness intervals.
156 static void testSplitAt(MachineFunction
&MF
, LiveIntervals
&LIS
,
157 unsigned SplitAt
, unsigned BlockNum
) {
158 MachineInstr
&SplitInstr
= getMI(MF
, SplitAt
, BlockNum
);
159 MachineBasicBlock
&MBB
= *SplitInstr
.getParent();
161 // Split block and update live intervals
162 MBB
.splitAt(SplitInstr
, false, &LIS
);
165 static void liveIntervalTest(StringRef MIRFunc
, LiveIntervalTest T
) {
167 std::unique_ptr
<LLVMTargetMachine
> TM
= createTargetMachine();
168 // This test is designed for the X86 backend; stop if it is not available.
172 legacy::PassManager PM
;
175 StringRef MIRString
= (Twine(R
"MIR(
180 - { id: 0, class: sreg_64 }
183 )MIR") + Twine(MIRFunc
) + Twine("...\n")).toNullTerminatedStringRef(S
);
184 std::unique_ptr
<MIRParser
> MIR
;
185 std::unique_ptr
<Module
> M
= parseMIR(Context
, PM
, MIR
, *TM
, MIRString
,
189 PM
.add(new TestPass(T
));
194 } // End of anonymous namespace.
196 char TestPass::ID
= 0;
197 INITIALIZE_PASS(TestPass
, "testpass", "testpass", false, false)
199 TEST(LiveIntervalTest
, MoveUpDef
) {
201 liveIntervalTest(R
"MIR(
204 early-clobber %0 = IMPLICIT_DEF
206 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
207 testHandleMove(MF
, LIS
, 2, 1);
211 TEST(LiveIntervalTest
, MoveUpRedef
) {
212 liveIntervalTest(R
"MIR(
215 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
217 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
218 testHandleMove(MF
, LIS
, 2, 1);
222 TEST(LiveIntervalTest
, MoveUpEarlyDef
) {
223 liveIntervalTest(R
"MIR(
226 early-clobber %0 = IMPLICIT_DEF
228 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
229 testHandleMove(MF
, LIS
, 2, 1);
233 TEST(LiveIntervalTest
, MoveUpEarlyRedef
) {
234 liveIntervalTest(R
"MIR(
237 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
239 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
240 testHandleMove(MF
, LIS
, 2, 1);
244 TEST(LiveIntervalTest
, MoveUpKill
) {
245 liveIntervalTest(R
"MIR(
249 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
250 testHandleMove(MF
, LIS
, 2, 1);
254 TEST(LiveIntervalTest
, MoveUpKillFollowing
) {
255 liveIntervalTest(R
"MIR(
260 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
261 testHandleMove(MF
, LIS
, 2, 1);
265 // TODO: Construct a situation where we have intervals following a hole
266 // while still having connected components.
268 TEST(LiveIntervalTest
, MoveDownDef
) {
270 liveIntervalTest(R
"MIR(
272 early-clobber %0 = IMPLICIT_DEF
275 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
276 testHandleMove(MF
, LIS
, 1, 2);
280 TEST(LiveIntervalTest
, MoveDownRedef
) {
281 liveIntervalTest(R
"MIR(
283 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
286 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
287 testHandleMove(MF
, LIS
, 1, 2);
291 TEST(LiveIntervalTest
, MoveDownEarlyDef
) {
292 liveIntervalTest(R
"MIR(
294 early-clobber %0 = IMPLICIT_DEF
297 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
298 testHandleMove(MF
, LIS
, 1, 2);
302 TEST(LiveIntervalTest
, MoveDownEarlyRedef
) {
303 liveIntervalTest(R
"MIR(
305 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
308 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
309 testHandleMove(MF
, LIS
, 1, 2);
313 TEST(LiveIntervalTest
, MoveDownKill
) {
314 liveIntervalTest(R
"MIR(
318 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
319 testHandleMove(MF
, LIS
, 1, 2);
323 TEST(LiveIntervalTest
, MoveDownKillFollowing
) {
324 liveIntervalTest(R
"MIR(
329 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
330 testHandleMove(MF
, LIS
, 1, 2);
334 TEST(LiveIntervalTest
, MoveUndefUse
) {
335 liveIntervalTest(R
"MIR(
337 S_NOP 0, implicit undef %0
340 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
341 testHandleMove(MF
, LIS
, 1, 3);
345 TEST(LiveIntervalTest
, MoveUpValNos
) {
346 // handleMoveUp() had a bug where it would reuse the value number of the
347 // destination segment, even though we have no guarantee that this valno
348 // wasn't used in other segments.
349 liveIntervalTest(R
"MIR(
350 successors: %bb.1, %bb.2
352 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
358 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
359 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
360 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
362 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
363 testHandleMove(MF
, LIS
, 2, 0, 2);
367 TEST(LiveIntervalTest
, MoveOverUndefUse0
) {
368 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
369 liveIntervalTest(R
"MIR(
372 S_NOP 0, implicit undef %0
373 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
374 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
375 testHandleMove(MF
, LIS
, 3, 1);
379 TEST(LiveIntervalTest
, MoveOverUndefUse1
) {
380 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
381 liveIntervalTest(R
"MIR(
382 $sgpr0 = IMPLICIT_DEF
384 S_NOP 0, implicit undef $sgpr0
385 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
386 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
387 testHandleMove(MF
, LIS
, 3, 1);
391 TEST(LiveIntervalTest
, SubRegMoveDown
) {
392 // Subregister ranges can have holes inside a basic block. Check for a
393 // movement of the form 32->150 in a liverange [16, 32) [100,200).
394 liveIntervalTest(R
"MIR(
395 successors: %bb.1, %bb.2
397 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
401 S_NOP 0, implicit %0.sub0
402 S_NOP 0, implicit %0.sub1
404 undef %0.sub0 = IMPLICIT_DEF
405 %0.sub1 = IMPLICIT_DEF
408 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
409 // Scheduler behaviour: Clear def,read-undef flag and move.
410 MachineInstr
&MI
= getMI(MF
, 3, /*BlockNum=*/1);
411 MI
.getOperand(0).setIsUndef(false);
412 testHandleMove(MF
, LIS
, 1, 4, /*BlockNum=*/1);
416 TEST(LiveIntervalTest
, SubRegMoveUp
) {
417 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
418 // after swapping subreg definitions.
419 liveIntervalTest(R
"MIR(
420 successors: %bb.1, %bb.2
421 undef %0.sub0 = IMPLICIT_DEF
422 %0.sub1 = IMPLICIT_DEF
423 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
426 S_NOP 0, implicit %0.sub1
428 S_NOP 0, implicit %0.sub1
429 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
430 testHandleMove(MF
, LIS
, 1, 0);
434 TEST(LiveIntervalTest
, DeadSubRegMoveUp
) {
435 // handleMoveUp had a bug where moving a dead subreg def into the middle of
436 // an earlier segment resulted in an invalid live range.
437 liveIntervalTest(R
"MIR(
438 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
439 %125.sub1:vreg_128 = COPY %125.sub0
440 %125.sub2:vreg_128 = COPY %125.sub0
441 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
442 %51.sub1:vreg_128 = COPY %51.sub0
443 %51.sub2:vreg_128 = COPY %51.sub0
444 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
445 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
446 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
447 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
448 %60:vgpr_32 = nofpexcept V_MAD_F32_e64 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $mode, implicit $exec
449 %63:vgpr_32 = nofpexcept V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $mode, implicit $exec
450 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
451 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
452 %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
453 dead undef %125.sub3:vreg_128 = nofpexcept V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $mode, implicit $exec
454 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
455 testHandleMove(MF
, LIS
, 15, 12);
459 TEST(LiveIntervalTest
, EarlyClobberSubRegMoveUp
) {
460 // handleMoveUp had a bug where moving an early-clobber subreg def into the
461 // middle of an earlier segment resulted in an invalid live range.
462 liveIntervalTest(R
"MIR(
463 %4:sreg_32 = IMPLICIT_DEF
464 %6:sreg_32 = IMPLICIT_DEF
465 undef early-clobber %9.sub0:sreg_64 = STRICT_WWM %4:sreg_32, implicit $exec
466 %5:sreg_32 = S_FLBIT_I32_B32 %9.sub0:sreg_64
467 early-clobber %9.sub1:sreg_64 = STRICT_WWM %6:sreg_32, implicit $exec
468 %7:sreg_32 = S_FLBIT_I32_B32 %9.sub1:sreg_64
469 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
470 testHandleMove(MF
, LIS
, 4, 3);
474 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDef
) {
475 liveIntervalTest(R
"MIR(
476 %1:vreg_64 = IMPLICIT_DEF
479 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
480 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
481 undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec
482 %1.sub1:vreg_64 = COPY %2
483 S_NOP 0, implicit %1.sub1
486 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
487 MachineInstr
&UndefSubregDef
= getMI(MF
, 2, 1);
488 // The scheduler clears undef from subregister defs before moving
489 UndefSubregDef
.getOperand(0).setIsUndef(false);
490 testHandleMove(MF
, LIS
, 3, 1, 1);
494 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDefMulti
) {
495 liveIntervalTest(R
"MIR(
496 %1:vreg_96 = IMPLICIT_DEF
499 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
500 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
501 undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec
502 %1.sub1:vreg_96 = COPY %2
503 %1.sub2:vreg_96 = COPY %2
504 S_NOP 0, implicit %1.sub1, implicit %1.sub2
507 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
508 MachineInstr
&UndefSubregDef
= getMI(MF
, 2, 1);
509 // The scheduler clears undef from subregister defs before moving
510 UndefSubregDef
.getOperand(0).setIsUndef(false);
511 testHandleMove(MF
, LIS
, 4, 1, 1);
515 TEST(LiveIntervalTest
, TestMoveSubRegUseAcrossMainRangeHole
) {
516 liveIntervalTest(R
"MIR(
517 %1:sgpr_128 = IMPLICIT_DEF
519 %2:sgpr_32 = COPY %1.sub2
520 %3:sgpr_32 = COPY %1.sub1
522 undef %1.sub0 = IMPLICIT_DEF
523 %1.sub2 = IMPLICIT_DEF
524 S_CBRANCH_SCC1 %bb.1, implicit undef $scc
527 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
528 MachineInstr
&MI
= getMI(MF
, 3, /*BlockNum=*/1);
529 MI
.getOperand(0).setIsUndef(false);
530 testHandleMove(MF
, LIS
, 4, 3, 1);
531 testHandleMove(MF
, LIS
, 1, 4, 1);
535 TEST(LiveIntervalTest
, TestMoveSubRegsOfOneReg
) {
536 liveIntervalTest(R
"MIR(
537 INLINEASM &"", 0, 1835018, def undef %4.sub0:vreg_64, 1835018, def undef %4.sub1:vreg_64
539 undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec
540 %2.sub1:vreg_64 = COPY %2.sub0
542 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
543 testHandleMove(MF
, LIS
, 1, 4);
544 testHandleMove(MF
, LIS
, 0, 3);
548 TEST(LiveIntervalTest
, BundleUse
) {
549 liveIntervalTest(R
"MIR(
554 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
555 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
559 TEST(LiveIntervalTest
, BundleDef
) {
560 liveIntervalTest(R
"MIR(
565 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
566 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1);
570 TEST(LiveIntervalTest
, BundleRedef
) {
571 liveIntervalTest(R
"MIR(
574 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
576 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
577 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
581 TEST(LiveIntervalTest
, BundleInternalUse
) {
582 liveIntervalTest(R
"MIR(
587 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
588 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 2);
592 TEST(LiveIntervalTest
, BundleUndefUse
) {
593 liveIntervalTest(R
"MIR(
596 S_NOP 0, implicit undef %0
598 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
599 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
603 TEST(LiveIntervalTest
, BundleSubRegUse
) {
604 liveIntervalTest(R
"MIR(
605 successors: %bb.1, %bb.2
606 undef %0.sub0 = IMPLICIT_DEF
607 %0.sub1 = IMPLICIT_DEF
608 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
612 S_NOP 0, implicit %0.sub1
614 S_NOP 0, implicit %0.sub1
615 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
616 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1, 1);
620 TEST(LiveIntervalTest
, BundleSubRegDef
) {
621 liveIntervalTest(R
"MIR(
622 successors: %bb.1, %bb.2
623 undef %0.sub0 = IMPLICIT_DEF
624 %0.sub1 = IMPLICIT_DEF
625 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
629 S_NOP 0, implicit %0.sub1
631 S_NOP 0, implicit %0.sub1
632 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
633 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1, 0);
637 TEST(LiveIntervalTest
, SplitAtOneInstruction
) {
638 liveIntervalTest(R
"MIR(
644 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
645 testSplitAt(MF
, LIS
, 1, 0);
649 TEST(LiveIntervalTest
, SplitAtMultiInstruction
) {
650 liveIntervalTest(R
"MIR(
660 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
661 testSplitAt(MF
, LIS
, 0, 0);
665 TEST(LiveIntervalTest
, RepairIntervals
) {
666 liveIntervalTest(R
"MIR(
667 %1:sgpr_32 = IMPLICIT_DEF
668 dead %2:sgpr_32 = COPY undef %3.sub0:sgpr_128
669 undef %4.sub2:sgpr_128 = COPY %1:sgpr_32
670 %5:sgpr_32 = COPY %4.sub2:sgpr_128
671 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
672 MachineInstr
&Instr1
= getMI(MF
, 1, 0);
673 MachineInstr
&Instr2
= getMI(MF
, 2, 0);
674 MachineInstr
&Instr3
= getMI(MF
, 3, 0);
675 LIS
.RemoveMachineInstrFromMaps(Instr2
);
676 MachineBasicBlock
*MBB
= Instr1
.getParent();
677 SmallVector
<Register
> OrigRegs
{
678 Instr1
.getOperand(0).getReg(),
679 Instr2
.getOperand(0).getReg(),
680 Instr2
.getOperand(1).getReg(),
682 LIS
.repairIntervalsInRange(MBB
, Instr2
, Instr3
, OrigRegs
);
686 int main(int argc
, char **argv
) {
687 ::testing::InitGoogleTest(&argc
, argv
);
689 return RUN_ALL_TESTS();