938 lines · cpp
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"19 20#include "../lib/CodeGen/RegisterCoalescer.h"21 22using namespace llvm;23 24namespace llvm {25 void initializeTestPassPass(PassRegistry &);26}27 28namespace {29 30void initLLVM() {31 InitializeAllTargets();32 InitializeAllTargetMCs();33 InitializeAllAsmPrinters();34 InitializeAllAsmParsers();35 36 PassRegistry *Registry = PassRegistry::getPassRegistry();37 initializeCore(*Registry);38 initializeCodeGen(*Registry);39}40 41/// Create a TargetMachine. As we lack a dedicated always available target for42/// unittests, we go for "AMDGPU" to be able to test normal and subregister43/// liveranges.44std::unique_ptr<TargetMachine> createTargetMachine() {45 Triple TargetTriple("amdgcn--");46 std::string Error;47 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);48 if (!T)49 return nullptr;50 51 TargetOptions Options;52 return std::unique_ptr<TargetMachine>(53 T->createTargetMachine(TargetTriple, "gfx900", "", Options, std::nullopt,54 std::nullopt, CodeGenOptLevel::Aggressive));55}56 57std::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);64 if (!MIR)65 return nullptr;66 67 std::unique_ptr<Module> M = MIR->parseIRModule();68 if (!M)69 return nullptr;70 71 M->setDataLayout(TM.createDataLayout());72 73 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(&TM);74 if (MIR->parseMachineFunctions(*M, MMIWP->getMMI()))75 return nullptr;76 PM.add(MMIWP);77 78 return M;79}80 81struct TestPass : public MachineFunctionPass {82 static char ID;83 TestPass() : MachineFunctionPass(ID) {}84};85 86template <typename AnalysisType>87struct TestPassT : public TestPass {88 89 typedef std::function<void(MachineFunction&,AnalysisType&)> TestFx;90 91 TestPassT() {92 // We should never call this but always use PM.add(new TestPass(...))93 abort();94 }95 TestPassT(TestFx T, bool ShouldPass)96 : T(T), ShouldPass(ShouldPass) {97 initializeTestPassPass(*PassRegistry::getPassRegistry());98 }99 100 bool runOnMachineFunction(MachineFunction &MF) override {101 AnalysisType &A = getAnalysis<AnalysisType>();102 T(MF, A);103 EXPECT_EQ(MF.verify(this, /* Banner=*/nullptr,104 /*OS=*/nullptr,105 /* AbortOnError=*/false),106 ShouldPass);107 return true;108 }109 110 void getAnalysisUsage(AnalysisUsage &AU) const override {111 AU.setPreservesAll();112 AU.addRequired<AnalysisType>();113 AU.addPreserved<AnalysisType>();114 MachineFunctionPass::getAnalysisUsage(AU);115 }116private:117 TestFx T;118 bool ShouldPass;119};120 121static MachineInstr &getMI(MachineFunction &MF, unsigned At,122 unsigned BlockNum) {123 MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);124 125 unsigned I = 0;126 for (MachineInstr &MI : MBB) {127 if (I == At)128 return MI;129 ++I;130 }131 llvm_unreachable("Instruction not found");132}133 134/**135 * Move instruction number \p From in front of instruction number \p To and136 * update affected liveness intervals with LiveIntervalAnalysis::handleMove().137 */138static 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);142 143 MachineBasicBlock &MBB = *FromInstr.getParent();144 MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator());145 LIS.handleMove(FromInstr, true);146}147 148/**149 * Move instructions numbered \p From inclusive through instruction number150 * \p To into a newly formed bundle and update affected liveness intervals151 * with LiveIntervalAnalysis::handleMoveIntoNewBundle().152 */153static 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();160 161 // Build bundle162 finalizeBundle(MBB, I, std::next(ToInstr.getIterator()));163 MF.getProperties().resetIsSSA();164 165 // Update LiveIntervals166 MachineBasicBlock::instr_iterator BundleStart = std::prev(I);167 LIS.handleMoveIntoNewBundle(*BundleStart, true);168}169 170/**171 * Split block numbered \p BlockNum at instruction \p SplitAt using172 * MachineBasicBlock::splitAt updating liveness intervals.173 */174static void testSplitAt(MachineFunction &MF, LiveIntervals &LIS,175 unsigned SplitAt, unsigned BlockNum) {176 MachineInstr &SplitInstr = getMI(MF, SplitAt, BlockNum);177 MachineBasicBlock &MBB = *SplitInstr.getParent();178 179 // Split block and update live intervals180 MBB.splitAt(SplitInstr, false, &LIS);181}182 183/**184 * Helper function to test for interference between a hard register and a185 * virtual register live ranges.186 */187static bool checkRegUnitInterference(LiveIntervals &LIS,188 const TargetRegisterInfo &TRI,189 const LiveInterval &VirtReg,190 MCRegister PhysReg) {191 if (VirtReg.empty())192 return false;193 CoalescerPair CP(VirtReg.reg(), PhysReg, TRI);194 195 for (MCRegUnit Unit : TRI.regunits(PhysReg)) {196 const LiveRange &UnitRange = LIS.getRegUnit(Unit);197 if (VirtReg.overlaps(UnitRange, CP, *LIS.getSlotIndexes()))198 return true;199 }200 return false;201}202 203template <typename AnalysisType>204static void doTest(StringRef MIRFunc,205 typename TestPassT<AnalysisType>::TestFx T,206 bool ShouldPass = true) {207 LLVMContext Context;208 std::unique_ptr<TargetMachine> TM = createTargetMachine();209 // This test is designed for the X86 backend; stop if it is not available.210 if (!TM)211 return;212 213 legacy::PassManager PM;214 std::unique_ptr<MIRParser> MIR;215 std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRFunc);216 ASSERT_TRUE(M);217 218 PM.add(new TestPassT<AnalysisType>(T, ShouldPass));219 220 PM.run(*M);221}222 223static void liveIntervalTest(StringRef MIRFunc,224 TestPassT<LiveIntervalsWrapperPass>::TestFx T,225 bool ShouldPass = true) {226 SmallString<160> S;227 StringRef MIRString = (Twine(R"MIR(228---229...230name: func231registers:232 - { id: 0, class: sreg_64 }233body: |234 bb.0:235)MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);236 237 doTest<LiveIntervalsWrapperPass>(MIRString, T, ShouldPass);238}239 240static void liveVariablesTest(StringRef MIRFunc,241 TestPassT<LiveVariablesWrapperPass>::TestFx T,242 bool ShouldPass = true) {243 SmallString<160> S;244 StringRef MIRString = (Twine(R"MIR(245---246...247name: func248tracksRegLiveness: true249registers:250 - { id: 0, class: sreg_64 }251body: |252 bb.0:253)MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);254 doTest<LiveVariablesWrapperPass>(MIRString, T, ShouldPass);255}256 257} // End of anonymous namespace.258 259char TestPass::ID = 0;260INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)261 262TEST(LiveIntervalTest, MoveUpDef) {263 // Value defined.264 liveIntervalTest(265 R"MIR(266 S_NOP 0267 S_NOP 0268 early-clobber %0 = IMPLICIT_DEF269 S_NOP 0, implicit %0270)MIR",271 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {272 testHandleMove(MF, LISWrapper.getLIS(), 2, 1);273 });274}275 276TEST(LiveIntervalTest, MoveUpRedef) {277 liveIntervalTest(R"MIR(278 %0 = IMPLICIT_DEF279 S_NOP 0280 %0 = IMPLICIT_DEF implicit %0(tied-def 0)281 S_NOP 0, implicit %0282)MIR",283 [](MachineFunction &MF, LiveIntervalsWrapperPass &LIS) {284 testHandleMove(MF, LIS.getLIS(), 2, 1);285 });286}287 288TEST(LiveIntervalTest, MoveUpEarlyDef) {289 liveIntervalTest(290 R"MIR(291 S_NOP 0292 S_NOP 0293 early-clobber %0 = IMPLICIT_DEF294 S_NOP 0, implicit %0295)MIR",296 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {297 testHandleMove(MF, LISWrapper.getLIS(), 2, 1);298 });299}300 301TEST(LiveIntervalTest, MoveUpEarlyRedef) {302 liveIntervalTest(303 R"MIR(304 %0 = IMPLICIT_DEF305 S_NOP 0306 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)307 S_NOP 0, implicit %0308)MIR",309 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {310 testHandleMove(MF, LISWrapper.getLIS(), 2, 1);311 });312}313 314TEST(LiveIntervalTest, MoveUpKill) {315 liveIntervalTest(316 R"MIR(317 %0 = IMPLICIT_DEF318 S_NOP 0319 S_NOP 0, implicit %0320)MIR",321 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {322 testHandleMove(MF, LISWrapper.getLIS(), 2, 1);323 });324}325 326TEST(LiveIntervalTest, MoveUpKillFollowing) {327 liveIntervalTest(328 R"MIR(329 %0 = IMPLICIT_DEF330 S_NOP 0331 S_NOP 0, implicit %0332 S_NOP 0, implicit %0333)MIR",334 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {335 testHandleMove(MF, LISWrapper.getLIS(), 2, 1);336 });337}338 339// TODO: Construct a situation where we have intervals following a hole340// while still having connected components.341 342TEST(LiveIntervalTest, MoveDownDef) {343 // Value defined.344 liveIntervalTest(345 R"MIR(346 S_NOP 0347 early-clobber %0 = IMPLICIT_DEF348 S_NOP 0349 S_NOP 0, implicit %0350)MIR",351 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {352 testHandleMove(MF, LISWrapper.getLIS(), 1, 2);353 });354}355 356TEST(LiveIntervalTest, MoveDownRedef) {357 liveIntervalTest(358 R"MIR(359 %0 = IMPLICIT_DEF360 %0 = IMPLICIT_DEF implicit %0(tied-def 0)361 S_NOP 0362 S_NOP 0, implicit %0363)MIR",364 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {365 testHandleMove(MF, LISWrapper.getLIS(), 1, 2);366 });367}368 369TEST(LiveIntervalTest, MoveDownEarlyDef) {370 liveIntervalTest(371 R"MIR(372 S_NOP 0373 early-clobber %0 = IMPLICIT_DEF374 S_NOP 0375 S_NOP 0, implicit %0376)MIR",377 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {378 testHandleMove(MF, LISWrapper.getLIS(), 1, 2);379 });380}381 382TEST(LiveIntervalTest, MoveDownEarlyRedef) {383 liveIntervalTest(384 R"MIR(385 %0 = IMPLICIT_DEF386 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)387 S_NOP 0388 S_NOP 0, implicit %0389)MIR",390 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {391 testHandleMove(MF, LISWrapper.getLIS(), 1, 2);392 });393}394 395TEST(LiveIntervalTest, MoveDownKill) {396 liveIntervalTest(397 R"MIR(398 %0 = IMPLICIT_DEF399 S_NOP 0, implicit %0400 S_NOP 0401)MIR",402 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {403 testHandleMove(MF, LISWrapper.getLIS(), 1, 2);404 });405}406 407TEST(LiveIntervalTest, MoveDownKillFollowing) {408 liveIntervalTest(409 R"MIR(410 %0 = IMPLICIT_DEF411 S_NOP 0412 S_NOP 0, implicit %0413 S_NOP 0, implicit %0414)MIR",415 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {416 testHandleMove(MF, LISWrapper.getLIS(), 1, 2);417 });418}419 420TEST(LiveIntervalTest, MoveUndefUse) {421 liveIntervalTest(422 R"MIR(423 %0 = IMPLICIT_DEF424 S_NOP 0, implicit undef %0425 S_NOP 0, implicit %0426 S_NOP 0427)MIR",428 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {429 testHandleMove(MF, LISWrapper.getLIS(), 1, 3);430 });431}432 433TEST(LiveIntervalTest, MoveUpValNos) {434 // handleMoveUp() had a bug where it would reuse the value number of the435 // destination segment, even though we have no guarantee that this valno436 // wasn't used in other segments.437 liveIntervalTest(438 R"MIR(439 successors: %bb.1, %bb.2440 %0 = IMPLICIT_DEF441 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc442 S_BRANCH %bb.1443 bb.2:444 S_NOP 0, implicit %0445 bb.1:446 successors: %bb.2447 %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)450 S_BRANCH %bb.2451)MIR",452 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {453 testHandleMove(MF, LISWrapper.getLIS(), 2, 0, 2);454 });455}456 457TEST(LiveIntervalTest, MoveOverUndefUse0) {458 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.459 liveIntervalTest(460 R"MIR(461 %0 = IMPLICIT_DEF462 S_NOP 0463 S_NOP 0, implicit undef %0464 %0 = IMPLICIT_DEF implicit %0(tied-def 0)465)MIR",466 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {467 testHandleMove(MF, LISWrapper.getLIS(), 3, 1);468 });469}470 471TEST(LiveIntervalTest, MoveOverUndefUse1) {472 // findLastUseBefore() used by handleMoveUp() must ignore undef operands.473 liveIntervalTest(474 R"MIR(475 $sgpr0 = IMPLICIT_DEF476 S_NOP 0477 S_NOP 0, implicit undef $sgpr0478 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0)479)MIR",480 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {481 testHandleMove(MF, LISWrapper.getLIS(), 3, 1);482 });483}484 485TEST(LiveIntervalTest, SubRegMoveDown) {486 // Subregister ranges can have holes inside a basic block. Check for a487 // movement of the form 32->150 in a liverange [16, 32) [100,200).488 liveIntervalTest(489 R"MIR(490 successors: %bb.1, %bb.2491 %0 = IMPLICIT_DEF492 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc493 S_BRANCH %bb.1494 bb.2:495 successors: %bb.1496 S_NOP 0, implicit %0.sub0497 S_NOP 0, implicit %0.sub1498 S_NOP 0499 undef %0.sub0 = IMPLICIT_DEF500 %0.sub1 = IMPLICIT_DEF501 bb.1:502 S_NOP 0, implicit %0503)MIR",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);509 });510}511 512TEST(LiveIntervalTest, SubRegMoveUp) {513 // handleMoveUp had a bug not updating valno of segment incoming to bb.2514 // after swapping subreg definitions.515 liveIntervalTest(516 R"MIR(517 successors: %bb.1, %bb.2518 undef %0.sub0 = IMPLICIT_DEF519 %0.sub1 = IMPLICIT_DEF520 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc521 S_BRANCH %bb.1522 bb.1:523 S_NOP 0, implicit %0.sub1524 bb.2:525 S_NOP 0, implicit %0.sub1526)MIR",527 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {528 testHandleMove(MF, LISWrapper.getLIS(), 1, 0);529 });530}531 532TEST(LiveIntervalTest, DeadSubRegMoveUp) {533 // handleMoveUp had a bug where moving a dead subreg def into the middle of534 // an earlier segment resulted in an invalid live range.535 liveIntervalTest(536 R"MIR(537 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec538 %125.sub1:vreg_128 = COPY %125.sub0539 %125.sub2:vreg_128 = COPY %125.sub0540 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec541 %51.sub1:vreg_128 = COPY %51.sub0542 %51.sub2:vreg_128 = COPY %51.sub0543 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec544 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec545 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec546 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec547 %60:vgpr_32 = nofpexcept V_MAD_F32_e64 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $mode, implicit $exec548 %63:vgpr_32 = nofpexcept V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $mode, implicit $exec549 dead %66:vgpr_32 = nofpexcept V_MAD_F32_e64 0, %60, 0, undef %67:vgpr_32, 0, %125.sub2, 0, 0, implicit $mode, implicit $exec550 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 $exec551 %124.sub0:vreg_128 = nofpexcept V_MAD_F32_e64 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $mode, implicit $exec552 dead undef %125.sub3:vreg_128 = nofpexcept V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $mode, implicit $exec553)MIR",554 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {555 testHandleMove(MF, LISWrapper.getLIS(), 15, 12);556 });557}558 559TEST(LiveIntervalTest, EarlyClobberSubRegMoveUp) {560 // handleMoveUp had a bug where moving an early-clobber subreg def into the561 // middle of an earlier segment resulted in an invalid live range.562 liveIntervalTest(563 R"MIR(564 %4:sreg_32 = IMPLICIT_DEF565 %6:sreg_32 = IMPLICIT_DEF566 undef early-clobber %9.sub0:sreg_64 = STRICT_WWM %4:sreg_32, implicit $exec567 %5:sreg_32 = S_FLBIT_I32_B32 %9.sub0:sreg_64568 early-clobber %9.sub1:sreg_64 = STRICT_WWM %6:sreg_32, implicit $exec569 %7:sreg_32 = S_FLBIT_I32_B32 %9.sub1:sreg_64570)MIR",571 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {572 testHandleMove(MF, LISWrapper.getLIS(), 4, 3);573 });574}575 576TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) {577 liveIntervalTest(578 R"MIR(579 %1:vreg_64 = IMPLICIT_DEF580 581 bb.1:582 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec583 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec584 undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec585 %1.sub1:vreg_64 = COPY %2586 S_NOP 0, implicit %1.sub1587 S_BRANCH %bb.1588 589)MIR",590 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {591 MachineInstr &UndefSubregDef = getMI(MF, 2, 1);592 // The scheduler clears undef from subregister defs before moving593 UndefSubregDef.getOperand(0).setIsUndef(false);594 testHandleMove(MF, LISWrapper.getLIS(), 3, 1, 1);595 });596}597 598TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDefMulti) {599 liveIntervalTest(600 R"MIR(601 %1:vreg_96 = IMPLICIT_DEF602 603 bb.1:604 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec605 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec606 undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec607 %1.sub1:vreg_96 = COPY %2608 %1.sub2:vreg_96 = COPY %2609 S_NOP 0, implicit %1.sub1, implicit %1.sub2610 S_BRANCH %bb.1611 612)MIR",613 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {614 MachineInstr &UndefSubregDef = getMI(MF, 2, 1);615 // The scheduler clears undef from subregister defs before moving616 UndefSubregDef.getOperand(0).setIsUndef(false);617 testHandleMove(MF, LISWrapper.getLIS(), 4, 1, 1);618 });619}620 621TEST(LiveIntervalTest, TestMoveSubRegUseAcrossMainRangeHole) {622 liveIntervalTest(623 R"MIR(624 %1:sgpr_128 = IMPLICIT_DEF625 bb.1:626 %2:sgpr_32 = COPY %1.sub2627 %3:sgpr_32 = COPY %1.sub1628 %1.sub2 = COPY %2629 undef %1.sub0 = IMPLICIT_DEF630 %1.sub2 = IMPLICIT_DEF631 S_CBRANCH_SCC1 %bb.1, implicit undef $scc632 S_BRANCH %bb.2633 bb.2:634)MIR",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);640 });641}642 643TEST(LiveIntervalTest, TestMoveSubRegsOfOneReg) {644 liveIntervalTest(645 R"MIR(646 INLINEASM &"", 0, 1835018, def undef %4.sub0:vreg_64, 1835018, def undef %4.sub1:vreg_64647 %1:vreg_64 = COPY %4648 undef %2.sub0:vreg_64 = V_MOV_B32_e32 0, implicit $exec649 %2.sub1:vreg_64 = COPY %2.sub0650 %3:vreg_64 = COPY %2651)MIR",652 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {653 testHandleMove(MF, LISWrapper.getLIS(), 1, 4);654 testHandleMove(MF, LISWrapper.getLIS(), 0, 3);655 });656}657 658TEST(LiveIntervalTest, BundleUse) {659 liveIntervalTest(660 R"MIR(661 %0 = IMPLICIT_DEF662 S_NOP 0663 S_NOP 0, implicit %0664 S_NOP 0665)MIR",666 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {667 testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);668 });669}670 671TEST(LiveIntervalTest, BundleDef) {672 liveIntervalTest(673 R"MIR(674 %0 = IMPLICIT_DEF675 S_NOP 0676 S_NOP 0, implicit %0677 S_NOP 0678)MIR",679 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {680 testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1);681 });682}683 684TEST(LiveIntervalTest, BundleRedef) {685 liveIntervalTest(686 R"MIR(687 %0 = IMPLICIT_DEF688 S_NOP 0689 %0 = IMPLICIT_DEF implicit %0(tied-def 0)690 S_NOP 0, implicit %0691)MIR",692 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {693 testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);694 });695}696 697TEST(LiveIntervalTest, BundleInternalUse) {698 liveIntervalTest(699 R"MIR(700 %0 = IMPLICIT_DEF701 S_NOP 0702 S_NOP 0, implicit %0703 S_NOP 0704)MIR",705 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {706 testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 2);707 });708}709 710TEST(LiveIntervalTest, BundleUndefUse) {711 liveIntervalTest(712 R"MIR(713 %0 = IMPLICIT_DEF714 S_NOP 0715 S_NOP 0, implicit undef %0716 S_NOP 0717)MIR",718 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {719 testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 1, 2);720 });721}722 723TEST(LiveIntervalTest, BundleSubRegUse) {724 liveIntervalTest(725 R"MIR(726 successors: %bb.1, %bb.2727 undef %0.sub0 = IMPLICIT_DEF728 %0.sub1 = IMPLICIT_DEF729 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc730 S_BRANCH %bb.1731 bb.1:732 S_NOP 0733 S_NOP 0, implicit %0.sub1734 bb.2:735 S_NOP 0, implicit %0.sub1736)MIR",737 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {738 testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1, 1);739 });740}741 742TEST(LiveIntervalTest, BundleSubRegDef) {743 liveIntervalTest(744 R"MIR(745 successors: %bb.1, %bb.2746 undef %0.sub0 = IMPLICIT_DEF747 %0.sub1 = IMPLICIT_DEF748 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc749 S_BRANCH %bb.1750 bb.1:751 S_NOP 0752 S_NOP 0, implicit %0.sub1753 bb.2:754 S_NOP 0, implicit %0.sub1755)MIR",756 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {757 testHandleMoveIntoNewBundle(MF, LISWrapper.getLIS(), 0, 1, 0);758 });759}760 761TEST(LiveIntervalTest, SplitAtOneInstruction) {762 liveIntervalTest(763 R"MIR(764 successors: %bb.1765 %0 = IMPLICIT_DEF766 S_BRANCH %bb.1767 bb.1:768 S_NOP 0769)MIR",770 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {771 testSplitAt(MF, LISWrapper.getLIS(), 1, 0);772 });773}774 775TEST(LiveIntervalTest, SplitAtMultiInstruction) {776 liveIntervalTest(777 R"MIR(778 successors: %bb.1779 %0 = IMPLICIT_DEF780 S_NOP 0781 S_NOP 0782 S_NOP 0783 S_NOP 0784 S_BRANCH %bb.1785 bb.1:786 S_NOP 0787)MIR",788 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {789 testSplitAt(MF, LISWrapper.getLIS(), 0, 0);790 });791}792 793TEST(LiveIntervalTest, RepairIntervals) {794 liveIntervalTest(795 R"MIR(796 %1:sgpr_32 = IMPLICIT_DEF797 dead %2:sgpr_32 = COPY undef %3.sub0:sgpr_128798 undef %4.sub2:sgpr_128 = COPY %1:sgpr_32799 %5:sgpr_32 = COPY %4.sub2:sgpr_128800)MIR",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(),812 };813 LIS.repairIntervalsInRange(MBB, Instr2, Instr3, OrigRegs);814 });815}816 817TEST(LiveIntervalTest, AdjacentIntervals) {818 liveIntervalTest(819 R"MIR(820 successors: %bb.1, %bb.2821 822 $vgpr1 = IMPLICIT_DEF823 S_NOP 0, implicit $vgpr1824 %1:vgpr_32 = IMPLICIT_DEF825 %2:vgpr_32 = IMPLICIT_DEF826 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc827 S_BRANCH %bb.1828 bb.1:829 $vgpr0, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec830 S_NOP 0, implicit $vgpr0831 S_BRANCH %bb.3832 bb.2:833 $vgpr0 = IMPLICIT_DEF834 $vgpr1, dead renamable $vcc = V_ADD_CO_U32_e64 %1, %2, 0, implicit $exec835 S_NOP 0, implicit $vgpr0, implicit $vgpr1836 S_BRANCH %bb.3837 bb.3:838)MIR",839 [](MachineFunction &MF, LiveIntervalsWrapperPass &LISWrapper) {840 auto &LIS = LISWrapper.getLIS();841 const auto &R1 =842 LIS.getInterval(getMI(MF, 2, 0).getOperand(0).getReg());843 const auto &R2 =844 LIS.getInterval(getMI(MF, 3, 0).getOperand(0).getReg());845 MCRegister V1 = getMI(MF, 1, 2).getOperand(0).getReg().asMCReg();846 847 ASSERT_FALSE(checkRegUnitInterference(848 LIS, *MF.getSubtarget().getRegisterInfo(), R1, V1));849 ASSERT_FALSE(checkRegUnitInterference(850 LIS, *MF.getSubtarget().getRegisterInfo(), R2, V1));851 });852}853 854TEST(LiveIntervalTest, LiveThroughSegments) {855 liveIntervalTest(856 R"MIR(857 %0 = IMPLICIT_DEF858 S_BRANCH %bb.2859 bb.1:860 S_NOP 0, implicit %0861 S_ENDPGM 0862 bb.2:863 S_BRANCH %bb.1864)MIR",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);872 873 // %0 is live through bb.2. Move its def into bb.1 and update LIS but do874 // not remove the segment for bb.2. This should cause machine875 // verification to fail.876 LIS.RemoveMachineInstrFromMaps(ImpDef);877 ImpDef.moveBefore(&Nop);878 LIS.InsertMachineInstrInMaps(ImpDef);879 880 SlotIndex NewIdx = LIS.getInstructionIndex(ImpDef).getRegSlot();881 FirstSeg->start = NewIdx;882 FirstSeg->valno->def = NewIdx;883 },884 false);885}886 887TEST(LiveVariablesTest, recomputeForSingleDefVirtReg_handle_undef1) {888 liveVariablesTest(889 R"MIR(890 %0 = IMPLICIT_DEF891 S_NOP 0, implicit %0892 S_NOP 0, implicit undef %0893)MIR",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());900 901 Register R = Register::index2VirtReg(0);902 LV.recomputeForSingleDefVirtReg(R);903 904 EXPECT_TRUE(FirstNop.getOperand(1).isKill());905 EXPECT_FALSE(SecondNop.getOperand(1).isKill());906 });907}908 909TEST(LiveVariablesTest, recomputeForSingleDefVirtReg_handle_undef2) {910 liveVariablesTest(911 R"MIR(912 %0 = IMPLICIT_DEF913 S_NOP 0, implicit %0914 S_NOP 0, implicit undef %0, implicit %0915)MIR",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());923 924 Register R = Register::index2VirtReg(0);925 LV.recomputeForSingleDefVirtReg(R);926 927 EXPECT_FALSE(FirstNop.getOperand(1).isKill());928 EXPECT_FALSE(SecondNop.getOperand(1).isKill());929 EXPECT_TRUE(SecondNop.getOperand(2).isKill());930 });931}932 933int main(int argc, char **argv) {934 ::testing::InitGoogleTest(&argc, argv);935 initLLVM();936 return RUN_ALL_TESTS();937}938