1*d2336fd7STobias Stadler #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 2*d2336fd7STobias Stadler #include "GISelMITest.h" 3*d2336fd7STobias Stadler #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 4*d2336fd7STobias Stadler #include "llvm/CodeGen/TargetPassConfig.h" 5*d2336fd7STobias Stadler #include "llvm/IR/LegacyPassManager.h" 6*d2336fd7STobias Stadler 7*d2336fd7STobias Stadler namespace { 8*d2336fd7STobias Stadler 9*d2336fd7STobias Stadler class EraseMockInstructionSelector : public InstructionSelector { 10*d2336fd7STobias Stadler public: 11*d2336fd7STobias Stadler int NumSelected = 0; 12*d2336fd7STobias Stadler SmallVector<MachineInstr *> MIs; 13*d2336fd7STobias Stadler 14*d2336fd7STobias Stadler bool select(MachineInstr &MI) override { 15*d2336fd7STobias Stadler ++NumSelected; 16*d2336fd7STobias Stadler switch (NumSelected) { 17*d2336fd7STobias Stadler case 1: 18*d2336fd7STobias Stadler EXPECT_EQ(&MI, MIs[8]); 19*d2336fd7STobias Stadler // Erase previous instructions 20*d2336fd7STobias Stadler MIs[7]->eraseFromParent(); 21*d2336fd7STobias Stadler MIs[6]->eraseFromParent(); 22*d2336fd7STobias Stadler // Don't erase this MI before step 3 to prevent DCE 23*d2336fd7STobias Stadler return true; 24*d2336fd7STobias Stadler case 2: 25*d2336fd7STobias Stadler EXPECT_EQ(&MI, MIs[5]); 26*d2336fd7STobias Stadler // Erase previous instructions reversed 27*d2336fd7STobias Stadler MIs[3]->eraseFromParent(); 28*d2336fd7STobias Stadler MIs[4]->eraseFromParent(); 29*d2336fd7STobias Stadler MI.eraseFromParent(); 30*d2336fd7STobias Stadler return true; 31*d2336fd7STobias Stadler case 3: 32*d2336fd7STobias Stadler EXPECT_EQ(&MI, MIs[2]); 33*d2336fd7STobias Stadler MIs[8]->eraseFromParent(); 34*d2336fd7STobias Stadler // Erase first instructions 35*d2336fd7STobias Stadler MIs[0]->eraseFromParent(); 36*d2336fd7STobias Stadler MIs[1]->eraseFromParent(); 37*d2336fd7STobias Stadler MI.eraseFromParent(); 38*d2336fd7STobias Stadler return true; 39*d2336fd7STobias Stadler default: 40*d2336fd7STobias Stadler ADD_FAILURE(); 41*d2336fd7STobias Stadler return false; 42*d2336fd7STobias Stadler } 43*d2336fd7STobias Stadler } 44*d2336fd7STobias Stadler 45*d2336fd7STobias Stadler void setupGeneratedPerFunctionState(MachineFunction &MF) override {} 46*d2336fd7STobias Stadler }; 47*d2336fd7STobias Stadler 48*d2336fd7STobias Stadler TEST_F(AArch64GISelMITest, TestInstructionSelectErase) { 49*d2336fd7STobias Stadler StringRef MIRString = R"( 50*d2336fd7STobias Stadler $x0 = COPY %2(s64) 51*d2336fd7STobias Stadler $x0 = COPY %2(s64) 52*d2336fd7STobias Stadler $x0 = COPY %2(s64) 53*d2336fd7STobias Stadler $x0 = COPY %2(s64) 54*d2336fd7STobias Stadler $x0 = COPY %2(s64) 55*d2336fd7STobias Stadler $x0 = COPY %2(s64) 56*d2336fd7STobias Stadler )"; 57*d2336fd7STobias Stadler setUp(MIRString); 58*d2336fd7STobias Stadler if (!TM) 59*d2336fd7STobias Stadler GTEST_SKIP(); 60*d2336fd7STobias Stadler 61*d2336fd7STobias Stadler legacy::PassManager PM; 62*d2336fd7STobias Stadler std::unique_ptr<TargetPassConfig> TPC(TM->createPassConfig(PM)); 63*d2336fd7STobias Stadler 64*d2336fd7STobias Stadler EraseMockInstructionSelector ISel; 65*d2336fd7STobias Stadler ISel.TPC = TPC.get(); 66*d2336fd7STobias Stadler for (auto &MI : *EntryMBB) { 67*d2336fd7STobias Stadler ISel.MIs.push_back(&MI); 68*d2336fd7STobias Stadler } 69*d2336fd7STobias Stadler 70*d2336fd7STobias Stadler InstructionSelect ISelPass; 71*d2336fd7STobias Stadler ISelPass.setInstructionSelector(&ISel); 72*d2336fd7STobias Stadler ISelPass.selectMachineFunction(*MF); 73*d2336fd7STobias Stadler EXPECT_EQ(ISel.NumSelected, 3); 74*d2336fd7STobias Stadler } 75*d2336fd7STobias Stadler 76*d2336fd7STobias Stadler } // namespace 77