#include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "GISelMITest.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/LegacyPassManager.h" namespace { class EraseMockInstructionSelector : public InstructionSelector { public: int NumSelected = 0; SmallVector MIs; bool select(MachineInstr &MI) override { ++NumSelected; switch (NumSelected) { case 1: EXPECT_EQ(&MI, MIs[8]); // Erase previous instructions MIs[7]->eraseFromParent(); MIs[6]->eraseFromParent(); // Don't erase this MI before step 3 to prevent DCE return true; case 2: EXPECT_EQ(&MI, MIs[5]); // Erase previous instructions reversed MIs[3]->eraseFromParent(); MIs[4]->eraseFromParent(); MI.eraseFromParent(); return true; case 3: EXPECT_EQ(&MI, MIs[2]); MIs[8]->eraseFromParent(); // Erase first instructions MIs[0]->eraseFromParent(); MIs[1]->eraseFromParent(); MI.eraseFromParent(); return true; default: ADD_FAILURE(); return false; } } void setupGeneratedPerFunctionState(MachineFunction &MF) override {} }; TEST_F(AArch64GISelMITest, TestInstructionSelectErase) { StringRef MIRString = R"( $x0 = COPY %2(s64) $x0 = COPY %2(s64) $x0 = COPY %2(s64) $x0 = COPY %2(s64) $x0 = COPY %2(s64) $x0 = COPY %2(s64) )"; setUp(MIRString); if (!TM) GTEST_SKIP(); legacy::PassManager PM; std::unique_ptr TPC(TM->createPassConfig(PM)); EraseMockInstructionSelector ISel; ISel.TPC = TPC.get(); for (auto &MI : *EntryMBB) { ISel.MIs.push_back(&MI); } InstructionSelect ISelPass; ISelPass.setInstructionSelector(&ISel); ISelPass.selectMachineFunction(*MF); EXPECT_EQ(ISel.NumSelected, 3); } } // namespace