1 //===- MachineInstrTest.cpp -----------------------------------------------===//
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
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"
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
) {
51 Module
Mod("Module", Ctx
);
52 auto MF
= createMachineFunction(Ctx
, Mod
);
54 unsigned short NumOps
= 2;
55 unsigned char NumDefs
= 1;
58 MCOperandInfo OpInfo
[2];
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
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
) {
123 Module
Mod("Module", Ctx
);
124 auto MF
= createMachineFunction(Ctx
, Mod
);
126 unsigned short NumOps
= 2;
127 unsigned char NumDefs
= 1;
130 MCOperandInfo OpInfo
[2];
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
) {
204 Module
Mod("Module", Ctx
);
205 auto MF
= createMachineFunction(Ctx
, Mod
);
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
);
219 MachineInstr
*MI
= MF
->CreateMachineInstr(Table
.MCID
, DL
);
220 MI
->addOperand(*MF
, MachineOperand::CreateReg(0, /*isDef*/ true));
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
) {
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
) {
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
) {
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
;
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
) {
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
;
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
);
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
) {
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
;
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
) {
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
= {
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
) {
509 MDNode
*PCS
= MDNode::getDistinct(Ctx
, {});
510 MDNode
*DI
= MDNode::getDistinct(Ctx
, {});
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
) {
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();
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
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
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
);
611 EXPECT_EQ(MI
->getNumOperands(), 10U);
612 MI
->insert(MI
->operands_begin(), {});
613 EXPECT_EQ(MI
->getNumOperands(), 10U);