xref: /llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp (revision 5c9d82de6b72cc0c037daecce452c450870f0034)
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/ModuleSlotTracker.h"
22 #include "llvm/MC/MCAsmInfo.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/MC/TargetRegistry.h"
25 #include "llvm/Support/TargetSelect.h"
26 #include "llvm/Target/TargetMachine.h"
27 #include "llvm/Target/TargetOptions.h"
28 #include "llvm/TargetParser/Triple.h"
29 #include "gmock/gmock.h"
30 #include "gtest/gtest.h"
31 
32 using namespace llvm;
33 
34 namespace {
35 // Include helper functions to ease the manipulation of MachineFunctions.
36 #include "MFCommon.inc"
37 
38 std::unique_ptr<MCContext> createMCContext(MCAsmInfo *AsmInfo) {
39   Triple TheTriple(/*ArchStr=*/"", /*VendorStr=*/"", /*OSStr=*/"",
40                    /*EnvironmentStr=*/"elf");
41   return std::make_unique<MCContext>(TheTriple, AsmInfo, nullptr, nullptr,
42                                      nullptr, nullptr, false);
43 }
44 
45 // This test makes sure that MachineInstr::isIdenticalTo handles Defs correctly
46 // for various combinations of IgnoreDefs, and also that it is symmetrical.
47 TEST(IsIdenticalToTest, DifferentDefs) {
48   LLVMContext Ctx;
49   Module Mod("Module", Ctx);
50   auto MF = createMachineFunction(Ctx, Mod);
51 
52   unsigned short NumOps = 2;
53   unsigned char NumDefs = 1;
54   struct {
55     MCInstrDesc MCID;
56     MCOperandInfo OpInfo[2];
57   } Table = {
58       {0, NumOps, NumDefs, 0, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, 0},
59       {{0, 0, MCOI::OPERAND_REGISTER, 0},
60        {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}};
61 
62   // Create two MIs with different virtual reg defs and the same uses.
63   unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does.
64   unsigned VirtualDef2 = -43;
65   unsigned VirtualUse = -44;
66 
67   auto MI1 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
68   MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
69   MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));
70 
71   auto MI2 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
72   MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
73   MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));
74 
75   // Check that they are identical when we ignore virtual register defs, but not
76   // when we check defs.
77   ASSERT_FALSE(MI1->isIdenticalTo(*MI2, MachineInstr::CheckDefs));
78   ASSERT_FALSE(MI2->isIdenticalTo(*MI1, MachineInstr::CheckDefs));
79 
80   ASSERT_TRUE(MI1->isIdenticalTo(*MI2, MachineInstr::IgnoreVRegDefs));
81   ASSERT_TRUE(MI2->isIdenticalTo(*MI1, MachineInstr::IgnoreVRegDefs));
82 
83   // Create two MIs with different virtual reg defs, and a def or use of a
84   // sentinel register.
85   unsigned SentinelReg = 0;
86 
87   auto MI3 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
88   MI3->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
89   MI3->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));
90 
91   auto MI4 = MF->CreateMachineInstr(Table.MCID, DebugLoc());
92   MI4->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
93   MI4->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));
94 
95   // Check that they are never identical.
96   ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::CheckDefs));
97   ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::CheckDefs));
98 
99   ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::IgnoreVRegDefs));
100   ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::IgnoreVRegDefs));
101 }
102 
103 // Check that MachineInstrExpressionTrait::isEqual is symmetric and in sync with
104 // MachineInstrExpressionTrait::getHashValue
105 void checkHashAndIsEqualMatch(MachineInstr *MI1, MachineInstr *MI2) {
106   bool IsEqual1 = MachineInstrExpressionTrait::isEqual(MI1, MI2);
107   bool IsEqual2 = MachineInstrExpressionTrait::isEqual(MI2, MI1);
108 
109   ASSERT_EQ(IsEqual1, IsEqual2);
110 
111   auto Hash1 = MachineInstrExpressionTrait::getHashValue(MI1);
112   auto Hash2 = MachineInstrExpressionTrait::getHashValue(MI2);
113 
114   ASSERT_EQ(IsEqual1, Hash1 == Hash2);
115 }
116 
117 // This test makes sure that MachineInstrExpressionTraits::isEqual is in sync
118 // with MachineInstrExpressionTraits::getHashValue.
119 TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {
120   LLVMContext Ctx;
121   Module Mod("Module", Ctx);
122   auto MF = createMachineFunction(Ctx, Mod);
123 
124   unsigned short NumOps = 2;
125   unsigned char NumDefs = 1;
126   struct {
127     MCInstrDesc MCID;
128     MCOperandInfo OpInfo[2];
129   } Table = {
130       {0, NumOps, NumDefs, 0, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, 0},
131       {{0, 0, MCOI::OPERAND_REGISTER, 0},
132        {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}};
133 
134   // Define a series of instructions with different kinds of operands and make
135   // sure that the hash function is consistent with isEqual for various
136   // combinations of them.
137   unsigned VirtualDef1 = -42;
138   unsigned VirtualDef2 = -43;
139   unsigned VirtualReg = -44;
140   unsigned SentinelReg = 0;
141   unsigned PhysicalReg = 45;
142 
143   auto VD1VU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
144   VD1VU->addOperand(*MF,
145                     MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
146   VD1VU->addOperand(*MF,
147                     MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));
148 
149   auto VD2VU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
150   VD2VU->addOperand(*MF,
151                     MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
152   VD2VU->addOperand(*MF,
153                     MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));
154 
155   auto VD1SU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
156   VD1SU->addOperand(*MF,
157                     MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
158   VD1SU->addOperand(*MF,
159                     MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));
160 
161   auto VD1SD = MF->CreateMachineInstr(Table.MCID, DebugLoc());
162   VD1SD->addOperand(*MF,
163                     MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
164   VD1SD->addOperand(*MF,
165                     MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));
166 
167   auto VD2PU = MF->CreateMachineInstr(Table.MCID, DebugLoc());
168   VD2PU->addOperand(*MF,
169                     MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
170   VD2PU->addOperand(*MF,
171                     MachineOperand::CreateReg(PhysicalReg, /*isDef*/ false));
172 
173   auto VD2PD = MF->CreateMachineInstr(Table.MCID, DebugLoc());
174   VD2PD->addOperand(*MF,
175                     MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
176   VD2PD->addOperand(*MF,
177                     MachineOperand::CreateReg(PhysicalReg, /*isDef*/ true));
178 
179   checkHashAndIsEqualMatch(VD1VU, VD2VU);
180   checkHashAndIsEqualMatch(VD1VU, VD1SU);
181   checkHashAndIsEqualMatch(VD1VU, VD1SD);
182   checkHashAndIsEqualMatch(VD1VU, VD2PU);
183   checkHashAndIsEqualMatch(VD1VU, VD2PD);
184 
185   checkHashAndIsEqualMatch(VD2VU, VD1SU);
186   checkHashAndIsEqualMatch(VD2VU, VD1SD);
187   checkHashAndIsEqualMatch(VD2VU, VD2PU);
188   checkHashAndIsEqualMatch(VD2VU, VD2PD);
189 
190   checkHashAndIsEqualMatch(VD1SU, VD1SD);
191   checkHashAndIsEqualMatch(VD1SU, VD2PU);
192   checkHashAndIsEqualMatch(VD1SU, VD2PD);
193 
194   checkHashAndIsEqualMatch(VD1SD, VD2PU);
195   checkHashAndIsEqualMatch(VD1SD, VD2PD);
196 
197   checkHashAndIsEqualMatch(VD2PU, VD2PD);
198 }
199 
200 TEST(MachineInstrPrintingTest, DebugLocPrinting) {
201   LLVMContext Ctx;
202   Module Mod("Module", Ctx);
203   auto MF = createMachineFunction(Ctx, Mod);
204 
205   struct {
206     MCInstrDesc MCID;
207     MCOperandInfo OpInfo;
208   } Table = {{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
209              {0, 0, MCOI::OPERAND_REGISTER, 0}};
210 
211   DIFile *DIF = DIFile::getDistinct(Ctx, "filename", "");
212   DISubprogram *DIS = DISubprogram::getDistinct(
213       Ctx, nullptr, "", "", DIF, 0, nullptr, 0, nullptr, 0, 0, DINode::FlagZero,
214       DISubprogram::SPFlagZero, nullptr);
215   DILocation *DIL = DILocation::get(Ctx, 1, 5, DIS);
216   DebugLoc DL(DIL);
217   MachineInstr *MI = MF->CreateMachineInstr(Table.MCID, DL);
218   MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ true));
219 
220   std::string str;
221   raw_string_ostream OS(str);
222   MI->print(OS, /*IsStandalone*/true, /*SkipOpers*/false, /*SkipDebugLoc*/false,
223             /*AddNewLine*/false);
224   ASSERT_TRUE(
225       StringRef(OS.str()).starts_with("$noreg = UNKNOWN debug-location "));
226   ASSERT_TRUE(StringRef(OS.str()).ends_with("filename:1:5"));
227 }
228 
229 TEST(MachineInstrSpan, DistanceBegin) {
230   LLVMContext Ctx;
231   Module Mod("Module", Ctx);
232   auto MF = createMachineFunction(Ctx, Mod);
233   auto MBB = MF->CreateMachineBasicBlock();
234 
235   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
236 
237   auto MII = MBB->begin();
238   MachineInstrSpan MIS(MII, MBB);
239   ASSERT_TRUE(MIS.empty());
240 
241   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
242   MBB->insert(MII, MI);
243   ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
244 }
245 
246 TEST(MachineInstrSpan, DistanceEnd) {
247   LLVMContext Ctx;
248   Module Mod("Module", Ctx);
249   auto MF = createMachineFunction(Ctx, Mod);
250   auto MBB = MF->CreateMachineBasicBlock();
251 
252   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
253 
254   auto MII = MBB->end();
255   MachineInstrSpan MIS(MII, MBB);
256   ASSERT_TRUE(MIS.empty());
257 
258   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
259   MBB->insert(MII, MI);
260   ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
261 }
262 
263 TEST(MachineInstrExtraInfo, AddExtraInfo) {
264   LLVMContext Ctx;
265   Module Mod("Module", Ctx);
266   auto MF = createMachineFunction(Ctx, Mod);
267   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
268 
269   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
270   auto MAI = MCAsmInfo();
271   auto MC = createMCContext(&MAI);
272   auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
273                                       MachineMemOperand::MOLoad, 8, Align(8));
274   SmallVector<MachineMemOperand *, 2> MMOs;
275   MMOs.push_back(MMO);
276   MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
277   MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
278   MDNode *HAM = MDNode::getDistinct(Ctx, std::nullopt);
279   MDNode *PCS = MDNode::getDistinct(Ctx, std::nullopt);
280 
281   ASSERT_TRUE(MI->memoperands_empty());
282   ASSERT_FALSE(MI->getPreInstrSymbol());
283   ASSERT_FALSE(MI->getPostInstrSymbol());
284   ASSERT_FALSE(MI->getHeapAllocMarker());
285   ASSERT_FALSE(MI->getPCSections());
286 
287   MI->setMemRefs(*MF, MMOs);
288   ASSERT_TRUE(MI->memoperands().size() == 1);
289   ASSERT_FALSE(MI->getPreInstrSymbol());
290   ASSERT_FALSE(MI->getPostInstrSymbol());
291   ASSERT_FALSE(MI->getHeapAllocMarker());
292   ASSERT_FALSE(MI->getPCSections());
293 
294   MI->setPreInstrSymbol(*MF, Sym1);
295   ASSERT_TRUE(MI->memoperands().size() == 1);
296   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
297   ASSERT_FALSE(MI->getPostInstrSymbol());
298   ASSERT_FALSE(MI->getHeapAllocMarker());
299   ASSERT_FALSE(MI->getPCSections());
300 
301   MI->setPostInstrSymbol(*MF, Sym2);
302   ASSERT_TRUE(MI->memoperands().size() == 1);
303   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
304   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
305   ASSERT_FALSE(MI->getHeapAllocMarker());
306   ASSERT_FALSE(MI->getPCSections());
307 
308   MI->setHeapAllocMarker(*MF, HAM);
309   ASSERT_TRUE(MI->memoperands().size() == 1);
310   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
311   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
312   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
313   ASSERT_FALSE(MI->getPCSections());
314 
315   MI->setPCSections(*MF, PCS);
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_TRUE(MI->getPCSections() == PCS);
321 }
322 
323 TEST(MachineInstrExtraInfo, ChangeExtraInfo) {
324   LLVMContext Ctx;
325   Module Mod("Module", Ctx);
326   auto MF = createMachineFunction(Ctx, Mod);
327   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
328 
329   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
330   auto MAI = MCAsmInfo();
331   auto MC = createMCContext(&MAI);
332   auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
333                                       MachineMemOperand::MOLoad, 8, Align(8));
334   SmallVector<MachineMemOperand *, 2> MMOs;
335   MMOs.push_back(MMO);
336   MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
337   MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
338   MDNode *HAM = MDNode::getDistinct(Ctx, std::nullopt);
339   MDNode *PCS = MDNode::getDistinct(Ctx, std::nullopt);
340 
341   MI->setMemRefs(*MF, MMOs);
342   MI->setPreInstrSymbol(*MF, Sym1);
343   MI->setPostInstrSymbol(*MF, Sym2);
344   MI->setHeapAllocMarker(*MF, HAM);
345   MI->setPCSections(*MF, PCS);
346 
347   MMOs.push_back(MMO);
348 
349   MI->setMemRefs(*MF, MMOs);
350   ASSERT_TRUE(MI->memoperands().size() == 2);
351   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
352   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
353   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
354   ASSERT_TRUE(MI->getPCSections() == PCS);
355 
356   MI->setPostInstrSymbol(*MF, Sym1);
357   ASSERT_TRUE(MI->memoperands().size() == 2);
358   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
359   ASSERT_TRUE(MI->getPostInstrSymbol() == Sym1);
360   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
361   ASSERT_TRUE(MI->getPCSections() == PCS);
362 }
363 
364 TEST(MachineInstrExtraInfo, RemoveExtraInfo) {
365   LLVMContext Ctx;
366   Module Mod("Module", Ctx);
367   auto MF = createMachineFunction(Ctx, Mod);
368   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
369 
370   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
371   auto MAI = MCAsmInfo();
372   auto MC = createMCContext(&MAI);
373   auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
374                                       MachineMemOperand::MOLoad, 8, Align(8));
375   SmallVector<MachineMemOperand *, 2> MMOs;
376   MMOs.push_back(MMO);
377   MMOs.push_back(MMO);
378   MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
379   MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
380   MDNode *HAM = MDNode::getDistinct(Ctx, std::nullopt);
381   MDNode *PCS = MDNode::getDistinct(Ctx, std::nullopt);
382 
383   MI->setMemRefs(*MF, MMOs);
384   MI->setPreInstrSymbol(*MF, Sym1);
385   MI->setPostInstrSymbol(*MF, Sym2);
386   MI->setHeapAllocMarker(*MF, HAM);
387   MI->setPCSections(*MF, PCS);
388 
389   MI->setPostInstrSymbol(*MF, nullptr);
390   ASSERT_TRUE(MI->memoperands().size() == 2);
391   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
392   ASSERT_FALSE(MI->getPostInstrSymbol());
393   ASSERT_TRUE(MI->getHeapAllocMarker() == HAM);
394   ASSERT_TRUE(MI->getPCSections() == PCS);
395 
396   MI->setHeapAllocMarker(*MF, nullptr);
397   ASSERT_TRUE(MI->memoperands().size() == 2);
398   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
399   ASSERT_FALSE(MI->getPostInstrSymbol());
400   ASSERT_FALSE(MI->getHeapAllocMarker());
401   ASSERT_TRUE(MI->getPCSections() == PCS);
402 
403   MI->setPCSections(*MF, nullptr);
404   ASSERT_TRUE(MI->memoperands().size() == 2);
405   ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
406   ASSERT_FALSE(MI->getPostInstrSymbol());
407   ASSERT_FALSE(MI->getHeapAllocMarker());
408   ASSERT_FALSE(MI->getPCSections());
409 
410   MI->setPreInstrSymbol(*MF, nullptr);
411   ASSERT_TRUE(MI->memoperands().size() == 2);
412   ASSERT_FALSE(MI->getPreInstrSymbol());
413   ASSERT_FALSE(MI->getPostInstrSymbol());
414   ASSERT_FALSE(MI->getHeapAllocMarker());
415   ASSERT_FALSE(MI->getPCSections());
416 
417   MI->setMemRefs(*MF, {});
418   ASSERT_TRUE(MI->memoperands_empty());
419   ASSERT_FALSE(MI->getPreInstrSymbol());
420   ASSERT_FALSE(MI->getPostInstrSymbol());
421   ASSERT_FALSE(MI->getHeapAllocMarker());
422   ASSERT_FALSE(MI->getPCSections());
423 }
424 
425 TEST(MachineInstrDebugValue, AddDebugValueOperand) {
426   LLVMContext Ctx;
427   Module Mod("Module", Ctx);
428   auto MF = createMachineFunction(Ctx, Mod);
429 
430   for (const unsigned short Opcode :
431        {TargetOpcode::DBG_VALUE, TargetOpcode::DBG_VALUE_LIST,
432         TargetOpcode::DBG_INSTR_REF, TargetOpcode::DBG_PHI,
433         TargetOpcode::DBG_LABEL}) {
434     const MCInstrDesc MCID = {
435         Opcode, 0, 0, 0, 0,
436         0,      0, 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
437         0};
438 
439     auto *MI = MF->CreateMachineInstr(MCID, DebugLoc());
440     MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false));
441 
442     MI->addOperand(*MF, MachineOperand::CreateImm(0));
443     MI->getOperand(1).ChangeToRegister(0, false);
444 
445     ASSERT_TRUE(MI->getOperand(0).isDebug());
446     ASSERT_TRUE(MI->getOperand(1).isDebug());
447   }
448 }
449 
450 MATCHER_P(HasMIMetadata, MIMD, "") {
451   return arg->getDebugLoc() == MIMD.getDL() &&
452          arg->getPCSections() == MIMD.getPCSections();
453 }
454 
455 TEST(MachineInstrBuilder, BuildMI) {
456   LLVMContext Ctx;
457   MDNode *PCS = MDNode::getDistinct(Ctx, std::nullopt);
458   MDNode *DI = MDNode::getDistinct(Ctx, std::nullopt);
459   DebugLoc DL(DI);
460   MIMetadata MIMD(DL, PCS);
461   EXPECT_EQ(MIMD.getDL(), DL);
462   EXPECT_EQ(MIMD.getPCSections(), PCS);
463   // Check common BuildMI() overloads propagate MIMetadata.
464   Module Mod("Module", Ctx);
465   auto MF = createMachineFunction(Ctx, Mod);
466   auto MBB = MF->CreateMachineBasicBlock();
467   MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
468   EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD));
469   EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD));
470   EXPECT_THAT(BuildMI(*MBB, MBB->end(), MIMD, MCID), HasMIMetadata(MIMD));
471   EXPECT_THAT(BuildMI(*MBB, MBB->end(), MIMD, MCID), HasMIMetadata(MIMD));
472   EXPECT_THAT(BuildMI(*MBB, MBB->instr_end(), MIMD, MCID), HasMIMetadata(MIMD));
473   EXPECT_THAT(BuildMI(*MBB, *MBB->begin(), MIMD, MCID), HasMIMetadata(MIMD));
474   EXPECT_THAT(BuildMI(*MBB, &*MBB->begin(), MIMD, MCID), HasMIMetadata(MIMD));
475   EXPECT_THAT(BuildMI(MBB, MIMD, MCID), HasMIMetadata(MIMD));
476 }
477 
478 static_assert(std::is_trivially_copyable_v<MCOperand>, "trivially copyable");
479 
480 TEST(MachineInstrTest, SpliceOperands) {
481   LLVMContext Ctx;
482   Module Mod("Module", Ctx);
483   std::unique_ptr<MachineFunction> MF = createMachineFunction(Ctx, Mod);
484   MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
485   MCInstrDesc MCID = {TargetOpcode::INLINEASM,
486                       0,
487                       0,
488                       0,
489                       0,
490                       0,
491                       0,
492                       0,
493                       0,
494                       (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
495                       0};
496   MachineInstr *MI = MF->CreateMachineInstr(MCID, DebugLoc());
497   MBB->insert(MBB->begin(), MI);
498   MI->addOperand(MachineOperand::CreateImm(0));
499   MI->addOperand(MachineOperand::CreateImm(1));
500   MI->addOperand(MachineOperand::CreateImm(2));
501   MI->addOperand(MachineOperand::CreateImm(3));
502   MI->addOperand(MachineOperand::CreateImm(4));
503 
504   MI->removeOperand(1);
505   EXPECT_EQ(MI->getOperand(1).getImm(), MachineOperand::CreateImm(2).getImm());
506   EXPECT_EQ(MI->getNumOperands(), 4U);
507 
508   MachineOperand Ops[] = {
509       MachineOperand::CreateImm(42),   MachineOperand::CreateImm(1024),
510       MachineOperand::CreateImm(2048), MachineOperand::CreateImm(4096),
511       MachineOperand::CreateImm(8192),
512   };
513   auto *It = MI->operands_begin();
514   ++It;
515   MI->insert(It, Ops);
516 
517   EXPECT_EQ(MI->getNumOperands(), 9U);
518   EXPECT_EQ(MI->getOperand(0).getImm(), MachineOperand::CreateImm(0).getImm());
519   EXPECT_EQ(MI->getOperand(1).getImm(), MachineOperand::CreateImm(42).getImm());
520   EXPECT_EQ(MI->getOperand(2).getImm(),
521             MachineOperand::CreateImm(1024).getImm());
522   EXPECT_EQ(MI->getOperand(3).getImm(),
523             MachineOperand::CreateImm(2048).getImm());
524   EXPECT_EQ(MI->getOperand(4).getImm(),
525             MachineOperand::CreateImm(4096).getImm());
526   EXPECT_EQ(MI->getOperand(5).getImm(),
527             MachineOperand::CreateImm(8192).getImm());
528   EXPECT_EQ(MI->getOperand(6).getImm(), MachineOperand::CreateImm(2).getImm());
529   EXPECT_EQ(MI->getOperand(7).getImm(), MachineOperand::CreateImm(3).getImm());
530   EXPECT_EQ(MI->getOperand(8).getImm(), MachineOperand::CreateImm(4).getImm());
531 
532   // test tied operands
533   MCRegisterClass MRC{0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true};
534   TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0};
535   // MachineRegisterInfo will be very upset if these registers aren't
536   // allocatable.
537   assert(RC.isAllocatable() && "unusable TargetRegisterClass");
538   MachineRegisterInfo &MRI = MF->getRegInfo();
539   Register A = MRI.createVirtualRegister(&RC);
540   Register B = MRI.createVirtualRegister(&RC);
541   MI->getOperand(0).ChangeToRegister(A, /*isDef=*/true);
542   MI->getOperand(1).ChangeToRegister(B, /*isDef=*/false);
543   MI->tieOperands(0, 1);
544   EXPECT_TRUE(MI->getOperand(0).isTied());
545   EXPECT_TRUE(MI->getOperand(1).isTied());
546   EXPECT_EQ(MI->findTiedOperandIdx(0), 1U);
547   EXPECT_EQ(MI->findTiedOperandIdx(1), 0U);
548   MI->insert(&MI->getOperand(1), {MachineOperand::CreateImm(7)});
549   EXPECT_TRUE(MI->getOperand(0).isTied());
550   EXPECT_TRUE(MI->getOperand(1).isImm());
551   EXPECT_TRUE(MI->getOperand(2).isTied());
552   EXPECT_EQ(MI->findTiedOperandIdx(0), 2U);
553   EXPECT_EQ(MI->findTiedOperandIdx(2), 0U);
554   EXPECT_EQ(MI->getOperand(0).getReg(), A);
555   EXPECT_EQ(MI->getOperand(2).getReg(), B);
556 
557   // bad inputs
558   EXPECT_EQ(MI->getNumOperands(), 10U);
559   MI->insert(MI->operands_begin(), {});
560   EXPECT_EQ(MI->getNumOperands(), 10U);
561 }
562 
563 } // end namespace
564