brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.6 KiB · 45b8aeb Raw
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