xref: /llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp (revision 74deadf19650f6f3b6392ba09caa20dd38ae41e0)
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 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/CodeGen/MachineInstr.h"
10 #include "llvm/CodeGen/MachineBasicBlock.h"
11 #include "llvm/CodeGen/MachineFunction.h"
12 #include "llvm/CodeGen/MachineInstrBuilder.h"
13 #include "llvm/CodeGen/MachineMemOperand.h"
14 #include "llvm/CodeGen/MachineModuleInfo.h"
15 #include "llvm/CodeGen/TargetFrameLowering.h"
16 #include "llvm/CodeGen/TargetInstrInfo.h"
17 #include "llvm/CodeGen/TargetLowering.h"
18 #include "llvm/CodeGen/TargetSubtargetInfo.h"
19 #include "llvm/IR/DebugInfoMetadata.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/MemoryModelRelaxationAnnotations.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/IR/ModuleSlotTracker.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/TargetRegistry.h"
27 #include "llvm/Support/TargetSelect.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "llvm/Target/TargetOptions.h"
30 #include "llvm/TargetParser/Triple.h"
31 #include "gmock/gmock.h"
32 #include "gtest/gtest.h"
33 
34 using namespace llvm;
35 
36 namespace {
37 // Include helper functions to ease the manipulation of MachineFunctions.
38 #include "MFCommon.inc"
39 
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);
45 }
46 
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);
53 
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}}};
63 
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;
68 
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));
72 
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));
76 
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));
81 
82   ASSERT_TRUE(MI1->isIdenticalTo(*MI2, MachineInstr::IgnoreVRegDefs));
83   ASSERT_TRUE(MI2->isIdenticalTo(*MI1, MachineInstr::IgnoreVRegDefs));
84 
85   // Create two MIs with different virtual reg defs, and a def or use of a
86   // sentinel register.
87   unsigned SentinelReg = 0;
88 
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));
92 
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));
96 
97   // Check that they are never identical.
98   ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::CheckDefs));
99   ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::CheckDefs));
100 
101   ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::IgnoreVRegDefs));
102   ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::IgnoreVRegDefs));
103 }
104 
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);
110 
111   ASSERT_EQ(IsEqual1, IsEqual2);
112 
113   auto Hash1 = MachineInstrExpressionTrait::getHashValue(MI1);
114   auto Hash2 = MachineInstrExpressionTrait::getHashValue(MI2);
115 
116   ASSERT_EQ(IsEqual1, Hash1 == Hash2);
117 }
118 
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);
125 
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}}};
135 
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;
144 
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));
150 
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));
156 
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));
162 
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));
168 
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));
174 
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));
180 
181   checkHashAndIsEqualMatch(VD1VU, VD2VU);
182   checkHashAndIsEqualMatch(VD1VU, VD1SU);
183   checkHashAndIsEqualMatch(VD1VU, VD1SD);
184   checkHashAndIsEqualMatch(VD1VU, VD2PU);
185   checkHashAndIsEqualMatch(VD1VU, VD2PD);
186 
187   checkHashAndIsEqualMatch(VD2VU, VD1SU);
188   checkHashAndIsEqualMatch(VD2VU, VD1SD);
189   checkHashAndIsEqualMatch(VD2VU, VD2PU);
190   checkHashAndIsEqualMatch(VD2VU, VD2PD);
191 
192   checkHashAndIsEqualMatch(VD1SU, VD1SD);
193   checkHashAndIsEqualMatch(VD1SU, VD2PU);
194   checkHashAndIsEqualMatch(VD1SU, VD2PD);
195 
196   checkHashAndIsEqualMatch(VD1SD, VD2PU);
197   checkHashAndIsEqualMatch(VD1SD, VD2PD);
198 
199   checkHashAndIsEqualMatch(VD2PU, VD2PD);
200 }
201 
202 TEST(MachineInstrPrintingTest, DebugLocPrinting) {
203   LLVMContext Ctx;
204   Module Mod("Module", Ctx);
205   auto MF = createMachineFunction(Ctx, Mod);
206 
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}};
212 
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));
221 
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(
227       StringRef(OS.str()).starts_with("$noreg = UNKNOWN debug-location "));
228   ASSERT_TRUE(StringRef(OS.str()).ends_with("filename:1:5"));
229 }
230 
231 TEST(MachineInstrSpan, DistanceBegin) {
232   LLVMContext Ctx;
233   Module Mod("Module", Ctx);
234   auto MF = createMachineFunction(Ctx, Mod);
235   auto MBB = MF->CreateMachineBasicBlock();
236 
237   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
238 
239   auto MII = MBB->begin();
240   MachineInstrSpan MIS(MII, MBB);
241   ASSERT_TRUE(MIS.empty());
242 
243   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
244   MBB->insert(MII, MI);
245   ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
246 }
247 
248 TEST(MachineInstrSpan, DistanceEnd) {
249   LLVMContext Ctx;
250   Module Mod("Module", Ctx);
251   auto MF = createMachineFunction(Ctx, Mod);
252   auto MBB = MF->CreateMachineBasicBlock();
253 
254   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
255 
256   auto MII = MBB->end();
257   MachineInstrSpan MIS(MII, MBB);
258   ASSERT_TRUE(MIS.empty());
259 
260   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
261   MBB->insert(MII, MI);
262   ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
263 }
264 
265 TEST(MachineInstrExtraInfo, AddExtraInfo) {
266   LLVMContext Ctx;
267   Module Mod("Module", Ctx);
268   auto MF = createMachineFunction(Ctx, Mod);
269   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
270 
271   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
272   auto MAI = MCAsmInfo();
273   auto MC = createMCContext(&MAI);
274   auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
275                                       MachineMemOperand::MOLoad, 8, Align(8));
276   SmallVector<MachineMemOperand *, 2> MMOs;
277   MMOs.push_back(MMO);
278   MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
279   MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
280   MDNode *HAM = MDNode::getDistinct(Ctx, std::nullopt);
281   MDNode *PCS = MDNode::getDistinct(Ctx, std::nullopt);
282   MDNode *MMRA = MMRAMetadata::getTagMD(Ctx, "foo", "bar");
283 
284   ASSERT_TRUE(MI->memoperands_empty());
285   ASSERT_FALSE(MI->getPreInstrSymbol());
286   ASSERT_FALSE(MI->getPostInstrSymbol());
287   ASSERT_FALSE(MI->getHeapAllocMarker());
288   ASSERT_FALSE(MI->getPCSections());
289   ASSERT_FALSE(MI->getMMRAMetadata());
290 
291   MI->setMemRefs(*MF, MMOs);
292   ASSERT_TRUE(MI->memoperands().size() == 1);
293   ASSERT_FALSE(MI->getPreInstrSymbol());
294   ASSERT_FALSE(MI->getPostInstrSymbol());
295   ASSERT_FALSE(MI->getHeapAllocMarker());
296   ASSERT_FALSE(MI->getPCSections());
297   ASSERT_FALSE(MI->getMMRAMetadata());
298 
299   MI->setPreInstrSymbol(*MF, Sym1);
300   ASSERT_TRUE(MI->memoperands().size() == 1);
301   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
302   ASSERT_FALSE(MI->getPostInstrSymbol());
303   ASSERT_FALSE(MI->getHeapAllocMarker());
304   ASSERT_FALSE(MI->getPCSections());
305   ASSERT_FALSE(MI->getMMRAMetadata());
306 
307   MI->setPostInstrSymbol(*MF, Sym2);
308   ASSERT_TRUE(MI->memoperands().size() == 1);
309   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
310   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
311   ASSERT_FALSE(MI->getHeapAllocMarker());
312   ASSERT_FALSE(MI->getPCSections());
313   ASSERT_FALSE(MI->getMMRAMetadata());
314 
315   MI->setHeapAllocMarker(*MF, HAM);
316   ASSERT_TRUE(MI->memoperands().size() == 1);
317   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
318   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
319   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
320   ASSERT_FALSE(MI->getPCSections());
321   ASSERT_FALSE(MI->getMMRAMetadata());
322 
323   MI->setPCSections(*MF, PCS);
324   ASSERT_TRUE(MI->memoperands().size() == 1);
325   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
326   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
327   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
328   ASSERT_TRUE(MI->getPCSections() == PCS);
329   ASSERT_FALSE(MI->getMMRAMetadata());
330 
331   MI->setMMRAMetadata(*MF, MMRA);
332   ASSERT_TRUE(MI->memoperands().size() == 1);
333   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
334   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
335   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
336   ASSERT_TRUE(MI->getPCSections() == PCS);
337   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
338 
339   // Check with nothing but MMRAs.
340   MachineInstr *MMRAMI = MF->CreateMachineInstr(MCID, DebugLoc());
341   ASSERT_FALSE(MMRAMI->getMMRAMetadata());
342   MMRAMI->setMMRAMetadata(*MF, MMRA);
343   ASSERT_TRUE(MMRAMI->getMMRAMetadata() == MMRA);
344 }
345 
346 TEST(MachineInstrExtraInfo, ChangeExtraInfo) {
347   LLVMContext Ctx;
348   Module Mod("Module", Ctx);
349   auto MF = createMachineFunction(Ctx, Mod);
350   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
351 
352   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
353   auto MAI = MCAsmInfo();
354   auto MC = createMCContext(&MAI);
355   auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
356                                       MachineMemOperand::MOLoad, 8, Align(8));
357   SmallVector<MachineMemOperand *, 2> MMOs;
358   MMOs.push_back(MMO);
359   MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
360   MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
361   MDNode *HAM = MDNode::getDistinct(Ctx, std::nullopt);
362   MDNode *PCS = MDNode::getDistinct(Ctx, std::nullopt);
363 
364   MDNode *MMRA1 = MMRAMetadata::getTagMD(Ctx, "foo", "bar");
365   MDNode *MMRA2 = MMRAMetadata::getTagMD(Ctx, "bar", "bux");
366 
367   MI->setMemRefs(*MF, MMOs);
368   MI->setPreInstrSymbol(*MF, Sym1);
369   MI->setPostInstrSymbol(*MF, Sym2);
370   MI->setHeapAllocMarker(*MF, HAM);
371   MI->setPCSections(*MF, PCS);
372   MI->setMMRAMetadata(*MF, MMRA1);
373 
374   MMOs.push_back(MMO);
375 
376   MI->setMemRefs(*MF, MMOs);
377   ASSERT_TRUE(MI->memoperands().size() == 2);
378   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
379   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
380   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
381   ASSERT_TRUE(MI->getPCSections() == PCS);
382   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA1);
383 
384   MI->setPostInstrSymbol(*MF, Sym1);
385   ASSERT_TRUE(MI->memoperands().size() == 2);
386   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
387   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym1);
388   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
389   ASSERT_TRUE(MI->getPCSections() == PCS);
390   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA1);
391 
392   MI->setMMRAMetadata(*MF, MMRA2);
393   ASSERT_TRUE(MI->memoperands().size() == 2);
394   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
395   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym1);
396   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
397   ASSERT_TRUE(MI->getPCSections() == PCS);
398   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA2);
399 }
400 
401 TEST(MachineInstrExtraInfo, RemoveExtraInfo) {
402   LLVMContext Ctx;
403   Module Mod("Module", Ctx);
404   auto MF = createMachineFunction(Ctx, Mod);
405   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
406 
407   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
408   auto MAI = MCAsmInfo();
409   auto MC = createMCContext(&MAI);
410   auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
411                                       MachineMemOperand::MOLoad, 8, Align(8));
412   SmallVector<MachineMemOperand *, 2> MMOs;
413   MMOs.push_back(MMO);
414   MMOs.push_back(MMO);
415   MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
416   MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
417   MDNode *HAM = MDNode::getDistinct(Ctx, std::nullopt);
418   MDNode *PCS = MDNode::getDistinct(Ctx, std::nullopt);
419 
420   MDNode *MMRA = MDTuple::get(Ctx, {});
421 
422   MI->setMemRefs(*MF, MMOs);
423   MI->setPreInstrSymbol(*MF, Sym1);
424   MI->setPostInstrSymbol(*MF, Sym2);
425   MI->setHeapAllocMarker(*MF, HAM);
426   MI->setPCSections(*MF, PCS);
427   MI->setMMRAMetadata(*MF, MMRA);
428 
429   MI->setPostInstrSymbol(*MF, nullptr);
430   ASSERT_TRUE(MI->memoperands().size() == 2);
431   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
432   ASSERT_FALSE(MI->getPostInstrSymbol());
433   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
434   ASSERT_TRUE(MI->getPCSections() == PCS);
435   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
436 
437   MI->setHeapAllocMarker(*MF, nullptr);
438   ASSERT_TRUE(MI->memoperands().size() == 2);
439   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
440   ASSERT_FALSE(MI->getPostInstrSymbol());
441   ASSERT_FALSE(MI->getHeapAllocMarker());
442   ASSERT_TRUE(MI->getPCSections() == PCS);
443   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
444 
445   MI->setPCSections(*MF, nullptr);
446   ASSERT_TRUE(MI->memoperands().size() == 2);
447   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
448   ASSERT_FALSE(MI->getPostInstrSymbol());
449   ASSERT_FALSE(MI->getHeapAllocMarker());
450   ASSERT_FALSE(MI->getPCSections());
451   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
452 
453   MI->setPreInstrSymbol(*MF, nullptr);
454   ASSERT_TRUE(MI->memoperands().size() == 2);
455   ASSERT_FALSE(MI->getPreInstrSymbol());
456   ASSERT_FALSE(MI->getPostInstrSymbol());
457   ASSERT_FALSE(MI->getHeapAllocMarker());
458   ASSERT_FALSE(MI->getPCSections());
459   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
460 
461   MI->setMemRefs(*MF, {});
462   ASSERT_TRUE(MI->memoperands_empty());
463   ASSERT_FALSE(MI->getPreInstrSymbol());
464   ASSERT_FALSE(MI->getPostInstrSymbol());
465   ASSERT_FALSE(MI->getHeapAllocMarker());
466   ASSERT_FALSE(MI->getPCSections());
467   ASSERT_TRUE(MI->getMMRAMetadata() == MMRA);
468 
469   MI->setMMRAMetadata(*MF, nullptr);
470   ASSERT_TRUE(MI->memoperands_empty());
471   ASSERT_FALSE(MI->getPreInstrSymbol());
472   ASSERT_FALSE(MI->getPostInstrSymbol());
473   ASSERT_FALSE(MI->getHeapAllocMarker());
474   ASSERT_FALSE(MI->getPCSections());
475   ASSERT_FALSE(MI->getMMRAMetadata());
476 }
477 
478 TEST(MachineInstrDebugValue, AddDebugValueOperand) {
479   LLVMContext Ctx;
480   Module Mod("Module", Ctx);
481   auto MF = createMachineFunction(Ctx, Mod);
482 
483   for (const unsigned short Opcode :
484        {TargetOpcode::DBG_VALUE, TargetOpcode::DBG_VALUE_LIST,
485         TargetOpcode::DBG_INSTR_REF, TargetOpcode::DBG_PHI,
486         TargetOpcode::DBG_LABEL}) {
487     const MCInstrDesc MCID = {
488         Opcode, 0, 0, 0, 0,
489         0,      0, 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
490         0};
491 
492     auto *MI = MF->CreateMachineInstr(MCID, DebugLoc());
493     MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false));
494 
495     MI->addOperand(*MF, MachineOperand::CreateImm(0));
496     MI->getOperand(1).ChangeToRegister(0, false);
497 
498     ASSERT_TRUE(MI->getOperand(0).isDebug());
499     ASSERT_TRUE(MI->getOperand(1).isDebug());
500   }
501 }
502 
503 MATCHER_P(HasMIMetadata, MIMD, "") {
504   return arg->getDebugLoc() == MIMD.getDL() &&
505          arg->getPCSections() == MIMD.getPCSections();
506 }
507 
508 TEST(MachineInstrBuilder, BuildMI) {
509   LLVMContext Ctx;
510   MDNode *PCS = MDNode::getDistinct(Ctx, std::nullopt);
511   MDNode *DI = MDNode::getDistinct(Ctx, std::nullopt);
512   DebugLoc DL(DI);
513   MIMetadata MIMD(DL, PCS);
514   EXPECT_EQ(MIMD.getDL(), DL);
515   EXPECT_EQ(MIMD.getPCSections(), PCS);
516   // Check common BuildMI() overloads propagate MIMetadata.
517   Module Mod("Module", Ctx);
518   auto MF = createMachineFunction(Ctx, Mod);
519   auto MBB = MF->CreateMachineBasicBlock();
520   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
521   EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD));
522   EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD));
523   EXPECT_THAT(BuildMI(*MBB, MBB->end(), MIMD, MCID), HasMIMetadata(MIMD));
524   EXPECT_THAT(BuildMI(*MBB, MBB->end(), MIMD, MCID), HasMIMetadata(MIMD));
525   EXPECT_THAT(BuildMI(*MBB, MBB->instr_end(), MIMD, MCID), HasMIMetadata(MIMD));
526   EXPECT_THAT(BuildMI(*MBB, *MBB->begin(), MIMD, MCID), HasMIMetadata(MIMD));
527   EXPECT_THAT(BuildMI(*MBB, &*MBB->begin(), MIMD, MCID), HasMIMetadata(MIMD));
528   EXPECT_THAT(BuildMI(MBB, MIMD, MCID), HasMIMetadata(MIMD));
529 }
530 
531 static_assert(std::is_trivially_copyable_v<MCOperand>, "trivially copyable");
532 
533 TEST(MachineInstrTest, SpliceOperands) {
534   LLVMContext Ctx;
535   Module Mod("Module", Ctx);
536   std::unique_ptr<MachineFunction> MF = createMachineFunction(Ctx, Mod);
537   MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
538   MCInstrDesc MCID = {TargetOpcode::INLINEASM,
539                       0,
540                       0,
541                       0,
542                       0,
543                       0,
544                       0,
545                       0,
546                       0,
547                       (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
548                       0};
549   MachineInstr *MI = MF->CreateMachineInstr(MCID, DebugLoc());
550   MBB->insert(MBB->begin(), MI);
551   MI->addOperand(MachineOperand::CreateImm(0));
552   MI->addOperand(MachineOperand::CreateImm(1));
553   MI->addOperand(MachineOperand::CreateImm(2));
554   MI->addOperand(MachineOperand::CreateImm(3));
555   MI->addOperand(MachineOperand::CreateImm(4));
556 
557   MI->removeOperand(1);
558   EXPECT_EQ(MI->getOperand(1).getImm(), MachineOperand::CreateImm(2).getImm());
559   EXPECT_EQ(MI->getNumOperands(), 4U);
560 
561   MachineOperand Ops[] = {
562       MachineOperand::CreateImm(42),   MachineOperand::CreateImm(1024),
563       MachineOperand::CreateImm(2048), MachineOperand::CreateImm(4096),
564       MachineOperand::CreateImm(8192),
565   };
566   auto *It = MI->operands_begin();
567   ++It;
568   MI->insert(It, Ops);
569 
570   EXPECT_EQ(MI->getNumOperands(), 9U);
571   EXPECT_EQ(MI->getOperand(0).getImm(), MachineOperand::CreateImm(0).getImm());
572   EXPECT_EQ(MI->getOperand(1).getImm(), MachineOperand::CreateImm(42).getImm());
573   EXPECT_EQ(MI->getOperand(2).getImm(),
574             MachineOperand::CreateImm(1024).getImm());
575   EXPECT_EQ(MI->getOperand(3).getImm(),
576             MachineOperand::CreateImm(2048).getImm());
577   EXPECT_EQ(MI->getOperand(4).getImm(),
578             MachineOperand::CreateImm(4096).getImm());
579   EXPECT_EQ(MI->getOperand(5).getImm(),
580             MachineOperand::CreateImm(8192).getImm());
581   EXPECT_EQ(MI->getOperand(6).getImm(), MachineOperand::CreateImm(2).getImm());
582   EXPECT_EQ(MI->getOperand(7).getImm(), MachineOperand::CreateImm(3).getImm());
583   EXPECT_EQ(MI->getOperand(8).getImm(), MachineOperand::CreateImm(4).getImm());
584 
585   // test tied operands
586   MCRegisterClass MRC{
587       0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true};
588   TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0};
589   // MachineRegisterInfo will be very upset if these registers aren't
590   // allocatable.
591   assert(RC.isAllocatable() && "unusable TargetRegisterClass");
592   MachineRegisterInfo &MRI = MF->getRegInfo();
593   Register A = MRI.createVirtualRegister(&RC);
594   Register B = MRI.createVirtualRegister(&RC);
595   MI->getOperand(0).ChangeToRegister(A, /*isDef=*/true);
596   MI->getOperand(1).ChangeToRegister(B, /*isDef=*/false);
597   MI->tieOperands(0, 1);
598   EXPECT_TRUE(MI->getOperand(0).isTied());
599   EXPECT_TRUE(MI->getOperand(1).isTied());
600   EXPECT_EQ(MI->findTiedOperandIdx(0), 1U);
601   EXPECT_EQ(MI->findTiedOperandIdx(1), 0U);
602   MI->insert(&MI->getOperand(1), {MachineOperand::CreateImm(7)});
603   EXPECT_TRUE(MI->getOperand(0).isTied());
604   EXPECT_TRUE(MI->getOperand(1).isImm());
605   EXPECT_TRUE(MI->getOperand(2).isTied());
606   EXPECT_EQ(MI->findTiedOperandIdx(0), 2U);
607   EXPECT_EQ(MI->findTiedOperandIdx(2), 0U);
608   EXPECT_EQ(MI->getOperand(0).getReg(), A);
609   EXPECT_EQ(MI->getOperand(2).getReg(), B);
610 
611   // bad inputs
612   EXPECT_EQ(MI->getNumOperands(), 10U);
613   MI->insert(MI->operands_begin(), {});
614   EXPECT_EQ(MI->getNumOperands(), 10U);
615 }
616 
617 } // end namespace
618