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"
20 #include "../lib/CodeGen/RegisterCoalescer.h"
25 void initializeTestPassPass(PassRegistry
&);
31 InitializeAllTargets();
32 InitializeAllTargetMCs();
33 InitializeAllAsmPrinters();
34 InitializeAllAsmParsers();
36 PassRegistry
*Registry
= PassRegistry::getPassRegistry();
37 initializeCore(*Registry
);
38 initializeCodeGen(*Registry
);
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
44 std::unique_ptr
<TargetMachine
> createTargetMachine() {
45 Triple
TargetTriple("amdgcn--");
47 const Target
*T
= TargetRegistry::lookupTarget("", TargetTriple
, Error
);
51 TargetOptions Options
;
52 return std::unique_ptr
<TargetMachine
>(
53 T
->createTargetMachine("AMDGPU", "gfx900", "", Options
, std::nullopt
,
54 std::nullopt
, CodeGenOptLevel::Aggressive
));
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
);
67 std::unique_ptr
<Module
> M
= MIR
->parseIRModule();
71 M
->setDataLayout(TM
.createDataLayout());
73 MachineModuleInfoWrapperPass
*MMIWP
= new MachineModuleInfoWrapperPass(&TM
);
74 if (MIR
->parseMachineFunctions(*M
, MMIWP
->getMMI()))
81 struct TestPass
: public MachineFunctionPass
{
83 TestPass() : MachineFunctionPass(ID
) {}
86 template <typename AnalysisType
>
87 struct TestPassT
: public TestPass
{
89 typedef std::function
<void(MachineFunction
&,AnalysisType
&)> TestFx
;
92 // We should never call this but always use PM.add(new TestPass(...))
95 TestPassT(TestFx T
, bool ShouldPass
)
96 : T(T
), ShouldPass(ShouldPass
) {
97 initializeTestPassPass(*PassRegistry::getPassRegistry());
100 bool runOnMachineFunction(MachineFunction
&MF
) override
{
101 AnalysisType
&A
= getAnalysis
<AnalysisType
>();
103 EXPECT_EQ(MF
.verify(this, /* Banner=*/nullptr,
105 /* AbortOnError=*/false),
110 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
111 AU
.setPreservesAll();
112 AU
.addRequired
<AnalysisType
>();
113 AU
.addPreserved
<AnalysisType
>();
114 MachineFunctionPass::getAnalysisUsage(AU
);
121 static MachineInstr
&getMI(MachineFunction
&MF
, unsigned At
,
123 MachineBasicBlock
&MBB
= *MF
.getBlockNumbered(BlockNum
);
126 for (MachineInstr
&MI
: MBB
) {
131 llvm_unreachable("Instruction not found");
135 * Move instruction number \p From in front of instruction number \p To and
136 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
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
);
143 MachineBasicBlock
&MBB
= *FromInstr
.getParent();
144 MBB
.splice(ToInstr
.getIterator(), &MBB
, FromInstr
.getIterator());
145 LIS
.handleMove(FromInstr
, true);
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().
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();
162 finalizeBundle(MBB
, I
, std::next(ToInstr
.getIterator()));
163 MF
.getProperties().reset(MachineFunctionProperties::Property::IsSSA
);
165 // Update LiveIntervals
166 MachineBasicBlock::instr_iterator BundleStart
= std::prev(I
);
167 LIS
.handleMoveIntoNewBundle(*BundleStart
, true);
171 * Split block numbered \p BlockNum at instruction \p SplitAt using
172 * MachineBasicBlock::splitAt updating liveness intervals.
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();
179 // Split block and update live intervals
180 MBB
.splitAt(SplitInstr
, false, &LIS
);
184 * Helper function to test for interference between a hard register and a
185 * virtual register live ranges.
187 static bool checkRegUnitInterference(LiveIntervals
&LIS
,
188 const TargetRegisterInfo
&TRI
,
189 const LiveInterval
&VirtReg
,
190 MCRegister PhysReg
) {
193 CoalescerPair
CP(VirtReg
.reg(), PhysReg
, TRI
);
195 for (MCRegUnit Unit
: TRI
.regunits(PhysReg
)) {
196 const LiveRange
&UnitRange
= LIS
.getRegUnit(Unit
);
197 if (VirtReg
.overlaps(UnitRange
, CP
, *LIS
.getSlotIndexes()))
203 template <typename AnalysisType
>
204 static void doTest(StringRef MIRFunc
,
205 typename TestPassT
<AnalysisType
>::TestFx T
,
206 bool ShouldPass
= true) {
208 std::unique_ptr
<TargetMachine
> TM
= createTargetMachine();
209 // This test is designed for the X86 backend; stop if it is not available.
213 legacy::PassManager PM
;
214 std::unique_ptr
<MIRParser
> MIR
;
215 std::unique_ptr
<Module
> M
= parseMIR(Context
, PM
, MIR
, *TM
, MIRFunc
);
218 PM
.add(new TestPassT
<AnalysisType
>(T
, ShouldPass
));
223 static void liveIntervalTest(StringRef MIRFunc
,
224 TestPassT
<LiveIntervalsWrapperPass
>::TestFx T
,
225 bool ShouldPass
= true) {
227 StringRef MIRString
= (Twine(R
"MIR(
232 - { id: 0, class: sreg_64 }
235 )MIR") + Twine(MIRFunc
) + Twine("...\n")).toNullTerminatedStringRef(S
);
237 doTest
<LiveIntervalsWrapperPass
>(MIRString
, T
, ShouldPass
);
240 static void liveVariablesTest(StringRef MIRFunc
,
241 TestPassT
<LiveVariablesWrapperPass
>::TestFx T
,
242 bool ShouldPass
= true) {
244 StringRef MIRString
= (Twine(R
"MIR(
248 tracksRegLiveness: true
250 - { id: 0, class: sreg_64 }
253 )MIR") + Twine(MIRFunc
) + Twine("...\n")).toNullTerminatedStringRef(S
);
254 doTest
<LiveVariablesWrapperPass
>(MIRString
, T
, ShouldPass
);
257 } // End of anonymous namespace.
259 char TestPass::ID
= 0;
260 INITIALIZE_PASS(TestPass
, "testpass", "testpass", false, false)
262 TEST(LiveIntervalTest
, MoveUpDef
) {
268 early-clobber %0 = IMPLICIT_DEF
271 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
272 testHandleMove(MF
, LISWrapper
.getLIS(), 2, 1);
276 TEST(LiveIntervalTest
, MoveUpRedef
) {
277 liveIntervalTest(R
"MIR(
280 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
283 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LIS
) {
284 testHandleMove(MF
, LIS
.getLIS(), 2, 1);
288 TEST(LiveIntervalTest
, MoveUpEarlyDef
) {
293 early-clobber %0 = IMPLICIT_DEF
296 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
297 testHandleMove(MF
, LISWrapper
.getLIS(), 2, 1);
301 TEST(LiveIntervalTest
, MoveUpEarlyRedef
) {
306 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
309 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
310 testHandleMove(MF
, LISWrapper
.getLIS(), 2, 1);
314 TEST(LiveIntervalTest
, MoveUpKill
) {
321 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
322 testHandleMove(MF
, LISWrapper
.getLIS(), 2, 1);
326 TEST(LiveIntervalTest
, MoveUpKillFollowing
) {
334 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
335 testHandleMove(MF
, LISWrapper
.getLIS(), 2, 1);
339 // TODO: Construct a situation where we have intervals following a hole
340 // while still having connected components.
342 TEST(LiveIntervalTest
, MoveDownDef
) {
347 early-clobber %0 = IMPLICIT_DEF
351 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
352 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 2);
356 TEST(LiveIntervalTest
, MoveDownRedef
) {
360 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
364 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
365 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 2);
369 TEST(LiveIntervalTest
, MoveDownEarlyDef
) {
373 early-clobber %0 = IMPLICIT_DEF
377 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
378 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 2);
382 TEST(LiveIntervalTest
, MoveDownEarlyRedef
) {
386 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
390 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
391 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 2);
395 TEST(LiveIntervalTest
, MoveDownKill
) {
402 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
403 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 2);
407 TEST(LiveIntervalTest
, MoveDownKillFollowing
) {
415 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
416 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 2);
420 TEST(LiveIntervalTest
, MoveUndefUse
) {
424 S_NOP 0, implicit undef %0
428 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
429 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 3);
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.
439 successors: %bb.1, %bb.2
441 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
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)
452 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
453 testHandleMove(MF
, LISWrapper
.getLIS(), 2, 0, 2);
457 TEST(LiveIntervalTest
, MoveOverUndefUse0
) {
458 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
463 S_NOP 0, implicit undef %0
464 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
466 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
467 testHandleMove(MF
, LISWrapper
.getLIS(), 3, 1);
471 TEST(LiveIntervalTest
, MoveOverUndefUse1
) {
472 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
475 $sgpr0 = IMPLICIT_DEF
477 S_NOP 0, implicit undef $sgpr0
478 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
480 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
481 testHandleMove(MF
, LISWrapper
.getLIS(), 3, 1);
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).
490 successors: %bb.1, %bb.2
492 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
496 S_NOP 0, implicit %0.sub0
497 S_NOP 0, implicit %0.sub1
499 undef %0.sub0 = IMPLICIT_DEF
500 %0.sub1 = IMPLICIT_DEF
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);
512 TEST(LiveIntervalTest
, SubRegMoveUp
) {
513 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
514 // after swapping subreg definitions.
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
523 S_NOP 0, implicit %0.sub1
525 S_NOP 0, implicit %0.sub1
527 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
528 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 0);
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.
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
554 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
555 testHandleMove(MF
, LISWrapper
.getLIS(), 15, 12);
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.
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
571 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
572 testHandleMove(MF
, LISWrapper
.getLIS(), 4, 3);
576 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDef
) {
579 %1:vreg_64 = IMPLICIT_DEF
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
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);
598 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDefMulti
) {
601 %1:vreg_96 = IMPLICIT_DEF
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
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);
621 TEST(LiveIntervalTest
, TestMoveSubRegUseAcrossMainRangeHole
) {
624 %1:sgpr_128 = IMPLICIT_DEF
626 %2:sgpr_32 = COPY %1.sub2
627 %3:sgpr_32 = COPY %1.sub1
629 undef %1.sub0 = IMPLICIT_DEF
630 %1.sub2 = IMPLICIT_DEF
631 S_CBRANCH_SCC1 %bb.1, implicit undef $scc
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);
643 TEST(LiveIntervalTest
, TestMoveSubRegsOfOneReg
) {
646 INLINEASM &"", 0, 1835018, def undef %4.sub0:vreg_64, 1835018, def undef %4.sub1:vreg_64
648 undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec
649 %2.sub1:vreg_64 = COPY %2.sub0
652 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
653 testHandleMove(MF
, LISWrapper
.getLIS(), 1, 4);
654 testHandleMove(MF
, LISWrapper
.getLIS(), 0, 3);
658 TEST(LiveIntervalTest
, BundleUse
) {
666 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
667 testHandleMoveIntoNewBundle(MF
, LISWrapper
.getLIS(), 1, 2);
671 TEST(LiveIntervalTest
, BundleDef
) {
679 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
680 testHandleMoveIntoNewBundle(MF
, LISWrapper
.getLIS(), 0, 1);
684 TEST(LiveIntervalTest
, BundleRedef
) {
689 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
692 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
693 testHandleMoveIntoNewBundle(MF
, LISWrapper
.getLIS(), 1, 2);
697 TEST(LiveIntervalTest
, BundleInternalUse
) {
705 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
706 testHandleMoveIntoNewBundle(MF
, LISWrapper
.getLIS(), 0, 2);
710 TEST(LiveIntervalTest
, BundleUndefUse
) {
715 S_NOP 0, implicit undef %0
718 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
719 testHandleMoveIntoNewBundle(MF
, LISWrapper
.getLIS(), 1, 2);
723 TEST(LiveIntervalTest
, BundleSubRegUse
) {
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
733 S_NOP 0, implicit %0.sub1
735 S_NOP 0, implicit %0.sub1
737 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
738 testHandleMoveIntoNewBundle(MF
, LISWrapper
.getLIS(), 0, 1, 1);
742 TEST(LiveIntervalTest
, BundleSubRegDef
) {
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
752 S_NOP 0, implicit %0.sub1
754 S_NOP 0, implicit %0.sub1
756 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
757 testHandleMoveIntoNewBundle(MF
, LISWrapper
.getLIS(), 0, 1, 0);
761 TEST(LiveIntervalTest
, SplitAtOneInstruction
) {
770 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
771 testSplitAt(MF
, LISWrapper
.getLIS(), 1, 0);
775 TEST(LiveIntervalTest
, SplitAtMultiInstruction
) {
788 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
789 testSplitAt(MF
, LISWrapper
.getLIS(), 0, 0);
793 TEST(LiveIntervalTest
, RepairIntervals
) {
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
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(),
813 LIS
.repairIntervalsInRange(MBB
, Instr2
, Instr3
, OrigRegs
);
817 TEST(LiveIntervalTest
, AdjacentIntervals
) {
820 successors: %bb.1, %bb.2
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
829 $vgpr0, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec
830 S_NOP 0, implicit $vgpr0
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
839 [](MachineFunction
&MF
, LiveIntervalsWrapperPass
&LISWrapper
) {
840 auto &LIS
= LISWrapper
.getLIS();
842 LIS
.getInterval(getMI(MF
, 2, 0).getOperand(0).getReg());
844 LIS
.getInterval(getMI(MF
, 3, 0).getOperand(0).getReg());
845 MCRegister V1
= getMI(MF
, 1, 2).getOperand(0).getReg().asMCReg();
847 ASSERT_FALSE(checkRegUnitInterference(
848 LIS
, *MF
.getSubtarget().getRegisterInfo(), R1
, V1
));
849 ASSERT_FALSE(checkRegUnitInterference(
850 LIS
, *MF
.getSubtarget().getRegisterInfo(), R2
, V1
));
854 TEST(LiveIntervalTest
, LiveThroughSegments
) {
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
);
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
);
880 SlotIndex NewIdx
= LIS
.getInstructionIndex(ImpDef
).getRegSlot();
881 FirstSeg
->start
= NewIdx
;
882 FirstSeg
->valno
->def
= NewIdx
;
887 TEST(LiveVariablesTest
, recomputeForSingleDefVirtReg_handle_undef1
) {
892 S_NOP 0, implicit undef %0
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());
901 Register R
= Register::index2VirtReg(0);
902 LV
.recomputeForSingleDefVirtReg(R
);
904 EXPECT_TRUE(FirstNop
.getOperand(1).isKill());
905 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
909 TEST(LiveVariablesTest
, recomputeForSingleDefVirtReg_handle_undef2
) {
914 S_NOP 0, implicit undef %0, implicit %0
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());
924 Register R
= Register::index2VirtReg(0);
925 LV
.recomputeForSingleDefVirtReg(R
);
927 EXPECT_FALSE(FirstNop
.getOperand(1).isKill());
928 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
929 EXPECT_TRUE(SecondNop
.getOperand(2).isKill());
933 int main(int argc
, char **argv
) {
934 ::testing::InitGoogleTest(&argc
, argv
);
936 return RUN_ALL_TESTS();