• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "AArch64Subtarget.h"
2 #include "AArch64TargetMachine.h"
3 #include "llvm/CodeGen/MIRParser/MIRParser.h"
4 #include "llvm/CodeGen/MachineModuleInfo.h"
5 #include "llvm/Support/TargetRegistry.h"
6 #include "llvm/Support/TargetSelect.h"
7 
8 #include "gtest/gtest.h"
9 
10 using namespace llvm;
11 
12 namespace {
createTargetMachine()13 std::unique_ptr<TargetMachine> createTargetMachine() {
14   auto TT(Triple::normalize("aarch64--"));
15   std::string CPU("generic");
16   std::string FS("");
17 
18   LLVMInitializeAArch64TargetInfo();
19   LLVMInitializeAArch64Target();
20   LLVMInitializeAArch64TargetMC();
21 
22   std::string Error;
23   const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
24 
25   return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
26       TT, CPU, FS, TargetOptions(), None, None, CodeGenOpt::Default));
27 }
28 
createInstrInfo(TargetMachine * TM)29 std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
30   AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
31                       TM->getTargetFeatureString(), *TM, /* isLittle */ false);
32   return llvm::make_unique<AArch64InstrInfo>(ST);
33 }
34 
35 /// The \p InputIRSnippet is only needed for things that can't be expressed in
36 /// the \p InputMIRSnippet (global variables etc)
37 /// TODO: Some of this might be useful for other architectures as well - extract
38 ///       the platform-independent parts somewhere they can be reused.
runChecks(TargetMachine * TM,AArch64InstrInfo * II,const StringRef InputIRSnippet,const StringRef InputMIRSnippet,std::function<void (AArch64InstrInfo &,MachineFunction &)> Checks)39 void runChecks(
40     TargetMachine *TM, AArch64InstrInfo *II, const StringRef InputIRSnippet,
41     const StringRef InputMIRSnippet,
42     std::function<void(AArch64InstrInfo &, MachineFunction &)> Checks) {
43   LLVMContext Context;
44 
45   auto MIRString =
46     "--- |\n"
47     "  declare void @sizes()\n"
48     + InputIRSnippet.str() +
49     "...\n"
50     "---\n"
51     "name: sizes\n"
52     "body: |\n"
53     "  bb.0:\n"
54     + InputMIRSnippet.str();
55 
56   std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString);
57   std::unique_ptr<MIRParser> MParser =
58       createMIRParser(std::move(MBuffer), Context);
59   ASSERT_TRUE(MParser);
60 
61   std::unique_ptr<Module> M = MParser->parseIRModule();
62   ASSERT_TRUE(M);
63 
64   M->setTargetTriple(TM->getTargetTriple().getTriple());
65   M->setDataLayout(TM->createDataLayout());
66 
67   MachineModuleInfo MMI(TM);
68   bool Res = MParser->parseMachineFunctions(*M, MMI);
69   ASSERT_FALSE(Res);
70 
71   auto F = M->getFunction("sizes");
72   ASSERT_TRUE(F != nullptr);
73   auto &MF = MMI.getOrCreateMachineFunction(*F);
74 
75   Checks(*II, MF);
76 }
77 
78 } // anonymous namespace
79 
TEST(InstSizes,STACKMAP)80 TEST(InstSizes, STACKMAP) {
81   std::unique_ptr<TargetMachine> TM = createTargetMachine();
82   ASSERT_TRUE(TM);
83   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
84 
85   runChecks(TM.get(), II.get(), "", "    STACKMAP 0, 16\n"
86                                     "    STACKMAP 1, 32\n",
87             [](AArch64InstrInfo &II, MachineFunction &MF) {
88               auto I = MF.begin()->begin();
89               EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
90               ++I;
91               EXPECT_EQ(32u, II.getInstSizeInBytes(*I));
92             });
93 }
94 
TEST(InstSizes,PATCHPOINT)95 TEST(InstSizes, PATCHPOINT) {
96   std::unique_ptr<TargetMachine> TM = createTargetMachine();
97   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
98 
99   runChecks(TM.get(), II.get(), "",
100             "    PATCHPOINT 0, 16, 0, 0, 0, csr_aarch64_aapcs\n"
101             "    PATCHPOINT 1, 32, 0, 0, 0, csr_aarch64_aapcs\n",
102             [](AArch64InstrInfo &II, MachineFunction &MF) {
103               auto I = MF.begin()->begin();
104               EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
105               ++I;
106               EXPECT_EQ(32u, II.getInstSizeInBytes(*I));
107             });
108 }
109 
TEST(InstSizes,TLSDESC_CALLSEQ)110 TEST(InstSizes, TLSDESC_CALLSEQ) {
111   std::unique_ptr<TargetMachine> TM = createTargetMachine();
112   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
113 
114   runChecks(
115       TM.get(), II.get(),
116       "  @ThreadLocalGlobal = external thread_local global i32, align 8\n",
117       "    TLSDESC_CALLSEQ target-flags(aarch64-tls) @ThreadLocalGlobal\n",
118       [](AArch64InstrInfo &II, MachineFunction &MF) {
119         auto I = MF.begin()->begin();
120         EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
121       });
122 }
123