1 //===- MachineInstrBundleIteratorTest.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/ADT/STLExtras.h"
10 #include "llvm/CodeGen/MIRParser/MIRParser.h"
11 #include "llvm/CodeGen/MIRPrinter.h"
12 #include "llvm/CodeGen/MachineFunction.h"
13 #include "llvm/CodeGen/MachineMemOperand.h"
14 #include "llvm/CodeGen/MachineModuleInfo.h"
15 #include "llvm/CodeGen/MachineModuleSlotTracker.h"
16 #include "llvm/CodeGen/MachineOperand.h"
17 #include "llvm/CodeGen/TargetFrameLowering.h"
18 #include "llvm/CodeGen/TargetInstrInfo.h"
19 #include "llvm/CodeGen/TargetLowering.h"
20 #include "llvm/CodeGen/TargetSubtargetInfo.h"
21 #include "llvm/FileCheck/FileCheck.h"
22 #include "llvm/IR/MDBuilder.h"
23 #include "llvm/IR/ModuleSlotTracker.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/TargetRegistry.h"
26 #include "llvm/Support/SourceMgr.h"
27 #include "llvm/Support/TargetSelect.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "gtest/gtest.h"
33 class MachineMetadataTest
: public testing::Test
{
35 MachineMetadataTest() {}
39 std::unique_ptr
<Module
> M
;
40 std::unique_ptr
<MIRParser
> MIR
;
42 static void SetUpTestCase() {
43 InitializeAllTargetInfos();
44 InitializeAllTargets();
45 InitializeAllTargetMCs();
48 void SetUp() override
{ M
= std::make_unique
<Module
>("Dummy", Context
); }
50 void addHooks(ModuleSlotTracker
&MST
, const MachineOperand
&MO
) {
51 // Setup hooks to assign slot numbers for the specified machine metadata.
52 MST
.setProcessHook([&MO
](AbstractSlotTrackerStorage
*AST
, const Module
*M
,
53 bool ShouldInitializeAllMetadata
) {
54 if (ShouldInitializeAllMetadata
) {
56 AST
->createMetadataSlot(MO
.getMetadata());
59 MST
.setProcessHook([&MO
](AbstractSlotTrackerStorage
*AST
, const Function
*F
,
60 bool ShouldInitializeAllMetadata
) {
61 if (!ShouldInitializeAllMetadata
) {
63 AST
->createMetadataSlot(MO
.getMetadata());
68 std::unique_ptr
<LLVMTargetMachine
>
69 createTargetMachine(std::string TT
, StringRef CPU
, StringRef FS
) {
71 const Target
*T
= TargetRegistry::lookupTarget(TT
, Error
);
74 TargetOptions Options
;
75 return std::unique_ptr
<LLVMTargetMachine
>(
76 static_cast<LLVMTargetMachine
*>(T
->createTargetMachine(
77 TT
, CPU
, FS
, Options
, std::nullopt
, std::nullopt
)));
80 std::unique_ptr
<Module
> parseMIR(const TargetMachine
&TM
, StringRef MIRCode
,
81 const char *FnName
, MachineModuleInfo
&MMI
) {
82 SMDiagnostic Diagnostic
;
83 std::unique_ptr
<MemoryBuffer
> MBuffer
= MemoryBuffer::getMemBuffer(MIRCode
);
84 MIR
= createMIRParser(std::move(MBuffer
), Context
);
88 std::unique_ptr
<Module
> Mod
= MIR
->parseIRModule();
92 Mod
->setDataLayout(TM
.createDataLayout());
94 if (MIR
->parseMachineFunctions(*Mod
, MMI
)) {
103 // Helper to dump the printer output into a string.
104 static std::string
print(std::function
<void(raw_ostream
&OS
)> PrintFn
) {
106 raw_string_ostream
OS(Str
);
112 TEST_F(MachineMetadataTest
, TrivialHook
) {
113 // Verify that post-process hook is invoked to assign slot numbers for
117 // Create a MachineOperand with a metadata and print it.
118 Metadata
*MDS
= MDString::get(Context
, "foo");
119 MDNode
*Node
= MDNode::get(Context
, MDS
);
120 MachineOperand MO
= MachineOperand::CreateMetadata(Node
);
122 // Checking some preconditions on the newly created
124 ASSERT_TRUE(MO
.isMetadata());
125 ASSERT_EQ(MO
.getMetadata(), Node
);
127 ModuleSlotTracker
MST(M
.get());
130 // Print a MachineOperand containing a metadata node.
131 EXPECT_EQ("!0", print([&](raw_ostream
&OS
) {
132 MO
.print(OS
, MST
, LLT
{}, /*OpIdx*/ ~0U, /*PrintDef=*/false,
133 /*IsStandalone=*/false,
134 /*ShouldPrintRegisterTies=*/false, /*TiedOperandIdx=*/0,
136 /*IntrinsicInfo=*/nullptr);
138 // Print the definition of that metadata node.
139 EXPECT_EQ("!0 = !{!\"foo\"}",
140 print([&](raw_ostream
&OS
) { Node
->print(OS
, MST
); }));
143 TEST_F(MachineMetadataTest
, BasicHook
) {
144 // Verify that post-process hook is invoked to assign slot numbers for
145 // machine metadata. When both LLVM IR and machine IR contain metadata,
146 // ensure that machine metadata is always assigned after LLVM IR.
149 // Create a MachineOperand with a metadata and print it.
150 Metadata
*MachineMDS
= MDString::get(Context
, "foo");
151 MDNode
*MachineNode
= MDNode::get(Context
, MachineMDS
);
152 MachineOperand MO
= MachineOperand::CreateMetadata(MachineNode
);
154 // Checking some preconditions on the newly created
156 ASSERT_TRUE(MO
.isMetadata());
157 ASSERT_EQ(MO
.getMetadata(), MachineNode
);
159 // Create metadata in LLVM IR.
160 NamedMDNode
*MD
= M
->getOrInsertNamedMetadata("namedmd");
161 Metadata
*MDS
= MDString::get(Context
, "bar");
162 MDNode
*Node
= MDNode::get(Context
, MDS
);
163 MD
->addOperand(Node
);
165 ModuleSlotTracker
MST(M
.get());
168 // Print a MachineOperand containing a metadata node.
169 EXPECT_EQ("!1", print([&](raw_ostream
&OS
) {
170 MO
.print(OS
, MST
, LLT
{}, /*OpIdx*/ ~0U, /*PrintDef=*/false,
171 /*IsStandalone=*/false,
172 /*ShouldPrintRegisterTies=*/false, /*TiedOperandIdx=*/0,
174 /*IntrinsicInfo=*/nullptr);
176 // Print the definition of these unnamed metadata nodes.
177 EXPECT_EQ("!0 = !{!\"bar\"}",
178 print([&](raw_ostream
&OS
) { Node
->print(OS
, MST
); }));
179 EXPECT_EQ("!1 = !{!\"foo\"}",
180 print([&](raw_ostream
&OS
) { MachineNode
->print(OS
, MST
); }));
183 static bool checkOutput(std::string CheckString
, std::string Output
) {
184 auto CheckBuffer
= MemoryBuffer::getMemBuffer(CheckString
, "");
185 auto OutputBuffer
= MemoryBuffer::getMemBuffer(Output
, "Output", false);
187 SmallString
<4096> CheckFileBuffer
;
188 FileCheckRequest Req
;
190 StringRef CheckFileText
=
191 FC
.CanonicalizeFile(*CheckBuffer
.get(), CheckFileBuffer
);
194 SM
.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(CheckFileText
, "CheckFile"),
196 Regex PrefixRE
= FC
.buildCheckPrefixRegex();
197 if (FC
.readCheckFile(SM
, CheckFileText
, PrefixRE
))
200 auto OutBuffer
= OutputBuffer
->getBuffer();
201 SM
.AddNewSourceBuffer(std::move(OutputBuffer
), SMLoc());
202 return FC
.checkInput(SM
, OutBuffer
);
205 TEST_F(MachineMetadataTest
, MMSlotTrackerAArch64
) {
206 auto TM
= createTargetMachine(Triple::normalize("aarch64--"), "", "");
210 StringRef MIRString
= R
"MIR(
212 define i32 @test0(i32* %p) {
213 %r = load i32, i32* %p, align 4
220 - { reg: '$x0', virtual-reg: '%0' }
225 %0:gpr64common = COPY $x0
226 %1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p)
230 MachineModuleInfo
MMI(TM
.get());
231 M
= parseMIR(*TM
, MIRString
, "test0", MMI
);
234 auto *MF
= MMI
.getMachineFunction(*M
->getFunction("test0"));
235 auto *MBB
= MF
->getBlockNumbered(0);
237 auto &MI
= MBB
->back();
238 ASSERT_TRUE(MI
.hasOneMemOperand());
240 // Create and attached scoped AA metadata on that instruction with one MMO.
241 MDBuilder
MDB(Context
);
242 MDNode
*Domain
= MDB
.createAnonymousAliasScopeDomain("domain");
243 MDNode
*Scope0
= MDB
.createAnonymousAliasScope(Domain
, "scope0");
244 MDNode
*Scope1
= MDB
.createAnonymousAliasScope(Domain
, "scope1");
245 MDNode
*Set0
= MDNode::get(Context
, {Scope0
});
246 MDNode
*Set1
= MDNode::get(Context
, {Scope1
});
249 AAInfo
.TBAA
= AAInfo
.TBAAStruct
= nullptr;
251 AAInfo
.NoAlias
= Set1
;
253 auto *OldMMO
= MI
.memoperands().front();
254 auto *NewMMO
= MF
->getMachineMemOperand(OldMMO
, AAInfo
);
255 MI
.setMemRefs(*MF
, NewMMO
);
257 MachineModuleSlotTracker
MST(MF
);
258 // Print that MI with new machine metadata, which slot numbers should be
260 EXPECT_EQ("%1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p, "
261 "!alias.scope !0, !noalias !3)",
262 print([&](raw_ostream
&OS
) {
263 MI
.print(OS
, MST
, /*IsStandalone=*/false, /*SkipOpers=*/false,
264 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
267 std::vector
<const MDNode
*> Generated
{Domain
, Scope0
, Scope1
, Set0
, Set1
};
268 // Examine machine metadata collected. They should match ones
270 std::vector
<const MDNode
*> Collected
;
271 MachineModuleSlotTracker::MachineMDNodeListType MDList
;
272 MST
.collectMachineMDNodes(MDList
);
273 for (auto &MD
: MDList
)
274 Collected
.push_back(MD
.second
);
276 llvm::sort(Generated
);
277 llvm::sort(Collected
);
278 EXPECT_EQ(Collected
, Generated
);
280 // FileCheck the output from MIR printer.
281 std::string Output
= print([&](raw_ostream
&OS
) { printMIR(OS
, *MF
); });
282 std::string CheckString
= R
"(
283 CHECK: machineMetadataNodes:
284 CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain
"}
285 CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0
"}
286 CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1
"}
287 CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}
288 CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}
290 CHECK: %1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p, !alias.scope ![[MMSET0]], !noalias ![[MMSET1]])
292 EXPECT_TRUE(checkOutput(CheckString
, Output
));
295 TEST_F(MachineMetadataTest
, isMetaInstruction
) {
296 auto TM
= createTargetMachine(Triple::normalize("x86_64--"), "", "");
300 StringRef MIRString
= R
"MIR(
302 define void @test0(i32 %b) {
305 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang
", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
306 !1 = !DIFile(filename: "a
.c
", directory: "/tmp
")
307 !2 = !{i32 7, !"Dwarf Version
", i32 4}
308 !3 = !{i32 2, !"Debug Info Version
", i32 3}
309 !4 = !{i32 1, !"wchar_size
", i32 4}
310 !5 = !{i32 7, !"uwtable
", i32 1}
311 !6 = !{i32 7, !"frame
-pointer
", i32 2}
313 !8 = distinct !DISubprogram(name: "test0
", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
314 !9 = !DISubroutineType(types: !10)
316 !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
318 !13 = !DILocalVariable(name: "b
", arg: 1, scope: !8, file: !1, line: 1, type: !11)
319 !14 = !DILocation(line: 1, column: 16, scope: !8)
328 CFI_INSTRUCTION undefined $rax
331 DBG_VALUE $rax, $noreg, !13, !DIExpression(), debug-location !14
335 PSEUDO_PROBE 6699318081062747564, 1, 0, 0
336 $xmm0 = ARITH_FENCE $xmm0
341 MachineModuleInfo
MMI(TM
.get());
342 M
= parseMIR(*TM
, MIRString
, "test0", MMI
);
345 auto *MF
= MMI
.getMachineFunction(*M
->getFunction("test0"));
346 auto *MBB
= MF
->getBlockNumbered(0);
348 for (auto It
= MBB
->begin(); It
!= MBB
->end(); ++It
) {
349 MachineInstr
&MI
= *It
;
350 ASSERT_TRUE(MI
.isMetaInstruction());
354 TEST_F(MachineMetadataTest
, MMSlotTrackerX64
) {
355 auto TM
= createTargetMachine(Triple::normalize("x86_64--"), "", "");
359 StringRef MIRString
= R
"MIR(
361 define i32 @test0(i32* %p) {
362 %r = load i32, i32* %p, align 4
369 - { reg: '$rdi', virtual-reg: '%0' }
375 %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p)
379 MachineModuleInfo
MMI(TM
.get());
380 M
= parseMIR(*TM
, MIRString
, "test0", MMI
);
383 auto *MF
= MMI
.getMachineFunction(*M
->getFunction("test0"));
384 auto *MBB
= MF
->getBlockNumbered(0);
386 auto &MI
= MBB
->back();
387 ASSERT_FALSE(MI
.memoperands_empty());
388 ASSERT_TRUE(MI
.hasOneMemOperand());
390 // Create and attached scoped AA metadata on that instruction with one MMO.
391 MDBuilder
MDB(Context
);
392 MDNode
*Domain
= MDB
.createAnonymousAliasScopeDomain("domain");
393 MDNode
*Scope0
= MDB
.createAnonymousAliasScope(Domain
, "scope0");
394 MDNode
*Scope1
= MDB
.createAnonymousAliasScope(Domain
, "scope1");
395 MDNode
*Set0
= MDNode::get(Context
, {Scope0
});
396 MDNode
*Set1
= MDNode::get(Context
, {Scope1
});
399 AAInfo
.TBAA
= AAInfo
.TBAAStruct
= nullptr;
401 AAInfo
.NoAlias
= Set1
;
403 auto *OldMMO
= MI
.memoperands().front();
404 auto *NewMMO
= MF
->getMachineMemOperand(OldMMO
, AAInfo
);
405 MI
.setMemRefs(*MF
, NewMMO
);
407 MachineModuleSlotTracker
MST(MF
);
408 // Print that MI with new machine metadata, which slot numbers should be
410 EXPECT_EQ("%1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, "
411 "!alias.scope !0, !noalias !3)",
412 print([&](raw_ostream
&OS
) {
413 MI
.print(OS
, MST
, /*IsStandalone=*/false, /*SkipOpers=*/false,
414 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
417 std::vector
<const MDNode
*> Generated
{Domain
, Scope0
, Scope1
, Set0
, Set1
};
418 // Examine machine metadata collected. They should match ones
420 std::vector
<const MDNode
*> Collected
;
421 MachineModuleSlotTracker::MachineMDNodeListType MDList
;
422 MST
.collectMachineMDNodes(MDList
);
423 for (auto &MD
: MDList
)
424 Collected
.push_back(MD
.second
);
426 llvm::sort(Generated
);
427 llvm::sort(Collected
);
428 EXPECT_EQ(Collected
, Generated
);
430 // FileCheck the output from MIR printer.
431 std::string Output
= print([&](raw_ostream
&OS
) { printMIR(OS
, *MF
); });
432 std::string CheckString
= R
"(
433 CHECK: machineMetadataNodes:
434 CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain
"}
435 CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0
"}
436 CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1
"}
437 CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}
438 CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}
440 CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, !alias.scope ![[MMSET0]], !noalias ![[MMSET1]])
442 EXPECT_TRUE(checkOutput(CheckString
, Output
));
445 TEST_F(MachineMetadataTest
, MMSlotTrackerAMDGPU
) {
446 auto TM
= createTargetMachine(Triple::normalize("amdgcn-amd-amdhsa"),
451 StringRef MIRString
= R
"MIR(
453 define i32 @test0(i32* %p) {
454 %r = load i32, i32* %p, align 4
461 - { reg: '$vgpr0', virtual-reg: '%0' }
462 - { reg: '$vgpr1', virtual-reg: '%1' }
463 - { reg: '$sgpr30_sgpr31', virtual-reg: '%2' }
466 liveins: $vgpr0, $vgpr1, $sgpr30_sgpr31
468 %2:sreg_64 = COPY $sgpr30_sgpr31
469 %1:vgpr_32 = COPY $vgpr1
470 %0:vgpr_32 = COPY $vgpr0
471 %8:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
473 %5:vgpr_32 = FLAT_LOAD_DWORD killed %6, 0, 0, implicit $exec, implicit $flat_scr :: (load (s32) from %ir.p)
477 MachineModuleInfo
MMI(TM
.get());
478 M
= parseMIR(*TM
, MIRString
, "test0", MMI
);
481 auto *MF
= MMI
.getMachineFunction(*M
->getFunction("test0"));
482 auto *MBB
= MF
->getBlockNumbered(0);
484 auto &MI
= MBB
->back();
485 ASSERT_FALSE(MI
.memoperands_empty());
486 ASSERT_TRUE(MI
.hasOneMemOperand());
488 // Create and attached scoped AA metadata on that instruction with one MMO.
489 MDBuilder
MDB(Context
);
490 MDNode
*Domain
= MDB
.createAnonymousAliasScopeDomain("domain");
491 MDNode
*Scope0
= MDB
.createAnonymousAliasScope(Domain
, "scope0");
492 MDNode
*Scope1
= MDB
.createAnonymousAliasScope(Domain
, "scope1");
493 MDNode
*Set0
= MDNode::get(Context
, {Scope0
});
494 MDNode
*Set1
= MDNode::get(Context
, {Scope1
});
497 AAInfo
.TBAA
= AAInfo
.TBAAStruct
= nullptr;
499 AAInfo
.NoAlias
= Set1
;
501 auto *OldMMO
= MI
.memoperands().front();
502 auto *NewMMO
= MF
->getMachineMemOperand(OldMMO
, AAInfo
);
503 MI
.setMemRefs(*MF
, NewMMO
);
505 MachineModuleSlotTracker
MST(MF
);
506 // Print that MI with new machine metadata, which slot numbers should be
509 "%5:vgpr_32 = FLAT_LOAD_DWORD killed %4, 0, 0, implicit $exec, implicit "
510 "$flat_scr :: (load (s32) from %ir.p, !alias.scope !0, !noalias !3)",
511 print([&](raw_ostream
&OS
) {
512 MI
.print(OS
, MST
, /*IsStandalone=*/false, /*SkipOpers=*/false,
513 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
516 std::vector
<const MDNode
*> Generated
{Domain
, Scope0
, Scope1
, Set0
, Set1
};
517 // Examine machine metadata collected. They should match ones
519 std::vector
<const MDNode
*> Collected
;
520 MachineModuleSlotTracker::MachineMDNodeListType MDList
;
521 MST
.collectMachineMDNodes(MDList
);
522 for (auto &MD
: MDList
)
523 Collected
.push_back(MD
.second
);
525 llvm::sort(Generated
);
526 llvm::sort(Collected
);
527 EXPECT_EQ(Collected
, Generated
);
529 // FileCheck the output from MIR printer.
530 std::string Output
= print([&](raw_ostream
&OS
) { printMIR(OS
, *MF
); });
531 std::string CheckString
= R
"(
532 CHECK: machineMetadataNodes:
533 CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain
"}
534 CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0
"}
535 CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1
"}
536 CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}
537 CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}
539 CHECK: %5:vgpr_32 = FLAT_LOAD_DWORD killed %4, 0, 0, implicit $exec, implicit $flat_scr :: (load (s32) from %ir.p, !alias.scope ![[MMSET0]], !noalias ![[MMSET1]])
541 EXPECT_TRUE(checkOutput(CheckString
, Output
));
544 TEST_F(MachineMetadataTest
, TiedOpsRewritten
) {
545 auto TM
= createTargetMachine(Triple::normalize("powerpc64--"), "", "");
548 StringRef MIRString
= R
"MIR(
552 tracksRegLiveness: true
555 machineFunctionInfo: {}
560 %0 = RLWIMI killed %0, $r3, 1, 0, 30
562 BLR8 implicit $r3, implicit $lr8, implicit $rm
566 MachineModuleInfo
MMI(TM
.get());
567 M
= parseMIR(*TM
, MIRString
, "foo", MMI
);
569 auto *MF
= MMI
.getMachineFunction(*M
->getFunction("foo"));
570 MachineFunctionProperties
&Properties
= MF
->getProperties();
571 ASSERT_TRUE(Properties
.hasProperty(
572 MachineFunctionProperties::Property::TiedOpsRewritten
));
575 TEST_F(MachineMetadataTest
, NoTiedOpsRewritten
) {
576 auto TM
= createTargetMachine(Triple::normalize("powerpc64--"), "", "");
579 StringRef MIRString
= R
"MIR(
583 tracksRegLiveness: true
586 machineFunctionInfo: {}
591 %1:gprc = RLWIMI killed %0, $r3, 1, 0, 30
593 BLR8 implicit $r3, implicit $lr8, implicit $rm
597 MachineModuleInfo
MMI(TM
.get());
598 M
= parseMIR(*TM
, MIRString
, "foo", MMI
);
600 auto *MF
= MMI
.getMachineFunction(*M
->getFunction("foo"));
601 MachineFunctionProperties
&Properties
= MF
->getProperties();
602 ASSERT_FALSE(Properties
.hasProperty(
603 MachineFunctionProperties::Property::TiedOpsRewritten
));