Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / unittests / Target / AArch64 / InstSizes.cpp
blobd7e4b4a91cdbd6b1ec97a1f24b900656518c6b06
1 #include "AArch64Subtarget.h"
2 #include "AArch64TargetMachine.h"
3 #include "llvm/CodeGen/MIRParser/MIRParser.h"
4 #include "llvm/CodeGen/MachineModuleInfo.h"
5 #include "llvm/MC/TargetRegistry.h"
6 #include "llvm/Support/MemoryBuffer.h"
7 #include "llvm/Support/TargetSelect.h"
9 #include "gtest/gtest.h"
11 using namespace llvm;
13 namespace {
14 std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
15 auto TT(Triple::normalize("aarch64--"));
16 std::string CPU("generic");
17 std::string FS("+pauth,+mops,+mte");
19 LLVMInitializeAArch64TargetInfo();
20 LLVMInitializeAArch64Target();
21 LLVMInitializeAArch64TargetMC();
23 std::string Error;
24 const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
26 return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
27 TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), std::nullopt,
28 std::nullopt, CodeGenOptLevel::Default)));
31 std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
32 AArch64Subtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
33 std::string(TM->getTargetCPU()),
34 std::string(TM->getTargetFeatureString()), *TM,
35 /* isLittle */ false);
36 return std::make_unique<AArch64InstrInfo>(ST);
39 /// The \p InputIRSnippet is only needed for things that can't be expressed in
40 /// the \p InputMIRSnippet (global variables etc)
41 /// TODO: Some of this might be useful for other architectures as well - extract
42 /// the platform-independent parts somewhere they can be reused.
43 void runChecks(
44 LLVMTargetMachine *TM, AArch64InstrInfo *II, const StringRef InputIRSnippet,
45 const StringRef InputMIRSnippet,
46 std::function<void(AArch64InstrInfo &, MachineFunction &)> Checks) {
47 LLVMContext Context;
49 auto MIRString =
50 "--- |\n"
51 " declare void @sizes()\n"
52 + InputIRSnippet.str() +
53 "...\n"
54 "---\n"
55 "name: sizes\n"
56 "jumpTable:\n"
57 " kind: block-address\n"
58 " entries:\n"
59 " - id: 0\n"
60 " blocks: [ '%bb.0' ]\n"
61 "body: |\n"
62 " bb.0:\n"
63 + InputMIRSnippet.str();
65 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString);
66 std::unique_ptr<MIRParser> MParser =
67 createMIRParser(std::move(MBuffer), Context);
68 ASSERT_TRUE(MParser);
70 std::unique_ptr<Module> M = MParser->parseIRModule();
71 ASSERT_TRUE(M);
73 M->setTargetTriple(TM->getTargetTriple().getTriple());
74 M->setDataLayout(TM->createDataLayout());
76 MachineModuleInfo MMI(TM);
77 bool Res = MParser->parseMachineFunctions(*M, MMI);
78 ASSERT_FALSE(Res);
80 auto F = M->getFunction("sizes");
81 ASSERT_TRUE(F != nullptr);
82 auto &MF = MMI.getOrCreateMachineFunction(*F);
84 Checks(*II, MF);
87 } // anonymous namespace
89 TEST(InstSizes, Authenticated) {
90 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
91 ASSERT_TRUE(TM);
92 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
94 auto isAuthInst = [](AArch64InstrInfo &II, MachineFunction &MF) {
95 auto I = MF.begin()->begin();
96 EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
97 EXPECT_TRUE(I->getDesc().isAuthenticated());
100 runChecks(TM.get(), II.get(), "",
101 " \n"
102 " BLRAA $x10, $x9\n",
103 isAuthInst);
105 runChecks(TM.get(), II.get(), "",
106 " \n"
107 " RETAB implicit $lr, implicit $sp, implicit killed $x0\n",
108 isAuthInst);
110 runChecks(TM.get(), II.get(), "",
111 " \n"
112 " frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp\n",
113 isAuthInst);
115 runChecks(TM.get(), II.get(), "",
116 " \n"
117 " frame-destroy AUTIBSP implicit-def $lr, implicit killed $lr, implicit $sp\n",
118 isAuthInst);
121 TEST(InstSizes, STACKMAP) {
122 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
123 ASSERT_TRUE(TM);
124 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
126 runChecks(TM.get(), II.get(), "", " STACKMAP 0, 16\n"
127 " STACKMAP 1, 32\n",
128 [](AArch64InstrInfo &II, MachineFunction &MF) {
129 auto I = MF.begin()->begin();
130 EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
131 ++I;
132 EXPECT_EQ(32u, II.getInstSizeInBytes(*I));
136 TEST(InstSizes, PATCHPOINT) {
137 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
138 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
140 runChecks(TM.get(), II.get(), "",
141 " PATCHPOINT 0, 16, 0, 0, 0, csr_aarch64_aapcs\n"
142 " PATCHPOINT 1, 32, 0, 0, 0, csr_aarch64_aapcs\n",
143 [](AArch64InstrInfo &II, MachineFunction &MF) {
144 auto I = MF.begin()->begin();
145 EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
146 ++I;
147 EXPECT_EQ(32u, II.getInstSizeInBytes(*I));
151 TEST(InstSizes, STATEPOINT) {
152 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
153 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
155 runChecks(TM.get(), II.get(), "",
156 " STATEPOINT 0, 0, 0, @sizes, 2, 0, 2, 0, 2, 0, 2, 1, 1, 8,"
157 " $sp, 24, 2, 0, 2, 1, 0, 0\n",
158 [](AArch64InstrInfo &II, MachineFunction &MF) {
159 auto I = MF.begin()->begin();
160 EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
164 TEST(InstSizes, SPACE) {
165 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
166 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
168 runChecks(TM.get(), II.get(), "",
169 " $xzr = SPACE 1024, undef $xzr\n"
170 " dead $xzr = SPACE 4096, $xzr\n",
171 [](AArch64InstrInfo &II, MachineFunction &MF) {
172 auto I = MF.begin()->begin();
173 EXPECT_EQ(1024u, II.getInstSizeInBytes(*I));
174 ++I;
175 EXPECT_EQ(4096u, II.getInstSizeInBytes(*I));
179 TEST(InstSizes, TLSDESC_CALLSEQ) {
180 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
181 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
183 runChecks(
184 TM.get(), II.get(),
185 " @ThreadLocalGlobal = external thread_local global i32, align 8\n",
186 " TLSDESC_CALLSEQ target-flags(aarch64-tls) @ThreadLocalGlobal\n",
187 [](AArch64InstrInfo &II, MachineFunction &MF) {
188 auto I = MF.begin()->begin();
189 EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
193 TEST(InstSizes, StoreSwiftAsyncContext) {
194 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
195 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
197 runChecks(
198 TM.get(), II.get(), "",
199 " StoreSwiftAsyncContext $x0, $x1, 12, implicit-def $x16, "
200 "implicit-def $x17\n",
201 [](AArch64InstrInfo &II, MachineFunction &MF) {
202 auto I = MF.begin()->begin();
203 EXPECT_EQ(20u, II.getInstSizeInBytes(*I));
207 TEST(InstSizes, SpeculationBarrierISBDSBEndBB) {
208 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
209 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
211 runChecks(
212 TM.get(), II.get(), "",
213 " SpeculationBarrierISBDSBEndBB\n"
214 " BR $x8\n",
215 [](AArch64InstrInfo &II, MachineFunction &MF) {
216 auto I = MF.begin()->begin();
217 EXPECT_EQ(8u, II.getInstSizeInBytes(*I));
221 TEST(InstSizes, SpeculationBarrierSBEndBB) {
222 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
223 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
225 runChecks(
226 TM.get(), II.get(), "",
227 " SpeculationBarrierSBEndBB\n"
228 " BR $x8\n",
229 [](AArch64InstrInfo &II, MachineFunction &MF) {
230 auto I = MF.begin()->begin();
231 EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
235 TEST(InstSizes, JumpTable) {
236 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
237 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
239 runChecks(TM.get(), II.get(), "",
240 " $x10, $x11 = JumpTableDest32 $x9, $x8, %jump-table.0\n"
241 " $x10, $x11 = JumpTableDest16 $x9, $x8, %jump-table.0\n"
242 " $x10, $x11 = JumpTableDest8 $x9, $x8, %jump-table.0\n",
243 [](AArch64InstrInfo &II, MachineFunction &MF) {
244 auto I = MF.begin()->begin();
245 EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
246 ++I;
247 EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
248 ++I;
249 EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
253 TEST(InstSizes, MOPSMemoryPseudos) {
254 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
255 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
257 runChecks(TM.get(), II.get(), "",
258 " $x0, $x1, $x2 = MOPSMemoryMovePseudo $x0, $x1, $x2, "
259 "implicit-def $nzcv\n"
260 " $x0, $x1 = MOPSMemorySetPseudo $x0, $x1, $x2, "
261 "implicit-def $nzcv\n"
262 " $x0, $x1, $x8 = MOPSMemoryCopyPseudo $x0, $x1, $x8, "
263 "implicit-def $nzcv\n"
264 " $x0, $x1 = MOPSMemorySetTaggingPseudo $x0, $x1, $x2, "
265 "implicit-def $nzcv\n",
266 [](AArch64InstrInfo &II, MachineFunction &MF) {
267 auto I = MF.begin()->begin();
268 EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
269 ++I;
270 EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
271 ++I;
272 EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
273 ++I;
274 EXPECT_EQ(12u, II.getInstSizeInBytes(*I));