[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / llvm / unittests / MI / LiveIntervalTest.cpp
blobedc4baa6bfeca2654aef077dc5916b001664fa65
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"
21 using namespace llvm;
23 namespace llvm {
24 void initializeTestPassPass(PassRegistry &);
27 namespace {
29 void initLLVM() {
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
42 /// liveranges.
43 std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
44 Triple TargetTriple("amdgcn--");
45 std::string Error;
46 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
47 if (!T)
48 return nullptr;
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);
62 if (!MIR)
63 return nullptr;
65 std::unique_ptr<Module> M = MIR->parseIRModule();
66 if (!M)
67 return nullptr;
69 M->setDataLayout(TM.createDataLayout());
71 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(&TM);
72 if (MIR->parseMachineFunctions(*M, MMIWP->getMMI()))
73 return nullptr;
74 PM.add(MMIWP);
76 return M;
79 struct TestPass : public MachineFunctionPass {
80 static char ID;
81 TestPass() : MachineFunctionPass(ID) {}
84 template <typename AnalysisType>
85 struct TestPassT : public TestPass {
87 typedef std::function<void(MachineFunction&,AnalysisType&)> TestFx;
89 TestPassT() {
90 // We should never call this but always use PM.add(new TestPass(...))
91 abort();
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>();
100 T(MF, A);
101 EXPECT_EQ(MF.verify(this, /* Banner */ nullptr, /* AbortOnError */ false),
102 ShouldPass);
103 return true;
106 void getAnalysisUsage(AnalysisUsage &AU) const override {
107 AU.setPreservesAll();
108 AU.addRequired<AnalysisType>();
109 AU.addPreserved<AnalysisType>();
110 MachineFunctionPass::getAnalysisUsage(AU);
112 private:
113 TestFx T;
114 bool ShouldPass;
117 static MachineInstr &getMI(MachineFunction &MF, unsigned At,
118 unsigned BlockNum) {
119 MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
121 unsigned I = 0;
122 for (MachineInstr &MI : MBB) {
123 if (I == At)
124 return MI;
125 ++I;
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();
157 // Build bundle
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) {
187 if (VirtReg.empty())
188 return false;
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()))
194 return true;
196 return false;
199 template <typename AnalysisType>
200 static void doTest(StringRef MIRFunc,
201 typename TestPassT<AnalysisType>::TestFx T,
202 bool ShouldPass = true) {
203 LLVMContext Context;
204 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
205 // This test is designed for the X86 backend; stop if it is not available.
206 if (!TM)
207 return;
209 legacy::PassManager PM;
210 std::unique_ptr<MIRParser> MIR;
211 std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRFunc, "func");
212 ASSERT_TRUE(M);
214 PM.add(new TestPassT<AnalysisType>(T, ShouldPass));
216 PM.run(*M);
219 static void liveIntervalTest(StringRef MIRFunc,
220 TestPassT<LiveIntervals>::TestFx T,
221 bool ShouldPass = true) {
222 SmallString<160> S;
223 StringRef MIRString = (Twine(R"MIR(
226 name: func
227 registers:
228 - { id: 0, class: sreg_64 }
229 body: |
230 bb.0:
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) {
239 SmallString<160> S;
240 StringRef MIRString = (Twine(R"MIR(
243 name: func
244 tracksRegLiveness: true
245 registers:
246 - { id: 0, class: sreg_64 }
247 body: |
248 bb.0:
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) {
259 // Value defined.
260 liveIntervalTest(R"MIR(
261 S_NOP 0
262 S_NOP 0
263 early-clobber %0 = IMPLICIT_DEF
264 S_NOP 0, implicit %0
265 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
266 testHandleMove(MF, LIS, 2, 1);
270 TEST(LiveIntervalTest, MoveUpRedef) {
271 liveIntervalTest(R"MIR(
272 %0 = IMPLICIT_DEF
273 S_NOP 0
274 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
275 S_NOP 0, implicit %0
276 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
277 testHandleMove(MF, LIS, 2, 1);
281 TEST(LiveIntervalTest, MoveUpEarlyDef) {
282 liveIntervalTest(R"MIR(
283 S_NOP 0
284 S_NOP 0
285 early-clobber %0 = IMPLICIT_DEF
286 S_NOP 0, implicit %0
287 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
288 testHandleMove(MF, LIS, 2, 1);
292 TEST(LiveIntervalTest, MoveUpEarlyRedef) {
293 liveIntervalTest(R"MIR(
294 %0 = IMPLICIT_DEF
295 S_NOP 0
296 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
297 S_NOP 0, implicit %0
298 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
299 testHandleMove(MF, LIS, 2, 1);
303 TEST(LiveIntervalTest, MoveUpKill) {
304 liveIntervalTest(R"MIR(
305 %0 = IMPLICIT_DEF
306 S_NOP 0
307 S_NOP 0, implicit %0
308 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
309 testHandleMove(MF, LIS, 2, 1);
313 TEST(LiveIntervalTest, MoveUpKillFollowing) {
314 liveIntervalTest(R"MIR(
315 %0 = IMPLICIT_DEF
316 S_NOP 0
317 S_NOP 0, implicit %0
318 S_NOP 0, implicit %0
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) {
328 // Value defined.
329 liveIntervalTest(R"MIR(
330 S_NOP 0
331 early-clobber %0 = IMPLICIT_DEF
332 S_NOP 0
333 S_NOP 0, implicit %0
334 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
335 testHandleMove(MF, LIS, 1, 2);
339 TEST(LiveIntervalTest, MoveDownRedef) {
340 liveIntervalTest(R"MIR(
341 %0 = IMPLICIT_DEF
342 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
343 S_NOP 0
344 S_NOP 0, implicit %0
345 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
346 testHandleMove(MF, LIS, 1, 2);
350 TEST(LiveIntervalTest, MoveDownEarlyDef) {
351 liveIntervalTest(R"MIR(
352 S_NOP 0
353 early-clobber %0 = IMPLICIT_DEF
354 S_NOP 0
355 S_NOP 0, implicit %0
356 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
357 testHandleMove(MF, LIS, 1, 2);
361 TEST(LiveIntervalTest, MoveDownEarlyRedef) {
362 liveIntervalTest(R"MIR(
363 %0 = IMPLICIT_DEF
364 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)
365 S_NOP 0
366 S_NOP 0, implicit %0
367 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
368 testHandleMove(MF, LIS, 1, 2);
372 TEST(LiveIntervalTest, MoveDownKill) {
373 liveIntervalTest(R"MIR(
374 %0 = IMPLICIT_DEF
375 S_NOP 0, implicit %0
376 S_NOP 0
377 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
378 testHandleMove(MF, LIS, 1, 2);
382 TEST(LiveIntervalTest, MoveDownKillFollowing) {
383 liveIntervalTest(R"MIR(
384 %0 = IMPLICIT_DEF
385 S_NOP 0
386 S_NOP 0, implicit %0
387 S_NOP 0, implicit %0
388 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
389 testHandleMove(MF, LIS, 1, 2);
393 TEST(LiveIntervalTest, MoveUndefUse) {
394 liveIntervalTest(R"MIR(
395 %0 = IMPLICIT_DEF
396 S_NOP 0, implicit undef %0
397 S_NOP 0, implicit %0
398 S_NOP 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
410 %0 = IMPLICIT_DEF
411 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
412 S_BRANCH %bb.1
413 bb.2:
414 S_NOP 0, implicit %0
415 bb.1:
416 successors: %bb.2
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)
420 S_BRANCH %bb.2
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(
429 %0 = IMPLICIT_DEF
430 S_NOP 0
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
442 S_NOP 0
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
455 %0 = IMPLICIT_DEF
456 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc
457 S_BRANCH %bb.1
458 bb.2:
459 successors: %bb.1
460 S_NOP 0, implicit %0.sub0
461 S_NOP 0, implicit %0.sub1
462 S_NOP 0
463 undef %0.sub0 = IMPLICIT_DEF
464 %0.sub1 = IMPLICIT_DEF
465 bb.1:
466 S_NOP 0, implicit %0
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
483 S_BRANCH %bb.1
484 bb.1:
485 S_NOP 0, implicit %0.sub1
486 bb.2:
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
537 bb.1:
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
543 S_BRANCH %bb.1
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
557 bb.1:
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
564 S_BRANCH %bb.1
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
577 bb.1:
578 %2:sgpr_32 = COPY %1.sub2
579 %3:sgpr_32 = COPY %1.sub1
580 %1.sub2 = COPY %2
581 undef %1.sub0 = IMPLICIT_DEF
582 %1.sub2 = IMPLICIT_DEF
583 S_CBRANCH_SCC1 %bb.1, implicit undef $scc
584 S_BRANCH %bb.2
585 bb.2:
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
597 %1:vreg_64 = COPY %4
598 undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec
599 %2.sub1:vreg_64 = COPY %2.sub0
600 %3:vreg_64 = COPY %2
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(
609 %0 = IMPLICIT_DEF
610 S_NOP 0
611 S_NOP 0, implicit %0
612 S_NOP 0
613 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
614 testHandleMoveIntoNewBundle(MF, LIS, 1, 2);
618 TEST(LiveIntervalTest, BundleDef) {
619 liveIntervalTest(R"MIR(
620 %0 = IMPLICIT_DEF
621 S_NOP 0
622 S_NOP 0, implicit %0
623 S_NOP 0
624 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
625 testHandleMoveIntoNewBundle(MF, LIS, 0, 1);
629 TEST(LiveIntervalTest, BundleRedef) {
630 liveIntervalTest(R"MIR(
631 %0 = IMPLICIT_DEF
632 S_NOP 0
633 %0 = IMPLICIT_DEF implicit %0(tied-def 0)
634 S_NOP 0, implicit %0
635 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
636 testHandleMoveIntoNewBundle(MF, LIS, 1, 2);
640 TEST(LiveIntervalTest, BundleInternalUse) {
641 liveIntervalTest(R"MIR(
642 %0 = IMPLICIT_DEF
643 S_NOP 0
644 S_NOP 0, implicit %0
645 S_NOP 0
646 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
647 testHandleMoveIntoNewBundle(MF, LIS, 0, 2);
651 TEST(LiveIntervalTest, BundleUndefUse) {
652 liveIntervalTest(R"MIR(
653 %0 = IMPLICIT_DEF
654 S_NOP 0
655 S_NOP 0, implicit undef %0
656 S_NOP 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
668 S_BRANCH %bb.1
669 bb.1:
670 S_NOP 0
671 S_NOP 0, implicit %0.sub1
672 bb.2:
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
685 S_BRANCH %bb.1
686 bb.1:
687 S_NOP 0
688 S_NOP 0, implicit %0.sub1
689 bb.2:
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(
698 successors: %bb.1
699 %0 = IMPLICIT_DEF
700 S_BRANCH %bb.1
701 bb.1:
702 S_NOP 0
703 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
704 testSplitAt(MF, LIS, 1, 0);
708 TEST(LiveIntervalTest, SplitAtMultiInstruction) {
709 liveIntervalTest(R"MIR(
710 successors: %bb.1
711 %0 = IMPLICIT_DEF
712 S_NOP 0
713 S_NOP 0
714 S_NOP 0
715 S_NOP 0
716 S_BRANCH %bb.1
717 bb.1:
718 S_NOP 0
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) {
746 liveIntervalTest(
747 R"MIR(
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
755 S_BRANCH %bb.1
756 bb.1:
757 $vgpr0, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec
758 S_NOP 0, implicit $vgpr0
759 S_BRANCH %bb.3
760 bb.2:
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
764 S_BRANCH %bb.3
765 bb.3:
766 )MIR",
767 [](MachineFunction &MF, LiveIntervals &LIS) {
768 const auto &R1 =
769 LIS.getInterval(getMI(MF, 2, 0).getOperand(0).getReg());
770 const auto &R2 =
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) {
782 liveIntervalTest(
783 R"MIR(
784 %0 = IMPLICIT_DEF
785 S_BRANCH %bb.2
786 bb.1:
787 S_NOP 0, implicit %0
788 S_ENDPGM 0
789 bb.2:
790 S_BRANCH %bb.1
791 )MIR",
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;
810 false);
813 TEST(LiveVariablesTest, recomputeForSingleDefVirtReg_handle_undef1) {
814 liveVariablesTest(R"MIR(
815 %0 = IMPLICIT_DEF
816 S_NOP 0, implicit %0
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(
834 %0 = IMPLICIT_DEF
835 S_NOP 0, implicit %0
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);
855 initLLVM();
856 return RUN_ALL_TESTS();