[HLSL] Implement RWBuffer::operator[] via __builtin_hlsl_resource_getpointer (#117017)
[llvm-project.git] / llvm / unittests / CodeGen / MachineInstrTest.cpp
blobc32c2ce859af5d9b61df5a0258243c777fdbfb46
1 //===- MachineInstrTest.cpp -----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/CodeGen/MachineInstr.h"
10 #include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
11 #include "llvm/CodeGen/MachineBasicBlock.h"
12 #include "llvm/CodeGen/MachineFunction.h"
13 #include "llvm/CodeGen/MachineInstrBuilder.h"
14 #include "llvm/CodeGen/MachineMemOperand.h"
15 #include "llvm/CodeGen/MachineModuleInfo.h"
16 #include "llvm/CodeGen/TargetFrameLowering.h"
17 #include "llvm/CodeGen/TargetInstrInfo.h"
18 #include "llvm/CodeGen/TargetLowering.h"
19 #include "llvm/CodeGen/TargetSubtargetInfo.h"
20 #include "llvm/IR/DebugInfoMetadata.h"
21 #include "llvm/IR/IRBuilder.h"
22 #include "llvm/IR/MemoryModelRelaxationAnnotations.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/IR/ModuleSlotTracker.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/TargetRegistry.h"
28 #include "llvm/Support/TargetSelect.h"
29 #include "llvm/Target/TargetOptions.h"
30 #include "llvm/TargetParser/Triple.h"
31 #include "gmock/gmock.h"
32 #include "gtest/gtest.h"
34 using namespace llvm;
36 namespace {
37 // Include helper functions to ease the manipulation of MachineFunctions.
38 #include "MFCommon.inc"
40 std::unique_ptr<MCContext> createMCContext(MCAsmInfo *AsmInfo) {
41 Triple TheTriple(/*ArchStr=*/"", /*VendorStr=*/"", /*OSStr=*/"",
42 /*EnvironmentStr=*/"elf");
43 return std::make_unique<MCContext>(TheTriple, AsmInfo, nullptr, nullptr,
44 nullptr, nullptr, false);
47 // This test makes sure that MachineInstr::isIdenticalTo handles Defs correctly
48 // for various combinations of IgnoreDefs, and also that it is symmetrical.
49 TEST(IsIdenticalToTest, DifferentDefs) {
50 LLVMContext Ctx;
51 Module Mod("Module", Ctx);
52 auto MF = createMachineFunction(Ctx, Mod);
54 unsigned short NumOps = 2;
55 unsigned char NumDefs = 1;
56 struct {
57 MCInstrDesc MCID;
58 MCOperandInfo OpInfo[2];
59 } Table = {
60 {0, NumOps, NumDefs, 0, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, 0},
61 {{0, 0, MCOI::OPERAND_REGISTER, 0},
62 {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}};
64 // Create two MIs with different virtual reg defs and the same uses.
65 unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does.
66 unsigned VirtualDef2 = -43;
67 unsigned VirtualUse = -44;
69 auto MI1 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
70 MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
71 MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));
73 auto MI2 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
74 MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
75 MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));
77 // Check that they are identical when we ignore virtual register defs, but not
78 // when we check defs.
79 ASSERT_FALSE(MI1->isIdenticalTo(*MI2, MachineInstr::CheckDefs));
80 ASSERT_FALSE(MI2->isIdenticalTo(*MI1, MachineInstr::CheckDefs));
82 ASSERT_TRUE(MI1->isIdenticalTo(*MI2, MachineInstr::IgnoreVRegDefs));
83 ASSERT_TRUE(MI2->isIdenticalTo(*MI1, MachineInstr::IgnoreVRegDefs));
85 // Create two MIs with different virtual reg defs, and a def or use of a
86 // sentinel register.
87 unsigned SentinelReg = 0;
89 auto MI3 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
90 MI3->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
91 MI3->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));
93 auto MI4 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
94 MI4->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
95 MI4->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));
97 // Check that they are never identical.
98 ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::CheckDefs));
99 ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::CheckDefs));
101 ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::IgnoreVRegDefs));
102 ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::IgnoreVRegDefs));
105 // Check that MachineInstrExpressionTrait::isEqual is symmetric and in sync with
106 // MachineInstrExpressionTrait::getHashValue
107 void checkHashAndIsEqualMatch(MachineInstr *MI1, MachineInstr *MI2) {
108 bool IsEqual1 = MachineInstrExpressionTrait::isEqual(MI1, MI2);
109 bool IsEqual2 = MachineInstrExpressionTrait::isEqual(MI2, MI1);
111 ASSERT_EQ(IsEqual1, IsEqual2);
113 auto Hash1 = MachineInstrExpressionTrait::getHashValue(MI1);
114 auto Hash2 = MachineInstrExpressionTrait::getHashValue(MI2);
116 ASSERT_EQ(IsEqual1, Hash1 == Hash2);
119 // This test makes sure that MachineInstrExpressionTraits::isEqual is in sync
120 // with MachineInstrExpressionTraits::getHashValue.
121 TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {
122 LLVMContext Ctx;
123 Module Mod("Module", Ctx);
124 auto MF = createMachineFunction(Ctx, Mod);
126 unsigned short NumOps = 2;
127 unsigned char NumDefs = 1;
128 struct {
129 MCInstrDesc MCID;
130 MCOperandInfo OpInfo[2];
131 } Table = {
132 {0, NumOps, NumDefs, 0, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, 0},
133 {{0, 0, MCOI::OPERAND_REGISTER, 0},
134 {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}};
136 // Define a series of instructions with different kinds of operands and make
137 // sure that the hash function is consistent with isEqual for various
138 // combinations of them.
139 unsigned VirtualDef1 = -42;
140 unsigned VirtualDef2 = -43;
141 unsigned VirtualReg = -44;
142 unsigned SentinelReg = 0;
143 unsigned PhysicalReg = 45;
145 auto VD1VU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
146 VD1VU->addOperand(*MF,
147 MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
148 VD1VU->addOperand(*MF,
149 MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));
151 auto VD2VU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
152 VD2VU->addOperand(*MF,
153 MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
154 VD2VU->addOperand(*MF,
155 MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));
157 auto VD1SU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
158 VD1SU->addOperand(*MF,
159 MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
160 VD1SU->addOperand(*MF,
161 MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));
163 auto VD1SD = MF->CreateMachineInstr(Table.MCID, DebugLoc());
164 VD1SD->addOperand(*MF,
165 MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
166 VD1SD->addOperand(*MF,
167 MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));
169 auto VD2PU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
170 VD2PU->addOperand(*MF,
171 MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
172 VD2PU->addOperand(*MF,
173 MachineOperand::CreateReg(PhysicalReg, /*isDef*/ false));
175 auto VD2PD = MF->CreateMachineInstr(Table.MCID, DebugLoc());
176 VD2PD->addOperand(*MF,
177 MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
178 VD2PD->addOperand(*MF,
179 MachineOperand::CreateReg(PhysicalReg, /*isDef*/ true));
181 checkHashAndIsEqualMatch(VD1VU, VD2VU);
182 checkHashAndIsEqualMatch(VD1VU, VD1SU);
183 checkHashAndIsEqualMatch(VD1VU, VD1SD);
184 checkHashAndIsEqualMatch(VD1VU, VD2PU);
185 checkHashAndIsEqualMatch(VD1VU, VD2PD);
187 checkHashAndIsEqualMatch(VD2VU, VD1SU);
188 checkHashAndIsEqualMatch(VD2VU, VD1SD);
189 checkHashAndIsEqualMatch(VD2VU, VD2PU);
190 checkHashAndIsEqualMatch(VD2VU, VD2PD);
192 checkHashAndIsEqualMatch(VD1SU, VD1SD);
193 checkHashAndIsEqualMatch(VD1SU, VD2PU);
194 checkHashAndIsEqualMatch(VD1SU, VD2PD);
196 checkHashAndIsEqualMatch(VD1SD, VD2PU);
197 checkHashAndIsEqualMatch(VD1SD, VD2PD);
199 checkHashAndIsEqualMatch(VD2PU, VD2PD);
202 TEST(MachineInstrPrintingTest, DebugLocPrinting) {
203 LLVMContext Ctx;
204 Module Mod("Module", Ctx);
205 auto MF = createMachineFunction(Ctx, Mod);
207 struct {
208 MCInstrDesc MCID;
209 MCOperandInfo OpInfo;
210 } Table = {{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
211 {0, 0, MCOI::OPERAND_REGISTER, 0}};
213 DIFile *DIF = DIFile::getDistinct(Ctx, "filename", "");
214 DISubprogram *DIS = DISubprogram::getDistinct(
215 Ctx, nullptr, "", "", DIF, 0, nullptr, 0, nullptr, 0, 0, DINode::FlagZero,
216 DISubprogram::SPFlagZero, nullptr);
217 DILocation *DIL = DILocation::get(Ctx, 1, 5, DIS);
218 DebugLoc DL(DIL);
219 MachineInstr *MI = MF->CreateMachineInstr(Table.MCID, DL);
220 MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ true));
222 std::string str;
223 raw_string_ostream OS(str);
224 MI->print(OS, /*IsStandalone*/true, /*SkipOpers*/false, /*SkipDebugLoc*/false,
225 /*AddNewLine*/false);
226 ASSERT_TRUE(StringRef(str).starts_with("$noreg = UNKNOWN debug-location "));
227 ASSERT_TRUE(StringRef(str).ends_with("filename:1:5"));
230 TEST(MachineInstrSpan, DistanceBegin) {
231 LLVMContext Ctx;
232 Module Mod("Module", Ctx);
233 auto MF = createMachineFunction(Ctx, Mod);
234 auto MBB = MF->CreateMachineBasicBlock();
236 MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
238 auto MII = MBB->begin();
239 MachineInstrSpan MIS(MII, MBB);
240 ASSERT_TRUE(MIS.empty());
242 auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
243 MBB->insert(MII, MI);
244 ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
247 TEST(MachineInstrSpan, DistanceEnd) {
248 LLVMContext Ctx;
249 Module Mod("Module", Ctx);
250 auto MF = createMachineFunction(Ctx, Mod);
251 auto MBB = MF->CreateMachineBasicBlock();
253 MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
255 auto MII = MBB->end();
256 MachineInstrSpan MIS(MII, MBB);
257 ASSERT_TRUE(MIS.empty());
259 auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
260 MBB->insert(MII, MI);
261 ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
264 TEST(MachineInstrExtraInfo, AddExtraInfo) {
265 LLVMContext Ctx;
266 Module Mod("Module", Ctx);
267 auto MF = createMachineFunction(Ctx, Mod);
268 MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
270 auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
271 auto MAI = MCAsmInfo();
272 auto MC = createMCContext(&MAI);
273 auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
274 MachineMemOperand::MOLoad, 8, Align(8));
275 SmallVector<MachineMemOperand *, 2> MMOs;
276 MMOs.push_back(MMO);
277 MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
278 MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
279 MDNode *HAM = MDNode::getDistinct(Ctx, {});
280 MDNode *PCS = MDNode::getDistinct(Ctx, {});
281 MDNode *MMRA = MMRAMetadata::getTagMD(Ctx, "foo", "bar");
283 ASSERT_TRUE(MI->memoperands_empty());
284 ASSERT_FALSE(MI->getPreInstrSymbol());
285 ASSERT_FALSE(MI->getPostInstrSymbol());
286 ASSERT_FALSE(MI->getHeapAllocMarker());
287 ASSERT_FALSE(MI->getPCSections());
288 ASSERT_FALSE(MI->getMMRAMetadata());
290 MI->setMemRefs(*MF, MMOs);
291 ASSERT_TRUE(MI->memoperands().size() == 1);
292 ASSERT_FALSE(MI->getPreInstrSymbol());
293 ASSERT_FALSE(MI->getPostInstrSymbol());
294 ASSERT_FALSE(MI->getHeapAllocMarker());
295 ASSERT_FALSE(MI->getPCSections());
296 ASSERT_FALSE(MI->getMMRAMetadata());
298 MI->setPreInstrSymbol(*MF, Sym1);
299 ASSERT_TRUE(MI->memoperands().size() == 1);
300 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
301 ASSERT_FALSE(MI->getPostInstrSymbol());
302 ASSERT_FALSE(MI->getHeapAllocMarker());
303 ASSERT_FALSE(MI->getPCSections());
304 ASSERT_FALSE(MI->getMMRAMetadata());
306 MI->setPostInstrSymbol(*MF, Sym2);
307 ASSERT_TRUE(MI->memoperands().size() == 1);
308 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
309 ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
310 ASSERT_FALSE(MI->getHeapAllocMarker());
311 ASSERT_FALSE(MI->getPCSections());
312 ASSERT_FALSE(MI->getMMRAMetadata());
314 MI->setHeapAllocMarker(*MF, HAM);
315 ASSERT_TRUE(MI->memoperands().size() == 1);
316 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
317 ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
318 ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
319 ASSERT_FALSE(MI->getPCSections());
320 ASSERT_FALSE(MI->getMMRAMetadata());
322 MI->setPCSections(*MF, PCS);
323 ASSERT_TRUE(MI->memoperands().size() == 1);
324 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
325 ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
326 ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
327 ASSERT_TRUE(MI->getPCSections() == PCS);
328 ASSERT_FALSE(MI->getMMRAMetadata());
330 MI->setMMRAMetadata(*MF, MMRA);
331 ASSERT_TRUE(MI->memoperands().size() == 1);
332 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
333 ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
334 ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
335 ASSERT_TRUE(MI->getPCSections() == PCS);
336 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
338 // Check with nothing but MMRAs.
339 MachineInstr *MMRAMI = MF->CreateMachineInstr(MCID, DebugLoc());
340 ASSERT_FALSE(MMRAMI->getMMRAMetadata());
341 MMRAMI->setMMRAMetadata(*MF, MMRA);
342 ASSERT_TRUE(MMRAMI->getMMRAMetadata() == MMRA);
345 TEST(MachineInstrExtraInfo, ChangeExtraInfo) {
346 LLVMContext Ctx;
347 Module Mod("Module", Ctx);
348 auto MF = createMachineFunction(Ctx, Mod);
349 MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
351 auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
352 auto MAI = MCAsmInfo();
353 auto MC = createMCContext(&MAI);
354 auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
355 MachineMemOperand::MOLoad, 8, Align(8));
356 SmallVector<MachineMemOperand *, 2> MMOs;
357 MMOs.push_back(MMO);
358 MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
359 MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
360 MDNode *HAM = MDNode::getDistinct(Ctx, {});
361 MDNode *PCS = MDNode::getDistinct(Ctx, {});
363 MDNode *MMRA1 = MMRAMetadata::getTagMD(Ctx, "foo", "bar");
364 MDNode *MMRA2 = MMRAMetadata::getTagMD(Ctx, "bar", "bux");
366 MI->setMemRefs(*MF, MMOs);
367 MI->setPreInstrSymbol(*MF, Sym1);
368 MI->setPostInstrSymbol(*MF, Sym2);
369 MI->setHeapAllocMarker(*MF, HAM);
370 MI->setPCSections(*MF, PCS);
371 MI->setMMRAMetadata(*MF, MMRA1);
373 MMOs.push_back(MMO);
375 MI->setMemRefs(*MF, MMOs);
376 ASSERT_TRUE(MI->memoperands().size() == 2);
377 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
378 ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
379 ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
380 ASSERT_TRUE(MI->getPCSections() == PCS);
381 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA1);
383 MI->setPostInstrSymbol(*MF, Sym1);
384 ASSERT_TRUE(MI->memoperands().size() == 2);
385 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
386 ASSERT_TRUE(MI->getPostInstrSymbol() == Sym1);
387 ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
388 ASSERT_TRUE(MI->getPCSections() == PCS);
389 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA1);
391 MI->setMMRAMetadata(*MF, MMRA2);
392 ASSERT_TRUE(MI->memoperands().size() == 2);
393 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
394 ASSERT_TRUE(MI->getPostInstrSymbol() == Sym1);
395 ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
396 ASSERT_TRUE(MI->getPCSections() == PCS);
397 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA2);
400 TEST(MachineInstrExtraInfo, RemoveExtraInfo) {
401 LLVMContext Ctx;
402 Module Mod("Module", Ctx);
403 auto MF = createMachineFunction(Ctx, Mod);
404 MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
406 auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
407 auto MAI = MCAsmInfo();
408 auto MC = createMCContext(&MAI);
409 auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
410 MachineMemOperand::MOLoad, 8, Align(8));
411 SmallVector<MachineMemOperand *, 2> MMOs;
412 MMOs.push_back(MMO);
413 MMOs.push_back(MMO);
414 MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
415 MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
416 MDNode *HAM = MDNode::getDistinct(Ctx, {});
417 MDNode *PCS = MDNode::getDistinct(Ctx, {});
419 MDNode *MMRA = MDTuple::get(Ctx, {});
421 MI->setMemRefs(*MF, MMOs);
422 MI->setPreInstrSymbol(*MF, Sym1);
423 MI->setPostInstrSymbol(*MF, Sym2);
424 MI->setHeapAllocMarker(*MF, HAM);
425 MI->setPCSections(*MF, PCS);
426 MI->setMMRAMetadata(*MF, MMRA);
428 MI->setPostInstrSymbol(*MF, nullptr);
429 ASSERT_TRUE(MI->memoperands().size() == 2);
430 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
431 ASSERT_FALSE(MI->getPostInstrSymbol());
432 ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
433 ASSERT_TRUE(MI->getPCSections() == PCS);
434 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
436 MI->setHeapAllocMarker(*MF, nullptr);
437 ASSERT_TRUE(MI->memoperands().size() == 2);
438 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
439 ASSERT_FALSE(MI->getPostInstrSymbol());
440 ASSERT_FALSE(MI->getHeapAllocMarker());
441 ASSERT_TRUE(MI->getPCSections() == PCS);
442 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
444 MI->setPCSections(*MF, nullptr);
445 ASSERT_TRUE(MI->memoperands().size() == 2);
446 ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
447 ASSERT_FALSE(MI->getPostInstrSymbol());
448 ASSERT_FALSE(MI->getHeapAllocMarker());
449 ASSERT_FALSE(MI->getPCSections());
450 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
452 MI->setPreInstrSymbol(*MF, nullptr);
453 ASSERT_TRUE(MI->memoperands().size() == 2);
454 ASSERT_FALSE(MI->getPreInstrSymbol());
455 ASSERT_FALSE(MI->getPostInstrSymbol());
456 ASSERT_FALSE(MI->getHeapAllocMarker());
457 ASSERT_FALSE(MI->getPCSections());
458 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
460 MI->setMemRefs(*MF, {});
461 ASSERT_TRUE(MI->memoperands_empty());
462 ASSERT_FALSE(MI->getPreInstrSymbol());
463 ASSERT_FALSE(MI->getPostInstrSymbol());
464 ASSERT_FALSE(MI->getHeapAllocMarker());
465 ASSERT_FALSE(MI->getPCSections());
466 ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
468 MI->setMMRAMetadata(*MF, nullptr);
469 ASSERT_TRUE(MI->memoperands_empty());
470 ASSERT_FALSE(MI->getPreInstrSymbol());
471 ASSERT_FALSE(MI->getPostInstrSymbol());
472 ASSERT_FALSE(MI->getHeapAllocMarker());
473 ASSERT_FALSE(MI->getPCSections());
474 ASSERT_FALSE(MI->getMMRAMetadata());
477 TEST(MachineInstrDebugValue, AddDebugValueOperand) {
478 LLVMContext Ctx;
479 Module Mod("Module", Ctx);
480 auto MF = createMachineFunction(Ctx, Mod);
482 for (const unsigned short Opcode :
483 {TargetOpcode::DBG_VALUE, TargetOpcode::DBG_VALUE_LIST,
484 TargetOpcode::DBG_INSTR_REF, TargetOpcode::DBG_PHI,
485 TargetOpcode::DBG_LABEL}) {
486 const MCInstrDesc MCID = {
487 Opcode, 0, 0, 0, 0,
488 0, 0, 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
491 auto *MI = MF->CreateMachineInstr(MCID, DebugLoc());
492 MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false));
494 MI->addOperand(*MF, MachineOperand::CreateImm(0));
495 MI->getOperand(1).ChangeToRegister(0, false);
497 ASSERT_TRUE(MI->getOperand(0).isDebug());
498 ASSERT_TRUE(MI->getOperand(1).isDebug());
502 MATCHER_P(HasMIMetadata, MIMD, "") {
503 return arg->getDebugLoc() == MIMD.getDL() &&
504 arg->getPCSections() == MIMD.getPCSections();
507 TEST(MachineInstrBuilder, BuildMI) {
508 LLVMContext Ctx;
509 MDNode *PCS = MDNode::getDistinct(Ctx, {});
510 MDNode *DI = MDNode::getDistinct(Ctx, {});
511 DebugLoc DL(DI);
512 MIMetadata MIMD(DL, PCS);
513 EXPECT_EQ(MIMD.getDL(), DL);
514 EXPECT_EQ(MIMD.getPCSections(), PCS);
515 // Check common BuildMI() overloads propagate MIMetadata.
516 Module Mod("Module", Ctx);
517 auto MF = createMachineFunction(Ctx, Mod);
518 auto MBB = MF->CreateMachineBasicBlock();
519 MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
520 EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD));
521 EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD));
522 EXPECT_THAT(BuildMI(*MBB, MBB->end(), MIMD, MCID), HasMIMetadata(MIMD));
523 EXPECT_THAT(BuildMI(*MBB, MBB->end(), MIMD, MCID), HasMIMetadata(MIMD));
524 EXPECT_THAT(BuildMI(*MBB, MBB->instr_end(), MIMD, MCID), HasMIMetadata(MIMD));
525 EXPECT_THAT(BuildMI(*MBB, *MBB->begin(), MIMD, MCID), HasMIMetadata(MIMD));
526 EXPECT_THAT(BuildMI(*MBB, &*MBB->begin(), MIMD, MCID), HasMIMetadata(MIMD));
527 EXPECT_THAT(BuildMI(MBB, MIMD, MCID), HasMIMetadata(MIMD));
530 static_assert(std::is_trivially_copyable_v<MCOperand>, "trivially copyable");
532 TEST(MachineInstrTest, SpliceOperands) {
533 LLVMContext Ctx;
534 Module Mod("Module", Ctx);
535 std::unique_ptr<MachineFunction> MF = createMachineFunction(Ctx, Mod);
536 MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
537 MCInstrDesc MCID = {TargetOpcode::INLINEASM,
546 (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
548 MachineInstr *MI = MF->CreateMachineInstr(MCID, DebugLoc());
549 MBB->insert(MBB->begin(), MI);
550 MI->addOperand(MachineOperand::CreateImm(0));
551 MI->addOperand(MachineOperand::CreateImm(1));
552 MI->addOperand(MachineOperand::CreateImm(2));
553 MI->addOperand(MachineOperand::CreateImm(3));
554 MI->addOperand(MachineOperand::CreateImm(4));
556 MI->removeOperand(1);
557 EXPECT_EQ(MI->getOperand(1).getImm(), MachineOperand::CreateImm(2).getImm());
558 EXPECT_EQ(MI->getNumOperands(), 4U);
560 MachineOperand Ops[] = {
561 MachineOperand::CreateImm(42), MachineOperand::CreateImm(1024),
562 MachineOperand::CreateImm(2048), MachineOperand::CreateImm(4096),
563 MachineOperand::CreateImm(8192),
565 auto *It = MI->operands_begin();
566 ++It;
567 MI->insert(It, Ops);
569 EXPECT_EQ(MI->getNumOperands(), 9U);
570 EXPECT_EQ(MI->getOperand(0).getImm(), MachineOperand::CreateImm(0).getImm());
571 EXPECT_EQ(MI->getOperand(1).getImm(), MachineOperand::CreateImm(42).getImm());
572 EXPECT_EQ(MI->getOperand(2).getImm(),
573 MachineOperand::CreateImm(1024).getImm());
574 EXPECT_EQ(MI->getOperand(3).getImm(),
575 MachineOperand::CreateImm(2048).getImm());
576 EXPECT_EQ(MI->getOperand(4).getImm(),
577 MachineOperand::CreateImm(4096).getImm());
578 EXPECT_EQ(MI->getOperand(5).getImm(),
579 MachineOperand::CreateImm(8192).getImm());
580 EXPECT_EQ(MI->getOperand(6).getImm(), MachineOperand::CreateImm(2).getImm());
581 EXPECT_EQ(MI->getOperand(7).getImm(), MachineOperand::CreateImm(3).getImm());
582 EXPECT_EQ(MI->getOperand(8).getImm(), MachineOperand::CreateImm(4).getImm());
584 // test tied operands
585 MCRegisterClass MRC{
586 0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true};
587 TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0};
588 // MachineRegisterInfo will be very upset if these registers aren't
589 // allocatable.
590 assert(RC.isAllocatable() && "unusable TargetRegisterClass");
591 MachineRegisterInfo &MRI = MF->getRegInfo();
592 Register A = MRI.createVirtualRegister(&RC);
593 Register B = MRI.createVirtualRegister(&RC);
594 MI->getOperand(0).ChangeToRegister(A, /*isDef=*/true);
595 MI->getOperand(1).ChangeToRegister(B, /*isDef=*/false);
596 MI->tieOperands(0, 1);
597 EXPECT_TRUE(MI->getOperand(0).isTied());
598 EXPECT_TRUE(MI->getOperand(1).isTied());
599 EXPECT_EQ(MI->findTiedOperandIdx(0), 1U);
600 EXPECT_EQ(MI->findTiedOperandIdx(1), 0U);
601 MI->insert(&MI->getOperand(1), {MachineOperand::CreateImm(7)});
602 EXPECT_TRUE(MI->getOperand(0).isTied());
603 EXPECT_TRUE(MI->getOperand(1).isImm());
604 EXPECT_TRUE(MI->getOperand(2).isTied());
605 EXPECT_EQ(MI->findTiedOperandIdx(0), 2U);
606 EXPECT_EQ(MI->findTiedOperandIdx(2), 0U);
607 EXPECT_EQ(MI->getOperand(0).getReg(), A);
608 EXPECT_EQ(MI->getOperand(2).getReg(), B);
610 // bad inputs
611 EXPECT_EQ(MI->getNumOperands(), 10U);
612 MI->insert(MI->operands_begin(), {});
613 EXPECT_EQ(MI->getNumOperands(), 10U);
616 } // end namespace