xref: /llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp (revision 6f3f08abdc9faac1fe07018bf72d532443f2ec05)
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/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"
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(StringRef(str).starts_with("$noreg = UNKNOWN debug-location "));
227   ASSERT_TRUE(StringRef(str).ends_with("filename:1:5"));
228 }
229 
230 TEST(MachineInstrSpan, DistanceBegin) {
231   LLVMContext Ctx;
232   Module Mod("Module", Ctx);
233   auto MF = createMachineFunction(Ctx, Mod);
234   auto MBB = MF->CreateMachineBasicBlock();
235 
236   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
237 
238   auto MII = MBB->begin();
239   MachineInstrSpan MIS(MII, MBB);
240   ASSERT_TRUE(MIS.empty());
241 
242   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
243   MBB->insert(MII, MI);
244   ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
245 }
246 
247 TEST(MachineInstrSpan, DistanceEnd) {
248   LLVMContext Ctx;
249   Module Mod("Module", Ctx);
250   auto MF = createMachineFunction(Ctx, Mod);
251   auto MBB = MF->CreateMachineBasicBlock();
252 
253   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
254 
255   auto MII = MBB->end();
256   MachineInstrSpan MIS(MII, MBB);
257   ASSERT_TRUE(MIS.empty());
258 
259   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
260   MBB->insert(MII, MI);
261   ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
262 }
263 
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};
269 
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");
282 
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());
289 
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());
297 
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());
305 
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());
313 
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());
321 
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());
329 
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);
337 
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);
343 }
344 
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};
350 
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, {});
362 
363   MDNode *MMRA1 = MMRAMetadata::getTagMD(Ctx, "foo", "bar");
364   MDNode *MMRA2 = MMRAMetadata::getTagMD(Ctx, "bar", "bux");
365 
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);
372 
373   MMOs.push_back(MMO);
374 
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);
382 
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);
390 
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);
398 }
399 
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};
405 
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, {});
418 
419   MDNode *MMRA = MDTuple::get(Ctx, {});
420 
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);
427 
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);
435 
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);
443 
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);
451 
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);
459 
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);
467 
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());
475 }
476 
477 TEST(MachineInstrDebugValue, AddDebugValueOperand) {
478   LLVMContext Ctx;
479   Module Mod("Module", Ctx);
480   auto MF = createMachineFunction(Ctx, Mod);
481 
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),
489         0};
490 
491     auto *MI = MF->CreateMachineInstr(MCID, DebugLoc());
492     MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false));
493 
494     MI->addOperand(*MF, MachineOperand::CreateImm(0));
495     MI->getOperand(1).ChangeToRegister(0, false);
496 
497     ASSERT_TRUE(MI->getOperand(0).isDebug());
498     ASSERT_TRUE(MI->getOperand(1).isDebug());
499   }
500 }
501 
502 MATCHER_P(HasMIMetadata, MIMD, "") {
503   return arg->getDebugLoc() == MIMD.getDL() &&
504          arg->getPCSections() == MIMD.getPCSections();
505 }
506 
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));
528 }
529 
530 static_assert(std::is_trivially_copyable_v<MCOperand>, "trivially copyable");
531 
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,
538                       0,
539                       0,
540                       0,
541                       0,
542                       0,
543                       0,
544                       0,
545                       0,
546                       (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
547                       0};
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));
555 
556   MI->removeOperand(1);
557   EXPECT_EQ(MI->getOperand(1).getImm(), MachineOperand::CreateImm(2).getImm());
558   EXPECT_EQ(MI->getNumOperands(), 4U);
559 
560   MachineOperand Ops[] = {
561       MachineOperand::CreateImm(42),   MachineOperand::CreateImm(1024),
562       MachineOperand::CreateImm(2048), MachineOperand::CreateImm(4096),
563       MachineOperand::CreateImm(8192),
564   };
565   auto *It = MI->operands_begin();
566   ++It;
567   MI->insert(It, Ops);
568 
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());
583 
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, 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);
609 
610   // bad inputs
611   EXPECT_EQ(MI->getNumOperands(), 10U);
612   MI->insert(MI->operands_begin(), {});
613   EXPECT_EQ(MI->getNumOperands(), 10U);
614 }
615 
616 } // end namespace
617