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()));
160 // Update LiveIntervals
161 MachineBasicBlock::instr_iterator BundleStart
= std::prev(I
);
162 LIS
.handleMoveIntoNewBundle(*BundleStart
, true);
166 * Split block numbered \p BlockNum at instruction \p SplitAt using
167 * MachineBasicBlock::splitAt updating liveness intervals.
169 static void testSplitAt(MachineFunction
&MF
, LiveIntervals
&LIS
,
170 unsigned SplitAt
, unsigned BlockNum
) {
171 MachineInstr
&SplitInstr
= getMI(MF
, SplitAt
, BlockNum
);
172 MachineBasicBlock
&MBB
= *SplitInstr
.getParent();
174 // Split block and update live intervals
175 MBB
.splitAt(SplitInstr
, false, &LIS
);
179 * Helper function to test for interference between a hard register and a
180 * virtual register live ranges.
182 static bool checkRegUnitInterference(LiveIntervals
&LIS
,
183 const TargetRegisterInfo
&TRI
,
184 const LiveInterval
&VirtReg
,
185 MCRegister PhysReg
) {
188 CoalescerPair
CP(VirtReg
.reg(), PhysReg
, TRI
);
190 for (MCRegUnit Unit
: TRI
.regunits(PhysReg
)) {
191 const LiveRange
&UnitRange
= LIS
.getRegUnit(Unit
);
192 if (VirtReg
.overlaps(UnitRange
, CP
, *LIS
.getSlotIndexes()))
198 template <typename AnalysisType
>
199 static void doTest(StringRef MIRFunc
,
200 typename TestPassT
<AnalysisType
>::TestFx T
,
201 bool ShouldPass
= true) {
203 std::unique_ptr
<LLVMTargetMachine
> TM
= createTargetMachine();
204 // This test is designed for the X86 backend; stop if it is not available.
208 legacy::PassManager PM
;
209 std::unique_ptr
<MIRParser
> MIR
;
210 std::unique_ptr
<Module
> M
= parseMIR(Context
, PM
, MIR
, *TM
, MIRFunc
, "func");
213 PM
.add(new TestPassT
<AnalysisType
>(T
, ShouldPass
));
218 static void liveIntervalTest(StringRef MIRFunc
,
219 TestPassT
<LiveIntervals
>::TestFx T
,
220 bool ShouldPass
= true) {
222 StringRef MIRString
= (Twine(R
"MIR(
227 - { id: 0, class: sreg_64 }
230 )MIR") + Twine(MIRFunc
) + Twine("...\n")).toNullTerminatedStringRef(S
);
232 doTest
<LiveIntervals
>(MIRString
, T
, ShouldPass
);
235 static void liveVariablesTest(StringRef MIRFunc
,
236 TestPassT
<LiveVariables
>::TestFx T
,
237 bool ShouldPass
= true) {
239 StringRef MIRString
= (Twine(R
"MIR(
243 tracksRegLiveness: true
245 - { id: 0, class: sreg_64 }
248 )MIR") + Twine(MIRFunc
) + Twine("...\n")).toNullTerminatedStringRef(S
);
249 doTest
<LiveVariables
>(MIRString
, T
, ShouldPass
);
252 } // End of anonymous namespace.
254 char TestPass::ID
= 0;
255 INITIALIZE_PASS(TestPass
, "testpass", "testpass", false, false)
257 TEST(LiveIntervalTest
, MoveUpDef
) {
259 liveIntervalTest(R
"MIR(
262 early-clobber %0 = IMPLICIT_DEF
264 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
265 testHandleMove(MF
, LIS
, 2, 1);
269 TEST(LiveIntervalTest
, MoveUpRedef
) {
270 liveIntervalTest(R
"MIR(
273 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
275 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
276 testHandleMove(MF
, LIS
, 2, 1);
280 TEST(LiveIntervalTest
, MoveUpEarlyDef
) {
281 liveIntervalTest(R
"MIR(
284 early-clobber %0 = IMPLICIT_DEF
286 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
287 testHandleMove(MF
, LIS
, 2, 1);
291 TEST(LiveIntervalTest
, MoveUpEarlyRedef
) {
292 liveIntervalTest(R
"MIR(
295 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
297 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
298 testHandleMove(MF
, LIS
, 2, 1);
302 TEST(LiveIntervalTest
, MoveUpKill
) {
303 liveIntervalTest(R
"MIR(
307 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
308 testHandleMove(MF
, LIS
, 2, 1);
312 TEST(LiveIntervalTest
, MoveUpKillFollowing
) {
313 liveIntervalTest(R
"MIR(
318 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
319 testHandleMove(MF
, LIS
, 2, 1);
323 // TODO: Construct a situation where we have intervals following a hole
324 // while still having connected components.
326 TEST(LiveIntervalTest
, MoveDownDef
) {
328 liveIntervalTest(R
"MIR(
330 early-clobber %0 = IMPLICIT_DEF
333 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
334 testHandleMove(MF
, LIS
, 1, 2);
338 TEST(LiveIntervalTest
, MoveDownRedef
) {
339 liveIntervalTest(R
"MIR(
341 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
344 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
345 testHandleMove(MF
, LIS
, 1, 2);
349 TEST(LiveIntervalTest
, MoveDownEarlyDef
) {
350 liveIntervalTest(R
"MIR(
352 early-clobber %0 = IMPLICIT_DEF
355 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
356 testHandleMove(MF
, LIS
, 1, 2);
360 TEST(LiveIntervalTest
, MoveDownEarlyRedef
) {
361 liveIntervalTest(R
"MIR(
363 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
366 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
367 testHandleMove(MF
, LIS
, 1, 2);
371 TEST(LiveIntervalTest
, MoveDownKill
) {
372 liveIntervalTest(R
"MIR(
376 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
377 testHandleMove(MF
, LIS
, 1, 2);
381 TEST(LiveIntervalTest
, MoveDownKillFollowing
) {
382 liveIntervalTest(R
"MIR(
387 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
388 testHandleMove(MF
, LIS
, 1, 2);
392 TEST(LiveIntervalTest
, MoveUndefUse
) {
393 liveIntervalTest(R
"MIR(
395 S_NOP 0, implicit undef %0
398 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
399 testHandleMove(MF
, LIS
, 1, 3);
403 TEST(LiveIntervalTest
, MoveUpValNos
) {
404 // handleMoveUp() had a bug where it would reuse the value number of the
405 // destination segment, even though we have no guarantee that this valno
406 // wasn't used in other segments.
407 liveIntervalTest(R
"MIR(
408 successors: %bb.1, %bb.2
410 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
416 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
417 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
418 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
420 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
421 testHandleMove(MF
, LIS
, 2, 0, 2);
425 TEST(LiveIntervalTest
, MoveOverUndefUse0
) {
426 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
427 liveIntervalTest(R
"MIR(
430 S_NOP 0, implicit undef %0
431 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
432 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
433 testHandleMove(MF
, LIS
, 3, 1);
437 TEST(LiveIntervalTest
, MoveOverUndefUse1
) {
438 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
439 liveIntervalTest(R
"MIR(
440 $sgpr0 = IMPLICIT_DEF
442 S_NOP 0, implicit undef $sgpr0
443 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)
444 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
445 testHandleMove(MF
, LIS
, 3, 1);
449 TEST(LiveIntervalTest
, SubRegMoveDown
) {
450 // Subregister ranges can have holes inside a basic block. Check for a
451 // movement of the form 32->150 in a liverange [16, 32) [100,200).
452 liveIntervalTest(R
"MIR(
453 successors: %bb.1, %bb.2
455 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
459 S_NOP 0, implicit %0.sub0
460 S_NOP 0, implicit %0.sub1
462 undef %0.sub0 = IMPLICIT_DEF
463 %0.sub1 = IMPLICIT_DEF
466 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
467 // Scheduler behaviour: Clear def,read-undef flag and move.
468 MachineInstr
&MI
= getMI(MF
, 3, /*BlockNum=*/1);
469 MI
.getOperand(0).setIsUndef(false);
470 testHandleMove(MF
, LIS
, 1, 4, /*BlockNum=*/1);
474 TEST(LiveIntervalTest
, SubRegMoveUp
) {
475 // handleMoveUp had a bug not updating valno of segment incoming to bb.2
476 // after swapping subreg definitions.
477 liveIntervalTest(R
"MIR(
478 successors: %bb.1, %bb.2
479 undef %0.sub0 = IMPLICIT_DEF
480 %0.sub1 = IMPLICIT_DEF
481 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
484 S_NOP 0, implicit %0.sub1
486 S_NOP 0, implicit %0.sub1
487 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
488 testHandleMove(MF
, LIS
, 1, 0);
492 TEST(LiveIntervalTest
, DeadSubRegMoveUp
) {
493 // handleMoveUp had a bug where moving a dead subreg def into the middle of
494 // an earlier segment resulted in an invalid live range.
495 liveIntervalTest(R
"MIR(
496 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
497 %125.sub1:vreg_128 = COPY %125.sub0
498 %125.sub2:vreg_128 = COPY %125.sub0
499 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
500 %51.sub1:vreg_128 = COPY %51.sub0
501 %51.sub2:vreg_128 = COPY %51.sub0
502 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
503 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
504 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
505 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
506 %60:vgpr_32 = nofpexcept V_MAD_F32_e64 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $mode, implicit $exec
507 %63:vgpr_32 = nofpexcept V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $mode, implicit $exec
508 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
509 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
510 %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
511 dead undef %125.sub3:vreg_128 = nofpexcept V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $mode, implicit $exec
512 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
513 testHandleMove(MF
, LIS
, 15, 12);
517 TEST(LiveIntervalTest
, EarlyClobberSubRegMoveUp
) {
518 // handleMoveUp had a bug where moving an early-clobber subreg def into the
519 // middle of an earlier segment resulted in an invalid live range.
520 liveIntervalTest(R
"MIR(
521 %4:sreg_32 = IMPLICIT_DEF
522 %6:sreg_32 = IMPLICIT_DEF
523 undef early-clobber %9.sub0:sreg_64 = STRICT_WWM %4:sreg_32, implicit $exec
524 %5:sreg_32 = S_FLBIT_I32_B32 %9.sub0:sreg_64
525 early-clobber %9.sub1:sreg_64 = STRICT_WWM %6:sreg_32, implicit $exec
526 %7:sreg_32 = S_FLBIT_I32_B32 %9.sub1:sreg_64
527 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
528 testHandleMove(MF
, LIS
, 4, 3);
532 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDef
) {
533 liveIntervalTest(R
"MIR(
534 %1:vreg_64 = IMPLICIT_DEF
537 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
538 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
539 undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec
540 %1.sub1:vreg_64 = COPY %2
541 S_NOP 0, implicit %1.sub1
544 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
545 MachineInstr
&UndefSubregDef
= getMI(MF
, 2, 1);
546 // The scheduler clears undef from subregister defs before moving
547 UndefSubregDef
.getOperand(0).setIsUndef(false);
548 testHandleMove(MF
, LIS
, 3, 1, 1);
552 TEST(LiveIntervalTest
, TestMoveSubRegDefAcrossUseDefMulti
) {
553 liveIntervalTest(R
"MIR(
554 %1:vreg_96 = IMPLICIT_DEF
557 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec
558 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec
559 undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec
560 %1.sub1:vreg_96 = COPY %2
561 %1.sub2:vreg_96 = COPY %2
562 S_NOP 0, implicit %1.sub1, implicit %1.sub2
565 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
566 MachineInstr
&UndefSubregDef
= getMI(MF
, 2, 1);
567 // The scheduler clears undef from subregister defs before moving
568 UndefSubregDef
.getOperand(0).setIsUndef(false);
569 testHandleMove(MF
, LIS
, 4, 1, 1);
573 TEST(LiveIntervalTest
, TestMoveSubRegUseAcrossMainRangeHole
) {
574 liveIntervalTest(R
"MIR(
575 %1:sgpr_128 = IMPLICIT_DEF
577 %2:sgpr_32 = COPY %1.sub2
578 %3:sgpr_32 = COPY %1.sub1
580 undef %1.sub0 = IMPLICIT_DEF
581 %1.sub2 = IMPLICIT_DEF
582 S_CBRANCH_SCC1 %bb.1, implicit undef $scc
585 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
586 MachineInstr
&MI
= getMI(MF
, 3, /*BlockNum=*/1);
587 MI
.getOperand(0).setIsUndef(false);
588 testHandleMove(MF
, LIS
, 4, 3, 1);
589 testHandleMove(MF
, LIS
, 1, 4, 1);
593 TEST(LiveIntervalTest
, TestMoveSubRegsOfOneReg
) {
594 liveIntervalTest(R
"MIR(
595 INLINEASM &"", 0, 1835018, def undef %4.sub0:vreg_64, 1835018, def undef %4.sub1:vreg_64
597 undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec
598 %2.sub1:vreg_64 = COPY %2.sub0
600 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
601 testHandleMove(MF
, LIS
, 1, 4);
602 testHandleMove(MF
, LIS
, 0, 3);
606 TEST(LiveIntervalTest
, BundleUse
) {
607 liveIntervalTest(R
"MIR(
612 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
613 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
617 TEST(LiveIntervalTest
, BundleDef
) {
618 liveIntervalTest(R
"MIR(
623 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
624 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1);
628 TEST(LiveIntervalTest
, BundleRedef
) {
629 liveIntervalTest(R
"MIR(
632 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
634 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
635 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
639 TEST(LiveIntervalTest
, BundleInternalUse
) {
640 liveIntervalTest(R
"MIR(
645 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
646 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 2);
650 TEST(LiveIntervalTest
, BundleUndefUse
) {
651 liveIntervalTest(R
"MIR(
654 S_NOP 0, implicit undef %0
656 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
657 testHandleMoveIntoNewBundle(MF
, LIS
, 1, 2);
661 TEST(LiveIntervalTest
, BundleSubRegUse
) {
662 liveIntervalTest(R
"MIR(
663 successors: %bb.1, %bb.2
664 undef %0.sub0 = IMPLICIT_DEF
665 %0.sub1 = IMPLICIT_DEF
666 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
670 S_NOP 0, implicit %0.sub1
672 S_NOP 0, implicit %0.sub1
673 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
674 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1, 1);
678 TEST(LiveIntervalTest
, BundleSubRegDef
) {
679 liveIntervalTest(R
"MIR(
680 successors: %bb.1, %bb.2
681 undef %0.sub0 = IMPLICIT_DEF
682 %0.sub1 = IMPLICIT_DEF
683 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
687 S_NOP 0, implicit %0.sub1
689 S_NOP 0, implicit %0.sub1
690 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
691 testHandleMoveIntoNewBundle(MF
, LIS
, 0, 1, 0);
695 TEST(LiveIntervalTest
, SplitAtOneInstruction
) {
696 liveIntervalTest(R
"MIR(
702 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
703 testSplitAt(MF
, LIS
, 1, 0);
707 TEST(LiveIntervalTest
, SplitAtMultiInstruction
) {
708 liveIntervalTest(R
"MIR(
718 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
719 testSplitAt(MF
, LIS
, 0, 0);
723 TEST(LiveIntervalTest
, RepairIntervals
) {
724 liveIntervalTest(R
"MIR(
725 %1:sgpr_32 = IMPLICIT_DEF
726 dead %2:sgpr_32 = COPY undef %3.sub0:sgpr_128
727 undef %4.sub2:sgpr_128 = COPY %1:sgpr_32
728 %5:sgpr_32 = COPY %4.sub2:sgpr_128
729 )MIR", [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
730 MachineInstr
&Instr1
= getMI(MF
, 1, 0);
731 MachineInstr
&Instr2
= getMI(MF
, 2, 0);
732 MachineInstr
&Instr3
= getMI(MF
, 3, 0);
733 LIS
.RemoveMachineInstrFromMaps(Instr2
);
734 MachineBasicBlock
*MBB
= Instr1
.getParent();
735 SmallVector
<Register
> OrigRegs
{
736 Instr1
.getOperand(0).getReg(),
737 Instr2
.getOperand(0).getReg(),
738 Instr2
.getOperand(1).getReg(),
740 LIS
.repairIntervalsInRange(MBB
, Instr2
, Instr3
, OrigRegs
);
744 TEST(LiveIntervalTest
, AdjacentIntervals
) {
747 successors: %bb.1, %bb.2
749 $vgpr1 = IMPLICIT_DEF
750 S_NOP 0, implicit $vgpr1
751 %1:vgpr_32 = IMPLICIT_DEF
752 %2:vgpr_32 = IMPLICIT_DEF
753 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
756 $vgpr0, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec
757 S_NOP 0, implicit $vgpr0
760 $vgpr0 = IMPLICIT_DEF
761 $vgpr1, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec
762 S_NOP 0, implicit $vgpr0, implicit $vgpr1
766 [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
768 LIS
.getInterval(getMI(MF
, 2, 0).getOperand(0).getReg());
770 LIS
.getInterval(getMI(MF
, 3, 0).getOperand(0).getReg());
771 MCRegister V1
= getMI(MF
, 1, 2).getOperand(0).getReg().asMCReg();
773 ASSERT_FALSE(checkRegUnitInterference(
774 LIS
, *MF
.getSubtarget().getRegisterInfo(), R1
, V1
));
775 ASSERT_FALSE(checkRegUnitInterference(
776 LIS
, *MF
.getSubtarget().getRegisterInfo(), R2
, V1
));
780 TEST(LiveIntervalTest
, LiveThroughSegments
) {
791 [](MachineFunction
&MF
, LiveIntervals
&LIS
) {
792 MachineInstr
&ImpDef
= getMI(MF
, 0, 0);
793 MachineInstr
&Nop
= getMI(MF
, 0, 1);
794 LiveInterval
&LI
= LIS
.getInterval(ImpDef
.getOperand(0).getReg());
795 SlotIndex OrigIdx
= LIS
.getInstructionIndex(ImpDef
).getRegSlot();
796 LiveInterval::iterator FirstSeg
= LI
.FindSegmentContaining(OrigIdx
);
798 // %0 is live through bb.2. Move its def into bb.1 and update LIS but do
799 // not remove the segment for bb.2. This should cause machine
800 // verification to fail.
801 LIS
.RemoveMachineInstrFromMaps(ImpDef
);
802 ImpDef
.moveBefore(&Nop
);
803 LIS
.InsertMachineInstrInMaps(ImpDef
);
805 SlotIndex NewIdx
= LIS
.getInstructionIndex(ImpDef
).getRegSlot();
806 FirstSeg
->start
= NewIdx
;
807 FirstSeg
->valno
->def
= NewIdx
;
812 TEST(LiveVariablesTest
, recomputeForSingleDefVirtReg_handle_undef1
) {
813 liveVariablesTest(R
"MIR(
816 S_NOP 0, implicit undef %0
817 )MIR", [](MachineFunction
&MF
, LiveVariables
&LV
) {
818 auto &FirstNop
= getMI(MF
, 1, 0);
819 auto &SecondNop
= getMI(MF
, 2, 0);
820 EXPECT_TRUE(FirstNop
.getOperand(1).isKill());
821 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
823 Register R
= Register::index2VirtReg(0);
824 LV
.recomputeForSingleDefVirtReg(R
);
826 EXPECT_TRUE(FirstNop
.getOperand(1).isKill());
827 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
831 TEST(LiveVariablesTest
, recomputeForSingleDefVirtReg_handle_undef2
) {
832 liveVariablesTest(R
"MIR(
835 S_NOP 0, implicit undef %0, implicit %0
836 )MIR", [](MachineFunction
&MF
, LiveVariables
&LV
) {
837 auto &FirstNop
= getMI(MF
, 1, 0);
838 auto &SecondNop
= getMI(MF
, 2, 0);
839 EXPECT_FALSE(FirstNop
.getOperand(1).isKill());
840 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
841 EXPECT_TRUE(SecondNop
.getOperand(2).isKill());
843 Register R
= Register::index2VirtReg(0);
844 LV
.recomputeForSingleDefVirtReg(R
);
846 EXPECT_FALSE(FirstNop
.getOperand(1).isKill());
847 EXPECT_FALSE(SecondNop
.getOperand(1).isKill());
848 EXPECT_TRUE(SecondNop
.getOperand(2).isKill());
852 int main(int argc
, char **argv
) {
853 ::testing::InitGoogleTest(&argc
, argv
);
855 return RUN_ALL_TESTS();