xref: /llvm-project/llvm/unittests/Target/LoongArch/InstSizes.cpp (revision bb3f5e1fed7c6ba733b7f273e93f5d3930976185)
16d34074dSXiaodong Liu #include "LoongArchSubtarget.h"
26d34074dSXiaodong Liu #include "LoongArchTargetMachine.h"
36d34074dSXiaodong Liu #include "llvm/CodeGen/MIRParser/MIRParser.h"
46d34074dSXiaodong Liu #include "llvm/CodeGen/MachineModuleInfo.h"
54169338eSNikita Popov #include "llvm/IR/Module.h"
66d34074dSXiaodong Liu #include "llvm/MC/TargetRegistry.h"
76d34074dSXiaodong Liu #include "llvm/Support/MemoryBuffer.h"
86d34074dSXiaodong Liu #include "llvm/Support/TargetSelect.h"
9fda79685SKazu Hirata #include <optional>
106d34074dSXiaodong Liu 
116d34074dSXiaodong Liu #include "gtest/gtest.h"
126d34074dSXiaodong Liu 
136d34074dSXiaodong Liu using namespace llvm;
146d34074dSXiaodong Liu 
156d34074dSXiaodong Liu namespace {
16*bb3f5e1fSMatin Raayai std::unique_ptr<TargetMachine> createTargetMachine() {
176d34074dSXiaodong Liu   auto TT(Triple::normalize("loongarch64--"));
186d34074dSXiaodong Liu   std::string CPU("generic-la64");
196d34074dSXiaodong Liu   std::string FS("+64bit");
206d34074dSXiaodong Liu 
216d34074dSXiaodong Liu   LLVMInitializeLoongArchTargetInfo();
226d34074dSXiaodong Liu   LLVMInitializeLoongArchTarget();
236d34074dSXiaodong Liu   LLVMInitializeLoongArchTargetMC();
246d34074dSXiaodong Liu 
256d34074dSXiaodong Liu   std::string Error;
266d34074dSXiaodong Liu   const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
276d34074dSXiaodong Liu 
28*bb3f5e1fSMatin Raayai   return std::unique_ptr<TargetMachine>(
29fda79685SKazu Hirata       TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), std::nullopt,
30*bb3f5e1fSMatin Raayai                                      std::nullopt, CodeGenOptLevel::Default));
316d34074dSXiaodong Liu }
326d34074dSXiaodong Liu 
336d34074dSXiaodong Liu std::unique_ptr<LoongArchInstrInfo> createInstrInfo(TargetMachine *TM) {
346d34074dSXiaodong Liu   LoongArchSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
356d34074dSXiaodong Liu                         std::string(TM->getTargetCPU()),
366d34074dSXiaodong Liu                         std::string(TM->getTargetFeatureString()), "lp64d",
376d34074dSXiaodong Liu                         *TM);
386d34074dSXiaodong Liu   return std::make_unique<LoongArchInstrInfo>(ST);
396d34074dSXiaodong Liu }
406d34074dSXiaodong Liu 
416d34074dSXiaodong Liu /// The \p InputIRSnippet is only needed for things that can't be expressed in
426d34074dSXiaodong Liu /// the \p InputMIRSnippet (global variables etc)
436d34074dSXiaodong Liu /// Inspired by AArch64
446d34074dSXiaodong Liu void runChecks(
45*bb3f5e1fSMatin Raayai     TargetMachine *TM, LoongArchInstrInfo *II, const StringRef InputIRSnippet,
46*bb3f5e1fSMatin Raayai     const StringRef InputMIRSnippet,
476d34074dSXiaodong Liu     std::function<void(LoongArchInstrInfo &, MachineFunction &)> Checks) {
486d34074dSXiaodong Liu   LLVMContext Context;
496d34074dSXiaodong Liu 
506d34074dSXiaodong Liu   auto MIRString = "--- |\n"
516d34074dSXiaodong Liu                    "  declare void @sizes()\n" +
526d34074dSXiaodong Liu                    InputIRSnippet.str() +
536d34074dSXiaodong Liu                    "...\n"
546d34074dSXiaodong Liu                    "---\n"
556d34074dSXiaodong Liu                    "name: sizes\n"
566d34074dSXiaodong Liu                    "jumpTable:\n"
576d34074dSXiaodong Liu                    "  kind:            block-address\n"
586d34074dSXiaodong Liu                    "  entries:\n"
596d34074dSXiaodong Liu                    "    - id:              0\n"
606d34074dSXiaodong Liu                    "      blocks:          [ '%bb.0' ]\n"
616d34074dSXiaodong Liu                    "body: |\n"
626d34074dSXiaodong Liu                    "  bb.0:\n" +
636d34074dSXiaodong Liu                    InputMIRSnippet.str();
646d34074dSXiaodong Liu 
656d34074dSXiaodong Liu   std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString);
666d34074dSXiaodong Liu   std::unique_ptr<MIRParser> MParser =
676d34074dSXiaodong Liu       createMIRParser(std::move(MBuffer), Context);
686d34074dSXiaodong Liu   ASSERT_TRUE(MParser);
696d34074dSXiaodong Liu 
706d34074dSXiaodong Liu   std::unique_ptr<Module> M = MParser->parseIRModule();
716d34074dSXiaodong Liu   ASSERT_TRUE(M);
726d34074dSXiaodong Liu 
736d34074dSXiaodong Liu   M->setTargetTriple(TM->getTargetTriple().getTriple());
746d34074dSXiaodong Liu   M->setDataLayout(TM->createDataLayout());
756d34074dSXiaodong Liu 
766d34074dSXiaodong Liu   MachineModuleInfo MMI(TM);
776d34074dSXiaodong Liu   bool Res = MParser->parseMachineFunctions(*M, MMI);
786d34074dSXiaodong Liu   ASSERT_FALSE(Res);
796d34074dSXiaodong Liu 
806d34074dSXiaodong Liu   auto F = M->getFunction("sizes");
816d34074dSXiaodong Liu   ASSERT_TRUE(F != nullptr);
826d34074dSXiaodong Liu   auto &MF = MMI.getOrCreateMachineFunction(*F);
836d34074dSXiaodong Liu 
846d34074dSXiaodong Liu   Checks(*II, MF);
856d34074dSXiaodong Liu }
866d34074dSXiaodong Liu 
876d34074dSXiaodong Liu } // anonymous namespace
886d34074dSXiaodong Liu 
896d34074dSXiaodong Liu TEST(InstSizes, INLINEASM_BR) {
90*bb3f5e1fSMatin Raayai   std::unique_ptr<TargetMachine> TM = createTargetMachine();
916d34074dSXiaodong Liu   std::unique_ptr<LoongArchInstrInfo> II = createInstrInfo(TM.get());
926d34074dSXiaodong Liu 
936d34074dSXiaodong Liu   runChecks(TM.get(), II.get(), "",
946d34074dSXiaodong Liu             // clang-format off
956d34074dSXiaodong Liu             "  INLINEASM_BR &nop, 1 /* sideeffect attdialect */, 13 /* imm */, %jump-table.0\n",
966d34074dSXiaodong Liu             // clang-format on
976d34074dSXiaodong Liu             [](LoongArchInstrInfo &II, MachineFunction &MF) {
986d34074dSXiaodong Liu               auto I = MF.begin()->begin();
996d34074dSXiaodong Liu               EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
1006d34074dSXiaodong Liu             });
1016d34074dSXiaodong Liu }
1026d34074dSXiaodong Liu 
1036d34074dSXiaodong Liu TEST(InstSizes, SPACE) {
104*bb3f5e1fSMatin Raayai   std::unique_ptr<TargetMachine> TM = createTargetMachine();
1056d34074dSXiaodong Liu   std::unique_ptr<LoongArchInstrInfo> II = createInstrInfo(TM.get());
1066d34074dSXiaodong Liu 
1076d34074dSXiaodong Liu   runChecks(TM.get(), II.get(), "", "  INLINEASM &\".space 1024\", 1\n",
1086d34074dSXiaodong Liu             [](LoongArchInstrInfo &II, MachineFunction &MF) {
1096d34074dSXiaodong Liu               auto I = MF.begin()->begin();
1106d34074dSXiaodong Liu               EXPECT_EQ(1024u, II.getInstSizeInBytes(*I));
1116d34074dSXiaodong Liu             });
1126d34074dSXiaodong Liu }
1136d34074dSXiaodong Liu 
1146d34074dSXiaodong Liu TEST(InstSizes, AtomicPseudo) {
115*bb3f5e1fSMatin Raayai   std::unique_ptr<TargetMachine> TM = createTargetMachine();
1166d34074dSXiaodong Liu   std::unique_ptr<LoongArchInstrInfo> II = createInstrInfo(TM.get());
1176d34074dSXiaodong Liu 
1186d34074dSXiaodong Liu   runChecks(
1196d34074dSXiaodong Liu       TM.get(), II.get(), "",
1206d34074dSXiaodong Liu       // clang-format off
1216d34074dSXiaodong Liu       "    dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoMaskedAtomicLoadAdd32 renamable $r7, renamable $r6, renamable $r8, 4\n"
1226d34074dSXiaodong Liu       "    dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoAtomicLoadAdd32 renamable $r7, renamable $r6, renamable $r8\n"
1236d34074dSXiaodong Liu       "    dead early-clobber renamable $r5, dead early-clobber renamable $r9, dead early-clobber renamable $r10 = PseudoMaskedAtomicLoadUMax32 renamable $r7, renamable $r6, renamable $r8, 4\n"
1246d34074dSXiaodong Liu       "    early-clobber renamable $r9, dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoMaskedAtomicLoadMax32 killed renamable $r6, killed renamable $r5, killed renamable $r7, killed renamable $r8, 4\n"
125203ba238Shev       "    dead early-clobber renamable $r5, dead early-clobber renamable $r9 = PseudoCmpXchg32 renamable $r7, renamable $r4, renamable $r6, 4\n"
1266d34074dSXiaodong Liu       "    dead early-clobber renamable $r5, dead early-clobber renamable $r9 = PseudoMaskedCmpXchg32 killed renamable $r7, killed renamable $r4, killed renamable $r6, killed renamable $r8, 4\n",
1276d34074dSXiaodong Liu       // clang-format on
1286d34074dSXiaodong Liu       [](LoongArchInstrInfo &II, MachineFunction &MF) {
1296d34074dSXiaodong Liu         auto I = MF.begin()->begin();
1306d34074dSXiaodong Liu         EXPECT_EQ(36u, II.getInstSizeInBytes(*I));
1316d34074dSXiaodong Liu         ++I;
1326d34074dSXiaodong Liu         EXPECT_EQ(24u, II.getInstSizeInBytes(*I));
1336d34074dSXiaodong Liu         ++I;
1346d34074dSXiaodong Liu         EXPECT_EQ(48u, II.getInstSizeInBytes(*I));
1356d34074dSXiaodong Liu         ++I;
1366d34074dSXiaodong Liu         EXPECT_EQ(56u, II.getInstSizeInBytes(*I));
1376d34074dSXiaodong Liu         ++I;
1386d34074dSXiaodong Liu         EXPECT_EQ(36u, II.getInstSizeInBytes(*I));
1396d34074dSXiaodong Liu         ++I;
1406d34074dSXiaodong Liu         EXPECT_EQ(44u, II.getInstSizeInBytes(*I));
1416d34074dSXiaodong Liu       });
1426d34074dSXiaodong Liu }
143ffcebcdbSLu Weining 
144ffcebcdbSLu Weining TEST(InstSizes, StatePoint) {
145*bb3f5e1fSMatin Raayai   std::unique_ptr<TargetMachine> TM = createTargetMachine();
146ffcebcdbSLu Weining   std::unique_ptr<LoongArchInstrInfo> II = createInstrInfo(TM.get());
147ffcebcdbSLu Weining 
148ffcebcdbSLu Weining   runChecks(
149ffcebcdbSLu Weining       TM.get(), II.get(), "  declare zeroext i1 @return_i1()\n",
150ffcebcdbSLu Weining       // clang-format off
151ffcebcdbSLu Weining       "  STATEPOINT 0, 0, 0, target-flags(loongarch-call-plt) @return_i1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, implicit-def $r3, implicit-def $r4\n",
152ffcebcdbSLu Weining       // clang-format on
153ffcebcdbSLu Weining       [](LoongArchInstrInfo &II, MachineFunction &MF) {
154ffcebcdbSLu Weining         auto I = MF.begin()->begin();
155ffcebcdbSLu Weining         EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
156ffcebcdbSLu Weining       });
157ffcebcdbSLu Weining }
158