xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/InstructionSelectTest.cpp (revision d2336fd75cc93d5191d56f8c7486069dc8aeec5b)
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