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