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/InitializePasses.h"
11 #include "llvm/MC/TargetRegistry.h"
12 #include "llvm/Support/MemoryBuffer.h"
13 #include "llvm/Support/SourceMgr.h"
14 #include "llvm/Support/TargetSelect.h"
15 #include "llvm/Target/TargetMachine.h"
16 #include "llvm/Target/TargetOptions.h"
17 #include "gtest/gtest.h"
19 #include "../lib/CodeGen/RegisterCoalescer.h"
24 void initializeTestPassPass(PassRegistry
&);
30 InitializeAllTargets();
31 InitializeAllTargetMCs();
32 InitializeAllAsmPrinters();
33 InitializeAllAsmParsers();
35 PassRegistry
*Registry
= PassRegistry::getPassRegistry();
36 initializeCore(*Registry
);
37 initializeCodeGen(*Registry
);
40 /// Create a TargetMachine. As we lack a dedicated always available target for
41 /// unittests, we go for "AMDGPU" to be able to test normal and subregister
43 std::unique_ptr
<LLVMTargetMachine
> createTargetMachine() {
44 Triple
TargetTriple("amdgcn--");
46 const Target
*T
= TargetRegistry::lookupTarget("", TargetTriple
, Error
);
50 TargetOptions Options
;
51 return std::unique_ptr
<LLVMTargetMachine
>(static_cast<LLVMTargetMachine
*>(
52 T
->createTargetMachine("AMDGPU", "gfx900", "", Options
, std::nullopt
,
53 std::nullopt
, CodeGenOptLevel::Aggressive
)));
56 std::unique_ptr
<Module
> parseMIR(LLVMContext
&Context
,
57 legacy::PassManagerBase
&PM
, std::unique_ptr
<MIRParser
> &MIR
,
58 const LLVMTargetMachine
&TM
, StringRef MIRCode
, const char *FuncName
) {
59 SMDiagnostic Diagnostic
;
60 std::unique_ptr
<MemoryBuffer
> MBuffer
= MemoryBuffer::getMemBuffer(MIRCode
);
61 MIR
= createMIRParser(std::move(MBuffer
), Context
);
65 std::unique_ptr
<Module
> M
= MIR
->parseIRModule();
69 M
->setDataLayout(TM
.createDataLayout());
71 MachineModuleInfoWrapperPass
*MMIWP
= new MachineModuleInfoWrapperPass(&TM
);
72 if (MIR
->parseMachineFunctions(*M
, MMIWP
->getMMI()))
79 struct TestPass
: public MachineFunctionPass
{
81 TestPass() : MachineFunctionPass(ID
) {}
84 template <typename AnalysisType
>
85 struct TestPassT
: public TestPass
{
87 typedef std::function
<void(MachineFunction
&,AnalysisType
&)> TestFx
;
90 // We should never call this but always use PM.add(new TestPass(...))
93 TestPassT(TestFx T
, bool ShouldPass
)
94 : T(T
), ShouldPass(ShouldPass
) {
95 initializeTestPassPass(*PassRegistry::getPassRegistry());
98 bool runOnMachineFunction(MachineFunction
&MF
) override
{
99 AnalysisType
&A
= getAnalysis
<AnalysisType
>();
101 EXPECT_EQ(MF
.verify(this, /* Banner */ nullptr, /* AbortOnError */ false),
106 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
107 AU
.setPreservesAll();
108 AU
.addRequired
<AnalysisType
>();
109 AU
.addPreserved
<AnalysisType
>();
110 MachineFunctionPass::getAnalysisUsage(AU
);
117 static MachineInstr
&getMI(MachineFunction
&MF
, unsigned At
,
119 MachineBasicBlock
&MBB
= *MF
.getBlockNumbered(BlockNum
);
122 for (MachineInstr
&MI
: MBB
) {
127 llvm_unreachable("Instruction not found");
131 * Move instruction number \p From in front of instruction number \p To and
132 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().
134 static void testHandleMove(MachineFunction
&MF
, LiveIntervals
&LIS
,
135 unsigned From
, unsigned To
, unsigned BlockNum
= 0) {
136 MachineInstr
&FromInstr
= getMI(MF
, From
, BlockNum
);
137 MachineInstr
&ToInstr
= getMI(MF
, To
, BlockNum
);
139 MachineBasicBlock
&MBB
= *FromInstr
.getParent();
140 MBB
.splice(ToInstr
.getIterator(), &MBB
, FromInstr
.getIterator());
141 LIS
.handleMove(FromInstr
, true);
145 * Move instructions numbered \p From inclusive through instruction number
146 * \p To into a newly formed bundle and update affected liveness intervals
147 * with LiveIntervalAnalysis::handleMoveIntoNewBundle().
149 static void testHandleMoveIntoNewBundle(MachineFunction
&MF
, LiveIntervals
&LIS
,
150 unsigned From
, unsigned To
,
151 unsigned BlockNum
= 0) {
152 MachineInstr
&FromInstr
= getMI(MF
, From
, BlockNum
);
153 MachineInstr
&ToInstr
= getMI(MF
, To
, BlockNum
);
154 MachineBasicBlock
&MBB
= *FromInstr
.getParent();
155 MachineBasicBlock::instr_iterator I
= FromInstr
.getIterator();
158 finalizeBundle(MBB
, I
, std::next(ToInstr
.getIterator()));
159 MF
.getProperties().reset(MachineFunctionProperties::Property::IsSSA
);
161 // Update LiveIntervals
162 MachineBasicBlock::instr_iterator BundleStart
= std::prev(I
);
163 LIS
.handleMoveIntoNewBundle(*BundleStart
, true);
167 * Split block numbered \p BlockNum at instruction \p SplitAt using
168 * MachineBasicBlock::splitAt updating liveness intervals.
170 static void testSplitAt(MachineFunction
&MF
, LiveIntervals
&LIS
,
171 unsigned SplitAt
, unsigned BlockNum
) {
172 MachineInstr
&SplitInstr
= getMI(MF
, SplitAt
, BlockNum
);
173 MachineBasicBlock
&MBB
= *SplitInstr
.getParent();
175 // Split block and update live intervals
176 MBB
.splitAt(SplitInstr
, false, &LIS
);
180 * Helper function to test for interference between a hard register and a
181 * virtual register live ranges.
183 static bool checkRegUnitInterference(LiveIntervals
&LIS
,
184 const TargetRegisterInfo
&TRI
,
185 const LiveInterval
&VirtReg
,
186 MCRegister PhysReg
) {
189 CoalescerPair
CP(VirtReg
.reg(), PhysReg
, TRI
);
191 for (MCRegUnit Unit
: TRI
.regunits(PhysReg
)) {
192 const LiveRange
&UnitRange
= LIS
.getRegUnit(Unit
);
193 if (VirtReg
.overlaps(UnitRange
, CP
, *LIS
.getSlotIndexes()))
199 template <typename AnalysisType
>
200 static void doTest(StringRef MIRFunc
,
201 typename TestPassT
<AnalysisType
>::TestFx T
,
202 bool ShouldPass
= true) {
204 std::unique_ptr
<LLVMTargetMachine
> TM
= createTargetMachine();
205 // This test is designed for the X86 backend; stop if it is not available.
209 legacy::PassManager PM
;
210 std::unique_ptr
<MIRParser
> MIR
;
211 std::unique_ptr
<Module
> M
= parseMIR(Context
, PM
, MIR
, *TM
, MIRFunc
, "func");
214 PM
.add(new TestPassT
<AnalysisType
>(T
, ShouldPass
));
219 static void liveIntervalTest(StringRef MIRFunc
,
220 TestPassT
<LiveIntervals
>::TestFx T
,
221 bool ShouldPass
= true) {
223 StringRef MIRString
= (Twine(R
"MIR(
228 - { id: 0, class: sreg_64 }
231 )MIR") + Twine(MIRFunc
) + Twine("...\n")).toNullTerminatedStringRef(S
);
233 doTest
<LiveIntervals
>(MIRString
, T
, ShouldPass
);
236 static void liveVariablesTest(StringRef MIRFunc
,
237 TestPassT
<LiveVariables
>::TestFx T
,
238 bool ShouldPass
= true) {
240 StringRef MIRString
= (Twine(R
"MIR(
244 tracksRegLiveness: true
246 - { id: 0, class: sreg_64 }
249 )MIR") + Twine(MIRFunc
) + Twine("...\n")).toNullTerminatedStringRef(S
);
250 doTest
<LiveVariables
>(MIRString
, T
, ShouldPass
);
253 } // End of anonymous namespace.
255 char TestPass::ID
= 0;
256 INITIALIZE_PASS(TestPass
, "testpass", "testpass", false, false)
258 TEST(LiveIntervalTest
, MoveUpDef
) {
260 liveIntervalTest(R
"MIR(
263 early-clobber %0 = IMPLICIT_DEF
265 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
266 testHandleMove(MF
, LIS
, 2, 1);
270 TEST(LiveIntervalTest
, MoveUpRedef
) {
271 liveIntervalTest(R
"MIR(
274 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
276 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
277 testHandleMove(MF
, LIS
, 2, 1);
281 TEST(LiveIntervalTest
, MoveUpEarlyDef
) {
282 liveIntervalTest(R
"MIR(
285 early-clobber %0 = IMPLICIT_DEF
287 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
288 testHandleMove(MF
, LIS
, 2, 1);
292 TEST(LiveIntervalTest
, MoveUpEarlyRedef
) {
293 liveIntervalTest(R
"MIR(
296 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
298 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
299 testHandleMove(MF
, LIS
, 2, 1);
303 TEST(LiveIntervalTest
, MoveUpKill
) {
304 liveIntervalTest(R
"MIR(
308 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
309 testHandleMove(MF
, LIS
, 2, 1);
313 TEST(LiveIntervalTest
, MoveUpKillFollowing
) {
314 liveIntervalTest(R
"MIR(
319 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
320 testHandleMove(MF
, LIS
, 2, 1);
324 // TODO: Construct a situation where we have intervals following a hole
325 // while still having connected components.
327 TEST(LiveIntervalTest
, MoveDownDef
) {
329 liveIntervalTest(R
"MIR(
331 early-clobber %0 = IMPLICIT_DEF
334 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
335 testHandleMove(MF
, LIS
, 1, 2);
339 TEST(LiveIntervalTest
, MoveDownRedef
) {
340 liveIntervalTest(R
"MIR(
342 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
345 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
346 testHandleMove(MF
, LIS
, 1, 2);
350 TEST(LiveIntervalTest
, MoveDownEarlyDef
) {
351 liveIntervalTest(R
"MIR(
353 early-clobber %0 = IMPLICIT_DEF
356 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
357 testHandleMove(MF
, LIS
, 1, 2);
361 TEST(LiveIntervalTest
, MoveDownEarlyRedef
) {
362 liveIntervalTest(R
"MIR(
364 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
367 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
368 testHandleMove(MF
, LIS
, 1, 2);
372 TEST(LiveIntervalTest
, MoveDownKill
) {
373 liveIntervalTest(R
"MIR(
377 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
378 testHandleMove(MF
, LIS
, 1, 2);
382 TEST(LiveIntervalTest
, MoveDownKillFollowing
) {
383 liveIntervalTest(R
"MIR(
388 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
389 testHandleMove(MF
, LIS
, 1, 2);
393 TEST(LiveIntervalTest
, MoveUndefUse
) {
394 liveIntervalTest(R
"MIR(
396 S_NOP 0, implicit undef %0
399 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
400 testHandleMove(MF
, LIS
, 1, 3);
404 TEST(LiveIntervalTest
, MoveUpValNos
) {
405 // handleMoveUp() had a bug where it would reuse the value number of the
406 // destination segment, even though we have no guarantee that this valno
407 // wasn't used in other segments.
408 liveIntervalTest(R
"MIR(
409 successors: %bb.1, %bb.2
411 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
417 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
418 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
419 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
421 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
422 testHandleMove(MF
, LIS
, 2, 0, 2);
426 TEST(LiveIntervalTest
, MoveOverUndefUse0
) {
427 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
428 liveIntervalTest(R
"MIR(
431 S_NOP 0, implicit undef %0
432 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
433 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
434 testHandleMove(MF
, LIS
, 3, 1);
438 TEST(LiveIntervalTest
, MoveOverUndefUse1
) {
439 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
440 liveIntervalTest(R
"MIR(
441 $sgpr0 = IMPLICIT_DEF
443 S_NOP 0, implicit undef $sgpr0
444 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
445 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
446 testHandleMove(MF
, LIS
, 3, 1);
450 TEST(LiveIntervalTest
, SubRegMoveDown
) {
451 // Subregister ranges can have holes inside a basic block. Check for a
452 // movement of the form 32->150 in a liverange [16, 32) [100,200).
453 liveIntervalTest(R
"MIR(
454 successors: %bb.1, %bb.2
456 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
460 S_NOP 0, implicit %0.sub0
461 S_NOP 0, implicit %0.sub1
463 undef %0.sub0 = IMPLICIT_DEF
464 %0.sub1 = IMPLICIT_DEF
467 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
468 // Scheduler behaviour: Clear def,read-undef flag and move.
469 MachineInstr
&MI
= getMI(MF
, 3, /*BlockNum=*/1);
470 MI
.getOperand(0).setIsUndef(false);
471 testHandleMove(MF
, LIS
, 1, 4, /*BlockNum=*/1);
475 TEST(LiveIntervalTest
, SubRegMoveUp
) {
476 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
477 // after swapping subreg definitions.
478 liveIntervalTest(R
"MIR(
479 successors: %bb.1, %bb.2
480 undef %0.sub0 = IMPLICIT_DEF
481 %0.sub1 = IMPLICIT_DEF
482 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
485 S_NOP 0, implicit %0.sub1
487 S_NOP 0, implicit %0.sub1
488 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
489 testHandleMove(MF
, LIS
, 1, 0);
493 TEST(LiveIntervalTest
, DeadSubRegMoveUp
) {
494 // handleMoveUp had a bug where moving a dead subreg def into the middle of
495 // an earlier segment resulted in an invalid live range.
496 liveIntervalTest(R
"MIR(
497 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
498 %125.sub1:vreg_128 = COPY %125.sub0
499 %125.sub2:vreg_128 = COPY %125.sub0
500 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
501 %51.sub1:vreg_128 = COPY %51.sub0
502 %51.sub2:vreg_128 = COPY %51.sub0
503 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
504 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
505 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
506 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
507 %60:vgpr_32 = nofpexcept V_MAD_F32_e64 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $mode, implicit $exec
508 %63:vgpr_32 = nofpexcept V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $mode, implicit $exec
509 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
510 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
511 %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
512 dead undef %125.sub3:vreg_128 = nofpexcept V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $mode, implicit $exec
513 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
514 testHandleMove(MF
, LIS
, 15, 12);
518 TEST(LiveIntervalTest
, EarlyClobberSubRegMoveUp
) {
519 // handleMoveUp had a bug where moving an early-clobber subreg def into the
520 // middle of an earlier segment resulted in an invalid live range.
521 liveIntervalTest(R
"MIR(
522 %4:sreg_32 = IMPLICIT_DEF
523 %6:sreg_32 = IMPLICIT_DEF
524 undef early-clobber %9.sub0:sreg_64 = STRICT_WWM %4:sreg_32, implicit $exec
525 %5:sreg_32 = S_FLBIT_I32_B32 %9.sub0:sreg_64
526 early-clobber %9.sub1:sreg_64 = STRICT_WWM %6:sreg_32, implicit $exec
527 %7:sreg_32 = S_FLBIT_I32_B32 %9.sub1:sreg_64
528 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
529 testHandleMove(MF
, LIS
, 4, 3);
533 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDef
) {
534 liveIntervalTest(R
"MIR(
535 %1:vreg_64 = IMPLICIT_DEF
538 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
539 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
540 undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec
541 %1.sub1:vreg_64 = COPY %2
542 S_NOP 0, implicit %1.sub1
545 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
546 MachineInstr
&UndefSubregDef
= getMI(MF
, 2, 1);
547 // The scheduler clears undef from subregister defs before moving
548 UndefSubregDef
.getOperand(0).setIsUndef(false);
549 testHandleMove(MF
, LIS
, 3, 1, 1);
553 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDefMulti
) {
554 liveIntervalTest(R
"MIR(
555 %1:vreg_96 = IMPLICIT_DEF
558 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
559 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
560 undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec
561 %1.sub1:vreg_96 = COPY %2
562 %1.sub2:vreg_96 = COPY %2
563 S_NOP 0, implicit %1.sub1, implicit %1.sub2
566 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
567 MachineInstr
&UndefSubregDef
= getMI(MF
, 2, 1);
568 // The scheduler clears undef from subregister defs before moving
569 UndefSubregDef
.getOperand(0).setIsUndef(false);
570 testHandleMove(MF
, LIS
, 4, 1, 1);
574 TEST(LiveIntervalTest
, TestMoveSubRegUseAcrossMainRangeHole
) {
575 liveIntervalTest(R
"MIR(
576 %1:sgpr_128 = IMPLICIT_DEF
578 %2:sgpr_32 = COPY %1.sub2
579 %3:sgpr_32 = COPY %1.sub1
581 undef %1.sub0 = IMPLICIT_DEF
582 %1.sub2 = IMPLICIT_DEF
583 S_CBRANCH_SCC1 %bb.1, implicit undef $scc
586 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
587 MachineInstr
&MI
= getMI(MF
, 3, /*BlockNum=*/1);
588 MI
.getOperand(0).setIsUndef(false);
589 testHandleMove(MF
, LIS
, 4, 3, 1);
590 testHandleMove(MF
, LIS
, 1, 4, 1);
594 TEST(LiveIntervalTest
, TestMoveSubRegsOfOneReg
) {
595 liveIntervalTest(R
"MIR(
596 INLINEASM &"", 0, 1835018, def undef %4.sub0:vreg_64, 1835018, def undef %4.sub1:vreg_64
598 undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec
599 %2.sub1:vreg_64 = COPY %2.sub0
601 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
602 testHandleMove(MF
, LIS
, 1, 4);
603 testHandleMove(MF
, LIS
, 0, 3);
607 TEST(LiveIntervalTest
, BundleUse
) {
608 liveIntervalTest(R
"MIR(
613 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
614 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
618 TEST(LiveIntervalTest
, BundleDef
) {
619 liveIntervalTest(R
"MIR(
624 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
625 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1);
629 TEST(LiveIntervalTest
, BundleRedef
) {
630 liveIntervalTest(R
"MIR(
633 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
635 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
636 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
640 TEST(LiveIntervalTest
, BundleInternalUse
) {
641 liveIntervalTest(R
"MIR(
646 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
647 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 2);
651 TEST(LiveIntervalTest
, BundleUndefUse
) {
652 liveIntervalTest(R
"MIR(
655 S_NOP 0, implicit undef %0
657 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
658 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
662 TEST(LiveIntervalTest
, BundleSubRegUse
) {
663 liveIntervalTest(R
"MIR(
664 successors: %bb.1, %bb.2
665 undef %0.sub0 = IMPLICIT_DEF
666 %0.sub1 = IMPLICIT_DEF
667 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
671 S_NOP 0, implicit %0.sub1
673 S_NOP 0, implicit %0.sub1
674 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
675 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1, 1);
679 TEST(LiveIntervalTest
, BundleSubRegDef
) {
680 liveIntervalTest(R
"MIR(
681 successors: %bb.1, %bb.2
682 undef %0.sub0 = IMPLICIT_DEF
683 %0.sub1 = IMPLICIT_DEF
684 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
688 S_NOP 0, implicit %0.sub1
690 S_NOP 0, implicit %0.sub1
691 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
692 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1, 0);
696 TEST(LiveIntervalTest
, SplitAtOneInstruction
) {
697 liveIntervalTest(R
"MIR(
703 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
704 testSplitAt(MF
, LIS
, 1, 0);
708 TEST(LiveIntervalTest
, SplitAtMultiInstruction
) {
709 liveIntervalTest(R
"MIR(
719 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
720 testSplitAt(MF
, LIS
, 0, 0);
724 TEST(LiveIntervalTest
, RepairIntervals
) {
725 liveIntervalTest(R
"MIR(
726 %1:sgpr_32 = IMPLICIT_DEF
727 dead %2:sgpr_32 = COPY undef %3.sub0:sgpr_128
728 undef %4.sub2:sgpr_128 = COPY %1:sgpr_32
729 %5:sgpr_32 = COPY %4.sub2:sgpr_128
730 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
731 MachineInstr
&Instr1
= getMI(MF
, 1, 0);
732 MachineInstr
&Instr2
= getMI(MF
, 2, 0);
733 MachineInstr
&Instr3
= getMI(MF
, 3, 0);
734 LIS
.RemoveMachineInstrFromMaps(Instr2
);
735 MachineBasicBlock
*MBB
= Instr1
.getParent();
736 SmallVector
<Register
> OrigRegs
{
737 Instr1
.getOperand(0).getReg(),
738 Instr2
.getOperand(0).getReg(),
739 Instr2
.getOperand(1).getReg(),
741 LIS
.repairIntervalsInRange(MBB
, Instr2
, Instr3
, OrigRegs
);
745 TEST(LiveIntervalTest
, AdjacentIntervals
) {
748 successors: %bb.1, %bb.2
750 $vgpr1 = IMPLICIT_DEF
751 S_NOP 0, implicit $vgpr1
752 %1:vgpr_32 = IMPLICIT_DEF
753 %2:vgpr_32 = IMPLICIT_DEF
754 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
757 $vgpr0, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec
758 S_NOP 0, implicit $vgpr0
761 $vgpr0 = IMPLICIT_DEF
762 $vgpr1, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec
763 S_NOP 0, implicit $vgpr0, implicit $vgpr1
767 [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
769 LIS
.getInterval(getMI(MF
, 2, 0).getOperand(0).getReg());
771 LIS
.getInterval(getMI(MF
, 3, 0).getOperand(0).getReg());
772 MCRegister V1
= getMI(MF
, 1, 2).getOperand(0).getReg().asMCReg();
774 ASSERT_FALSE(checkRegUnitInterference(
775 LIS
, *MF
.getSubtarget().getRegisterInfo(), R1
, V1
));
776 ASSERT_FALSE(checkRegUnitInterference(
777 LIS
, *MF
.getSubtarget().getRegisterInfo(), R2
, V1
));
781 TEST(LiveIntervalTest
, LiveThroughSegments
) {
792 [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
793 MachineInstr
&ImpDef
= getMI(MF
, 0, 0);
794 MachineInstr
&Nop
= getMI(MF
, 0, 1);
795 LiveInterval
&LI
= LIS
.getInterval(ImpDef
.getOperand(0).getReg());
796 SlotIndex OrigIdx
= LIS
.getInstructionIndex(ImpDef
).getRegSlot();
797 LiveInterval::iterator FirstSeg
= LI
.FindSegmentContaining(OrigIdx
);
799 // %0 is live through bb.2. Move its def into bb.1 and update LIS but do
800 // not remove the segment for bb.2. This should cause machine
801 // verification to fail.
802 LIS
.RemoveMachineInstrFromMaps(ImpDef
);
803 ImpDef
.moveBefore(&Nop
);
804 LIS
.InsertMachineInstrInMaps(ImpDef
);
806 SlotIndex NewIdx
= LIS
.getInstructionIndex(ImpDef
).getRegSlot();
807 FirstSeg
->start
= NewIdx
;
808 FirstSeg
->valno
->def
= NewIdx
;
813 TEST(LiveVariablesTest
, recomputeForSingleDefVirtReg_handle_undef1
) {
814 liveVariablesTest(R
"MIR(
817 S_NOP 0, implicit undef %0
818 )MIR", [](MachineFunction
&MF
, LiveVariables
&LV
) {
819 auto &FirstNop
= getMI(MF
, 1, 0);
820 auto &SecondNop
= getMI(MF
, 2, 0);
821 EXPECT_TRUE(FirstNop
.getOperand(1).isKill());
822 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
824 Register R
= Register::index2VirtReg(0);
825 LV
.recomputeForSingleDefVirtReg(R
);
827 EXPECT_TRUE(FirstNop
.getOperand(1).isKill());
828 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
832 TEST(LiveVariablesTest
, recomputeForSingleDefVirtReg_handle_undef2
) {
833 liveVariablesTest(R
"MIR(
836 S_NOP 0, implicit undef %0, implicit %0
837 )MIR", [](MachineFunction
&MF
, LiveVariables
&LV
) {
838 auto &FirstNop
= getMI(MF
, 1, 0);
839 auto &SecondNop
= getMI(MF
, 2, 0);
840 EXPECT_FALSE(FirstNop
.getOperand(1).isKill());
841 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
842 EXPECT_TRUE(SecondNop
.getOperand(2).isKill());
844 Register R
= Register::index2VirtReg(0);
845 LV
.recomputeForSingleDefVirtReg(R
);
847 EXPECT_FALSE(FirstNop
.getOperand(1).isKill());
848 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
849 EXPECT_TRUE(SecondNop
.getOperand(2).isKill());
853 int main(int argc
, char **argv
) {
854 ::testing::InitGoogleTest(&argc
, argv
);
856 return RUN_ALL_TESTS();