[AMDGPU] Test codegen'ing True16 additions.
[llvm-project.git] / llvm / unittests / MIR / MachineMetadata.cpp
blobf50e9b562942b6243162bfe2d715e9b8e6957e8d
1 //===- MachineInstrBundleIteratorTest.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 //===----------------------------------------------------------------------===//
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"
31 using namespace llvm;
33 class MachineMetadataTest : public testing::Test {
34 public:
35 MachineMetadataTest() {}
37 protected:
38 LLVMContext Context;
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) {
55 if (MO.isMetadata())
56 AST->createMetadataSlot(MO.getMetadata());
58 });
59 MST.setProcessHook([&MO](AbstractSlotTrackerStorage *AST, const Function *F,
60 bool ShouldInitializeAllMetadata) {
61 if (!ShouldInitializeAllMetadata) {
62 if (MO.isMetadata())
63 AST->createMetadataSlot(MO.getMetadata());
65 });
68 std::unique_ptr<LLVMTargetMachine>
69 createTargetMachine(std::string TT, StringRef CPU, StringRef FS) {
70 std::string Error;
71 const Target *T = TargetRegistry::lookupTarget(TT, Error);
72 if (!T)
73 return nullptr;
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);
85 if (!MIR)
86 return nullptr;
88 std::unique_ptr<Module> Mod = MIR->parseIRModule();
89 if (!Mod)
90 return nullptr;
92 Mod->setDataLayout(TM.createDataLayout());
94 if (MIR->parseMachineFunctions(*Mod, MMI)) {
95 M.reset();
96 return nullptr;
99 return Mod;
103 // Helper to dump the printer output into a string.
104 static std::string print(std::function<void(raw_ostream &OS)> PrintFn) {
105 std::string Str;
106 raw_string_ostream OS(Str);
107 PrintFn(OS);
108 OS.flush();
109 return Str;
112 TEST_F(MachineMetadataTest, TrivialHook) {
113 // Verify that post-process hook is invoked to assign slot numbers for
114 // machine metadata.
115 ASSERT_TRUE(M);
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
123 // MachineOperand.
124 ASSERT_TRUE(MO.isMetadata());
125 ASSERT_EQ(MO.getMetadata(), Node);
127 ModuleSlotTracker MST(M.get());
128 addHooks(MST, MO);
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,
135 /*TRI=*/nullptr,
136 /*IntrinsicInfo=*/nullptr);
137 }));
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.
147 ASSERT_TRUE(M);
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
155 // MachineOperand.
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());
166 addHooks(MST, MO);
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,
173 /*TRI=*/nullptr,
174 /*IntrinsicInfo=*/nullptr);
175 }));
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;
189 FileCheck FC(Req);
190 StringRef CheckFileText =
191 FC.CanonicalizeFile(*CheckBuffer.get(), CheckFileBuffer);
193 SourceMgr SM;
194 SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(CheckFileText, "CheckFile"),
195 SMLoc());
196 Regex PrefixRE = FC.buildCheckPrefixRegex();
197 if (FC.readCheckFile(SM, CheckFileText, PrefixRE))
198 return false;
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--"), "", "");
207 if (!TM)
208 GTEST_SKIP();
210 StringRef MIRString = R"MIR(
211 --- |
212 define i32 @test0(i32* %p) {
213 %r = load i32, i32* %p, align 4
214 ret i32 %r
218 name: test0
219 liveins:
220 - { reg: '$x0', virtual-reg: '%0' }
221 body: |
222 bb.0 (%ir-block.0):
223 liveins: $x0
225 %0:gpr64common = COPY $x0
226 %1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p)
228 )MIR";
230 MachineModuleInfo MMI(TM.get());
231 M = parseMIR(*TM, MIRString, "test0", MMI);
232 ASSERT_TRUE(M);
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});
248 AAMDNodes AAInfo;
249 AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;
250 AAInfo.Scope = Set0;
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
259 // assigned.
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);
265 }));
267 std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};
268 // Examine machine metadata collected. They should match ones
269 // afore-generated.
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]]}
289 CHECK: body:
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--"), "", "");
297 if (!TM)
298 GTEST_SKIP();
300 StringRef MIRString = R"MIR(
301 --- |
302 define void @test0(i32 %b) {
303 ret void
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}
312 !7 = !{!""}
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)
315 !10 = !{null, !11}
316 !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
317 !12 = !{}
318 !13 = !DILocalVariable(name: "b", arg: 1, scope: !8, file: !1, line: 1, type: !11)
319 !14 = !DILocation(line: 1, column: 16, scope: !8)
322 name: test0
323 machineFunctionInfo
324 body: |
325 bb.0:
326 $rdi = IMPLICIT_DEF
327 KILL $rsi
328 CFI_INSTRUCTION undefined $rax
329 EH_LABEL 0
330 GC_LABEL 0
331 DBG_VALUE $rax, $noreg, !13, !DIExpression(), debug-location !14
332 DBG_LABEL 0
333 LIFETIME_START 0
334 LIFETIME_END 0
335 PSEUDO_PROBE 6699318081062747564, 1, 0, 0
336 $xmm0 = ARITH_FENCE $xmm0
337 MEMBARRIER
339 )MIR";
341 MachineModuleInfo MMI(TM.get());
342 M = parseMIR(*TM, MIRString, "test0", MMI);
343 ASSERT_TRUE(M);
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--"), "", "");
356 if (!TM)
357 GTEST_SKIP();
359 StringRef MIRString = R"MIR(
360 --- |
361 define i32 @test0(i32* %p) {
362 %r = load i32, i32* %p, align 4
363 ret i32 %r
367 name: test0
368 liveins:
369 - { reg: '$rdi', virtual-reg: '%0' }
370 body: |
371 bb.0 (%ir-block.0):
372 liveins: $rdi
374 %0:gr64 = COPY $rdi
375 %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p)
377 )MIR";
379 MachineModuleInfo MMI(TM.get());
380 M = parseMIR(*TM, MIRString, "test0", MMI);
381 ASSERT_TRUE(M);
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});
398 AAMDNodes AAInfo;
399 AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;
400 AAInfo.Scope = Set0;
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
409 // assigned.
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);
415 }));
417 std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};
418 // Examine machine metadata collected. They should match ones
419 // afore-generated.
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]]}
439 CHECK: body:
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"),
447 "gfx1010", "");
448 if (!TM)
449 GTEST_SKIP();
451 StringRef MIRString = R"MIR(
452 --- |
453 define i32 @test0(i32* %p) {
454 %r = load i32, i32* %p, align 4
455 ret i32 %r
459 name: test0
460 liveins:
461 - { reg: '$vgpr0', virtual-reg: '%0' }
462 - { reg: '$vgpr1', virtual-reg: '%1' }
463 - { reg: '$sgpr30_sgpr31', virtual-reg: '%2' }
464 body: |
465 bb.0 (%ir-block.0):
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
472 %6:vreg_64 = COPY %8
473 %5:vgpr_32 = FLAT_LOAD_DWORD killed %6, 0, 0, implicit $exec, implicit $flat_scr :: (load (s32) from %ir.p)
475 )MIR";
477 MachineModuleInfo MMI(TM.get());
478 M = parseMIR(*TM, MIRString, "test0", MMI);
479 ASSERT_TRUE(M);
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});
496 AAMDNodes AAInfo;
497 AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;
498 AAInfo.Scope = Set0;
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
507 // assigned.
508 EXPECT_EQ(
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);
514 }));
516 std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};
517 // Examine machine metadata collected. They should match ones
518 // afore-generated.
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]]}
538 CHECK: body:
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--"), "", "");
546 if (!TM)
547 GTEST_SKIP();
548 StringRef MIRString = R"MIR(
550 name: foo
551 alignment: 16
552 tracksRegLiveness: true
553 frameInfo:
554 maxAlignment: 16
555 machineFunctionInfo: {}
556 body: |
557 bb.0:
558 liveins: $r3
559 %0:gprc = COPY $r3
560 %0 = RLWIMI killed %0, $r3, 1, 0, 30
561 $r3 = COPY %0
562 BLR8 implicit $r3, implicit $lr8, implicit $rm
565 )MIR";
566 MachineModuleInfo MMI(TM.get());
567 M = parseMIR(*TM, MIRString, "foo", MMI);
568 ASSERT_TRUE(M);
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--"), "", "");
577 if (!TM)
578 GTEST_SKIP();
579 StringRef MIRString = R"MIR(
581 name: foo
582 alignment: 16
583 tracksRegLiveness: true
584 frameInfo:
585 maxAlignment: 16
586 machineFunctionInfo: {}
587 body: |
588 bb.0:
589 liveins: $r3
590 %0:gprc = COPY $r3
591 %1:gprc = RLWIMI killed %0, $r3, 1, 0, 30
592 $r3 = COPY %1
593 BLR8 implicit $r3, implicit $lr8, implicit $rm
596 )MIR";
597 MachineModuleInfo MMI(TM.get());
598 M = parseMIR(*TM, MIRString, "foo", MMI);
599 ASSERT_TRUE(M);
600 auto *MF = MMI.getMachineFunction(*M->getFunction("foo"));
601 MachineFunctionProperties &Properties = MF->getProperties();
602 ASSERT_FALSE(Properties.hasProperty(
603 MachineFunctionProperties::Property::TiedOpsRewritten));