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"
8 #include "gtest/gtest.h"
13 std::unique_ptr
<LLVMTargetMachine
> createTargetMachine() {
14 auto TT(Triple::normalize("aarch64--"));
15 std::string
CPU("generic");
18 LLVMInitializeAArch64TargetInfo();
19 LLVMInitializeAArch64Target();
20 LLVMInitializeAArch64TargetMC();
23 const Target
*TheTarget
= TargetRegistry::lookupTarget(TT
, Error
);
25 return std::unique_ptr
<LLVMTargetMachine
>(static_cast<LLVMTargetMachine
*>(
26 TheTarget
->createTargetMachine(TT
, CPU
, FS
, TargetOptions(), None
, None
,
27 CodeGenOpt::Default
)));
30 std::unique_ptr
<AArch64InstrInfo
> createInstrInfo(TargetMachine
*TM
) {
31 AArch64Subtarget
ST(TM
->getTargetTriple(), TM
->getTargetCPU(),
32 TM
->getTargetFeatureString(), *TM
, /* isLittle */ false);
33 return llvm::make_unique
<AArch64InstrInfo
>(ST
);
36 /// The \p InputIRSnippet is only needed for things that can't be expressed in
37 /// the \p InputMIRSnippet (global variables etc)
38 /// TODO: Some of this might be useful for other architectures as well - extract
39 /// the platform-independent parts somewhere they can be reused.
41 LLVMTargetMachine
*TM
, AArch64InstrInfo
*II
, const StringRef InputIRSnippet
,
42 const StringRef InputMIRSnippet
,
43 std::function
<void(AArch64InstrInfo
&, MachineFunction
&)> Checks
) {
48 " declare void @sizes()\n"
49 + InputIRSnippet
.str() +
55 + InputMIRSnippet
.str();
57 std::unique_ptr
<MemoryBuffer
> MBuffer
= MemoryBuffer::getMemBuffer(MIRString
);
58 std::unique_ptr
<MIRParser
> MParser
=
59 createMIRParser(std::move(MBuffer
), Context
);
62 std::unique_ptr
<Module
> M
= MParser
->parseIRModule();
65 M
->setTargetTriple(TM
->getTargetTriple().getTriple());
66 M
->setDataLayout(TM
->createDataLayout());
68 MachineModuleInfo
MMI(TM
);
69 bool Res
= MParser
->parseMachineFunctions(*M
, MMI
);
72 auto F
= M
->getFunction("sizes");
73 ASSERT_TRUE(F
!= nullptr);
74 auto &MF
= MMI
.getOrCreateMachineFunction(*F
);
79 } // anonymous namespace
81 TEST(InstSizes
, STACKMAP
) {
82 std::unique_ptr
<LLVMTargetMachine
> TM
= createTargetMachine();
84 std::unique_ptr
<AArch64InstrInfo
> II
= createInstrInfo(TM
.get());
86 runChecks(TM
.get(), II
.get(), "", " STACKMAP 0, 16\n"
88 [](AArch64InstrInfo
&II
, MachineFunction
&MF
) {
89 auto I
= MF
.begin()->begin();
90 EXPECT_EQ(16u, II
.getInstSizeInBytes(*I
));
92 EXPECT_EQ(32u, II
.getInstSizeInBytes(*I
));
96 TEST(InstSizes
, PATCHPOINT
) {
97 std::unique_ptr
<LLVMTargetMachine
> TM
= createTargetMachine();
98 std::unique_ptr
<AArch64InstrInfo
> II
= createInstrInfo(TM
.get());
100 runChecks(TM
.get(), II
.get(), "",
101 " PATCHPOINT 0, 16, 0, 0, 0, csr_aarch64_aapcs\n"
102 " PATCHPOINT 1, 32, 0, 0, 0, csr_aarch64_aapcs\n",
103 [](AArch64InstrInfo
&II
, MachineFunction
&MF
) {
104 auto I
= MF
.begin()->begin();
105 EXPECT_EQ(16u, II
.getInstSizeInBytes(*I
));
107 EXPECT_EQ(32u, II
.getInstSizeInBytes(*I
));
111 TEST(InstSizes
, TLSDESC_CALLSEQ
) {
112 std::unique_ptr
<LLVMTargetMachine
> TM
= createTargetMachine();
113 std::unique_ptr
<AArch64InstrInfo
> II
= createInstrInfo(TM
.get());
117 " @ThreadLocalGlobal = external thread_local global i32, align 8\n",
118 " TLSDESC_CALLSEQ target-flags(aarch64-tls) @ThreadLocalGlobal\n",
119 [](AArch64InstrInfo
&II
, MachineFunction
&MF
) {
120 auto I
= MF
.begin()->begin();
121 EXPECT_EQ(16u, II
.getInstSizeInBytes(*I
));