599 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 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/Module.h"24#include "llvm/IR/ModuleSlotTracker.h"25#include "llvm/MC/MCAsmInfo.h"26#include "llvm/MC/TargetRegistry.h"27#include "llvm/Support/SourceMgr.h"28#include "llvm/Support/TargetSelect.h"29#include "llvm/Target/TargetMachine.h"30#include "gtest/gtest.h"31 32using namespace llvm;33 34class MachineMetadataTest : public testing::Test {35public:36 MachineMetadataTest() = default;37 38protected:39 LLVMContext Context;40 std::unique_ptr<Module> M;41 std::unique_ptr<MIRParser> MIR;42 43 static void SetUpTestCase() {44 InitializeAllTargetInfos();45 InitializeAllTargets();46 InitializeAllTargetMCs();47 }48 49 void SetUp() override { M = std::make_unique<Module>("Dummy", Context); }50 51 void addHooks(ModuleSlotTracker &MST, const MachineOperand &MO) {52 // Setup hooks to assign slot numbers for the specified machine metadata.53 MST.setProcessHook([&MO](AbstractSlotTrackerStorage *AST, const Module *M,54 bool ShouldInitializeAllMetadata) {55 if (ShouldInitializeAllMetadata) {56 if (MO.isMetadata())57 AST->createMetadataSlot(MO.getMetadata());58 }59 });60 MST.setProcessHook([&MO](AbstractSlotTrackerStorage *AST, const Function *F,61 bool ShouldInitializeAllMetadata) {62 if (!ShouldInitializeAllMetadata) {63 if (MO.isMetadata())64 AST->createMetadataSlot(MO.getMetadata());65 }66 });67 }68 69 std::unique_ptr<TargetMachine>70 createTargetMachine(std::string TargetStr, StringRef CPU, StringRef FS) {71 Triple TT(TargetStr);72 std::string Error;73 const Target *T = TargetRegistry::lookupTarget(TT, Error);74 if (!T)75 return nullptr;76 TargetOptions Options;77 return std::unique_ptr<TargetMachine>(T->createTargetMachine(78 TT, CPU, FS, Options, std::nullopt, std::nullopt));79 }80 81 std::unique_ptr<Module> parseMIR(const TargetMachine &TM, StringRef MIRCode,82 MachineModuleInfo &MMI) {83 SMDiagnostic Diagnostic;84 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);85 MIR = createMIRParser(std::move(MBuffer), Context);86 if (!MIR)87 return nullptr;88 89 std::unique_ptr<Module> Mod = MIR->parseIRModule();90 if (!Mod)91 return nullptr;92 93 Mod->setDataLayout(TM.createDataLayout());94 95 if (MIR->parseMachineFunctions(*Mod, MMI)) {96 M.reset();97 return nullptr;98 }99 100 return Mod;101 }102};103 104// Helper to dump the printer output into a string.105static std::string print(std::function<void(raw_ostream &OS)> PrintFn) {106 std::string Str;107 raw_string_ostream OS(Str);108 PrintFn(OS);109 return Str;110}111 112TEST_F(MachineMetadataTest, TrivialHook) {113 // Verify that post-process hook is invoked to assign slot numbers for114 // machine metadata.115 ASSERT_TRUE(M);116 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);121 122 // Checking some preconditions on the newly created123 // MachineOperand.124 ASSERT_TRUE(MO.isMetadata());125 ASSERT_EQ(MO.getMetadata(), Node);126 127 ModuleSlotTracker MST(M.get());128 addHooks(MST, MO);129 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 }));137 // Print the definition of that metadata node.138 EXPECT_EQ("!0 = !{!\"foo\"}",139 print([&](raw_ostream &OS) { Node->print(OS, MST); }));140}141 142TEST_F(MachineMetadataTest, BasicHook) {143 // Verify that post-process hook is invoked to assign slot numbers for144 // machine metadata. When both LLVM IR and machine IR contain metadata,145 // ensure that machine metadata is always assigned after LLVM IR.146 ASSERT_TRUE(M);147 148 // Create a MachineOperand with a metadata and print it.149 Metadata *MachineMDS = MDString::get(Context, "foo");150 MDNode *MachineNode = MDNode::get(Context, MachineMDS);151 MachineOperand MO = MachineOperand::CreateMetadata(MachineNode);152 153 // Checking some preconditions on the newly created154 // MachineOperand.155 ASSERT_TRUE(MO.isMetadata());156 ASSERT_EQ(MO.getMetadata(), MachineNode);157 158 // Create metadata in LLVM IR.159 NamedMDNode *MD = M->getOrInsertNamedMetadata("namedmd");160 Metadata *MDS = MDString::get(Context, "bar");161 MDNode *Node = MDNode::get(Context, MDS);162 MD->addOperand(Node);163 164 ModuleSlotTracker MST(M.get());165 addHooks(MST, MO);166 167 // Print a MachineOperand containing a metadata node.168 EXPECT_EQ("!1", print([&](raw_ostream &OS) {169 MO.print(OS, MST, LLT{}, /*OpIdx*/ ~0U, /*PrintDef=*/false,170 /*IsStandalone=*/false,171 /*ShouldPrintRegisterTies=*/false, /*TiedOperandIdx=*/0,172 /*TRI=*/nullptr);173 }));174 // Print the definition of these unnamed metadata nodes.175 EXPECT_EQ("!0 = !{!\"bar\"}",176 print([&](raw_ostream &OS) { Node->print(OS, MST); }));177 EXPECT_EQ("!1 = !{!\"foo\"}",178 print([&](raw_ostream &OS) { MachineNode->print(OS, MST); }));179}180 181static bool checkOutput(std::string CheckString, std::string Output) {182 auto CheckBuffer = MemoryBuffer::getMemBuffer(CheckString, "");183 auto OutputBuffer = MemoryBuffer::getMemBuffer(Output, "Output", false);184 185 SmallString<4096> CheckFileBuffer;186 FileCheckRequest Req;187 FileCheck FC(Req);188 StringRef CheckFileText = FC.CanonicalizeFile(*CheckBuffer, CheckFileBuffer);189 190 SourceMgr SM;191 SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(CheckFileText, "CheckFile"),192 SMLoc());193 if (FC.readCheckFile(SM, CheckFileText))194 return false;195 196 auto OutBuffer = OutputBuffer->getBuffer();197 SM.AddNewSourceBuffer(std::move(OutputBuffer), SMLoc());198 return FC.checkInput(SM, OutBuffer);199}200 201TEST_F(MachineMetadataTest, MMSlotTrackerAArch64) {202 auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");203 if (!TM)204 GTEST_SKIP();205 206 StringRef MIRString = R"MIR(207--- |208 define i32 @test0(ptr %p) {209 %r = load i32, ptr %p, align 4210 ret i32 %r211 }212...213---214name: test0215liveins:216 - { reg: '$x0', virtual-reg: '%0' }217body: |218 bb.0 (%ir-block.0):219 liveins: $x0220 221 %0:gpr64common = COPY $x0222 %1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p)223...224)MIR";225 226 MachineModuleInfo MMI(TM.get());227 M = parseMIR(*TM, MIRString, MMI);228 ASSERT_TRUE(M);229 230 auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));231 auto *MBB = MF->getBlockNumbered(0);232 233 auto &MI = MBB->back();234 ASSERT_TRUE(MI.hasOneMemOperand());235 236 // Create and attached scoped AA metadata on that instruction with one MMO.237 MDBuilder MDB(Context);238 MDNode *Domain = MDB.createAnonymousAliasScopeDomain("domain");239 MDNode *Scope0 = MDB.createAnonymousAliasScope(Domain, "scope0");240 MDNode *Scope1 = MDB.createAnonymousAliasScope(Domain, "scope1");241 MDNode *Set0 = MDNode::get(Context, {Scope0});242 MDNode *Set1 = MDNode::get(Context, {Scope1});243 244 AAMDNodes AAInfo;245 AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;246 AAInfo.Scope = Set0;247 AAInfo.NoAlias = Set1;248 249 auto *OldMMO = MI.memoperands().front();250 auto *NewMMO = MF->getMachineMemOperand(OldMMO, AAInfo);251 MI.setMemRefs(*MF, NewMMO);252 253 MachineModuleSlotTracker MST(MMI, MF);254 // Print that MI with new machine metadata, which slot numbers should be255 // assigned.256 EXPECT_EQ("%1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p, "257 "!alias.scope !0, !noalias !3)",258 print([&](raw_ostream &OS) {259 MI.print(OS, MST, /*IsStandalone=*/false, /*SkipOpers=*/false,260 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);261 }));262 263 std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};264 // Examine machine metadata collected. They should match ones265 // afore-generated.266 std::vector<const MDNode *> Collected;267 MachineModuleSlotTracker::MachineMDNodeListType MDList;268 MST.collectMachineMDNodes(MDList);269 for (auto &MD : MDList)270 Collected.push_back(MD.second);271 272 llvm::sort(Generated);273 llvm::sort(Collected);274 EXPECT_EQ(Collected, Generated);275 276 // FileCheck the output from MIR printer.277 std::string Output = print([&](raw_ostream &OS) { printMIR(OS, MMI, *MF); });278 std::string CheckString = R"(279CHECK: machineMetadataNodes:280CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain"}281CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0"}282CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1"}283CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}284CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}285CHECK: body:286CHECK: %1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p, !alias.scope ![[MMSET0]], !noalias ![[MMSET1]])287)";288 EXPECT_TRUE(checkOutput(CheckString, Output));289}290 291TEST_F(MachineMetadataTest, isMetaInstruction) {292 auto TM = createTargetMachine(Triple::normalize("x86_64--"), "", "");293 if (!TM)294 GTEST_SKIP();295 296 StringRef MIRString = R"MIR(297--- |298 define void @test0(i32 %b) {299 ret void300 }301 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)302 !1 = !DIFile(filename: "a.c", directory: "/tmp")303 !2 = !{i32 7, !"Dwarf Version", i32 4}304 !3 = !{i32 2, !"Debug Info Version", i32 3}305 !4 = !{i32 1, !"wchar_size", i32 4}306 !5 = !{i32 7, !"uwtable", i32 1}307 !6 = !{i32 7, !"frame-pointer", i32 2}308 !7 = !{!""}309 !8 = distinct !DISubprogram(name: "test0", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)310 !9 = !DISubroutineType(types: !10)311 !10 = !{null, !11}312 !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)313 !12 = !{}314 !13 = !DILocalVariable(name: "b", arg: 1, scope: !8, file: !1, line: 1, type: !11)315 !14 = !DILocation(line: 1, column: 16, scope: !8)316...317---318name: test0319machineFunctionInfo320body: |321 bb.0:322 $rdi = IMPLICIT_DEF323 KILL $rsi324 CFI_INSTRUCTION undefined $rax325 EH_LABEL 0326 GC_LABEL 0327 DBG_VALUE $rax, $noreg, !13, !DIExpression(), debug-location !14328 DBG_LABEL 0329 LIFETIME_START 0330 LIFETIME_END 0331 PSEUDO_PROBE 6699318081062747564, 1, 0, 0332 $xmm0 = ARITH_FENCE $xmm0333 MEMBARRIER334...335)MIR";336 337 MachineModuleInfo MMI(TM.get());338 M = parseMIR(*TM, MIRString, MMI);339 ASSERT_TRUE(M);340 341 auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));342 auto *MBB = MF->getBlockNumbered(0);343 344 for (auto It = MBB->begin(); It != MBB->end(); ++It) {345 MachineInstr &MI = *It;346 ASSERT_TRUE(MI.isMetaInstruction());347 }348}349 350TEST_F(MachineMetadataTest, MMSlotTrackerX64) {351 auto TM = createTargetMachine(Triple::normalize("x86_64--"), "", "");352 if (!TM)353 GTEST_SKIP();354 355 StringRef MIRString = R"MIR(356--- |357 define i32 @test0(ptr %p) {358 %r = load i32, ptr %p, align 4359 ret i32 %r360 }361...362---363name: test0364liveins:365 - { reg: '$rdi', virtual-reg: '%0' }366body: |367 bb.0 (%ir-block.0):368 liveins: $rdi369 370 %0:gr64 = COPY $rdi371 %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p)372...373)MIR";374 375 MachineModuleInfo MMI(TM.get());376 M = parseMIR(*TM, MIRString, MMI);377 ASSERT_TRUE(M);378 379 auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));380 auto *MBB = MF->getBlockNumbered(0);381 382 auto &MI = MBB->back();383 ASSERT_FALSE(MI.memoperands_empty());384 ASSERT_TRUE(MI.hasOneMemOperand());385 386 // Create and attached scoped AA metadata on that instruction with one MMO.387 MDBuilder MDB(Context);388 MDNode *Domain = MDB.createAnonymousAliasScopeDomain("domain");389 MDNode *Scope0 = MDB.createAnonymousAliasScope(Domain, "scope0");390 MDNode *Scope1 = MDB.createAnonymousAliasScope(Domain, "scope1");391 MDNode *Set0 = MDNode::get(Context, {Scope0});392 MDNode *Set1 = MDNode::get(Context, {Scope1});393 394 AAMDNodes AAInfo;395 AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;396 AAInfo.Scope = Set0;397 AAInfo.NoAlias = Set1;398 399 auto *OldMMO = MI.memoperands().front();400 auto *NewMMO = MF->getMachineMemOperand(OldMMO, AAInfo);401 MI.setMemRefs(*MF, NewMMO);402 403 MachineModuleSlotTracker MST(MMI, MF);404 // Print that MI with new machine metadata, which slot numbers should be405 // assigned.406 EXPECT_EQ("%1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, "407 "!alias.scope !0, !noalias !3)",408 print([&](raw_ostream &OS) {409 MI.print(OS, MST, /*IsStandalone=*/false, /*SkipOpers=*/false,410 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);411 }));412 413 std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};414 // Examine machine metadata collected. They should match ones415 // afore-generated.416 std::vector<const MDNode *> Collected;417 MachineModuleSlotTracker::MachineMDNodeListType MDList;418 MST.collectMachineMDNodes(MDList);419 for (auto &MD : MDList)420 Collected.push_back(MD.second);421 422 llvm::sort(Generated);423 llvm::sort(Collected);424 EXPECT_EQ(Collected, Generated);425 426 // FileCheck the output from MIR printer.427 std::string Output = print([&](raw_ostream &OS) { printMIR(OS, MMI, *MF); });428 std::string CheckString = R"(429CHECK: machineMetadataNodes:430CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain"}431CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0"}432CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1"}433CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}434CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}435CHECK: body:436CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, !alias.scope ![[MMSET0]], !noalias ![[MMSET1]])437)";438 EXPECT_TRUE(checkOutput(CheckString, Output));439}440 441TEST_F(MachineMetadataTest, MMSlotTrackerAMDGPU) {442 auto TM = createTargetMachine(Triple::normalize("amdgcn-amd-amdhsa"),443 "gfx1010", "");444 if (!TM)445 GTEST_SKIP();446 447 StringRef MIRString = R"MIR(448--- |449 define i32 @test0(ptr %p) {450 %r = load i32, ptr %p, align 4451 ret i32 %r452 }453...454---455name: test0456liveins:457 - { reg: '$vgpr0', virtual-reg: '%0' }458 - { reg: '$vgpr1', virtual-reg: '%1' }459 - { reg: '$sgpr30_sgpr31', virtual-reg: '%2' }460body: |461 bb.0 (%ir-block.0):462 liveins: $vgpr0, $vgpr1, $sgpr30_sgpr31463 464 %2:sreg_64 = COPY $sgpr30_sgpr31465 %1:vgpr_32 = COPY $vgpr1466 %0:vgpr_32 = COPY $vgpr0467 %8:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1468 %6:vreg_64 = COPY %8469 %5:vgpr_32 = FLAT_LOAD_DWORD killed %6, 0, 0, implicit $exec, implicit $flat_scr :: (load (s32) from %ir.p)470...471)MIR";472 473 MachineModuleInfo MMI(TM.get());474 M = parseMIR(*TM, MIRString, MMI);475 ASSERT_TRUE(M);476 477 auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));478 auto *MBB = MF->getBlockNumbered(0);479 480 auto &MI = MBB->back();481 ASSERT_FALSE(MI.memoperands_empty());482 ASSERT_TRUE(MI.hasOneMemOperand());483 484 // Create and attached scoped AA metadata on that instruction with one MMO.485 MDBuilder MDB(Context);486 MDNode *Domain = MDB.createAnonymousAliasScopeDomain("domain");487 MDNode *Scope0 = MDB.createAnonymousAliasScope(Domain, "scope0");488 MDNode *Scope1 = MDB.createAnonymousAliasScope(Domain, "scope1");489 MDNode *Set0 = MDNode::get(Context, {Scope0});490 MDNode *Set1 = MDNode::get(Context, {Scope1});491 492 AAMDNodes AAInfo;493 AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;494 AAInfo.Scope = Set0;495 AAInfo.NoAlias = Set1;496 497 auto *OldMMO = MI.memoperands().front();498 auto *NewMMO = MF->getMachineMemOperand(OldMMO, AAInfo);499 MI.setMemRefs(*MF, NewMMO);500 501 MachineModuleSlotTracker MST(MMI, MF);502 // Print that MI with new machine metadata, which slot numbers should be503 // assigned.504 EXPECT_EQ(505 "%5:vgpr_32 = FLAT_LOAD_DWORD killed %4, 0, 0, implicit $exec, implicit "506 "$flat_scr :: (load (s32) from %ir.p, !alias.scope !0, !noalias !3)",507 print([&](raw_ostream &OS) {508 MI.print(OS, MST, /*IsStandalone=*/false, /*SkipOpers=*/false,509 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);510 }));511 512 std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};513 // Examine machine metadata collected. They should match ones514 // afore-generated.515 std::vector<const MDNode *> Collected;516 MachineModuleSlotTracker::MachineMDNodeListType MDList;517 MST.collectMachineMDNodes(MDList);518 for (auto &MD : MDList)519 Collected.push_back(MD.second);520 521 llvm::sort(Generated);522 llvm::sort(Collected);523 EXPECT_EQ(Collected, Generated);524 525 // FileCheck the output from MIR printer.526 std::string Output = print([&](raw_ostream &OS) { printMIR(OS, MMI, *MF); });527 std::string CheckString = R"(528CHECK: machineMetadataNodes:529CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain"}530CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0"}531CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1"}532CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}533CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}534CHECK: body:535CHECK: %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]])536)";537 EXPECT_TRUE(checkOutput(CheckString, Output));538}539 540TEST_F(MachineMetadataTest, TiedOpsRewritten) {541 auto TM = createTargetMachine(Triple::normalize("powerpc64--"), "", "");542 if (!TM)543 GTEST_SKIP();544 StringRef MIRString = R"MIR(545---546name: foo547alignment: 16548tracksRegLiveness: true549frameInfo:550 maxAlignment: 16551machineFunctionInfo: {}552body: |553 bb.0:554 liveins: $r3555 %0:gprc = COPY $r3556 %0 = RLWIMI killed %0, $r3, 1, 0, 30557 $r3 = COPY %0558 BLR8 implicit $r3, implicit $lr8, implicit $rm559 560...561)MIR";562 MachineModuleInfo MMI(TM.get());563 M = parseMIR(*TM, MIRString, MMI);564 ASSERT_TRUE(M);565 auto *MF = MMI.getMachineFunction(*M->getFunction("foo"));566 MachineFunctionProperties &Properties = MF->getProperties();567 ASSERT_TRUE(Properties.hasTiedOpsRewritten());568}569 570TEST_F(MachineMetadataTest, NoTiedOpsRewritten) {571 auto TM = createTargetMachine(Triple::normalize("powerpc64--"), "", "");572 if (!TM)573 GTEST_SKIP();574 StringRef MIRString = R"MIR(575---576name: foo577alignment: 16578tracksRegLiveness: true579frameInfo:580 maxAlignment: 16581machineFunctionInfo: {}582body: |583 bb.0:584 liveins: $r3585 %0:gprc = COPY $r3586 %1:gprc = RLWIMI killed %0, $r3, 1, 0, 30587 $r3 = COPY %1588 BLR8 implicit $r3, implicit $lr8, implicit $rm589 590...591)MIR";592 MachineModuleInfo MMI(TM.get());593 M = parseMIR(*TM, MIRString, MMI);594 ASSERT_TRUE(M);595 auto *MF = MMI.getMachineFunction(*M->getFunction("foo"));596 MachineFunctionProperties &Properties = MF->getProperties();597 ASSERT_FALSE(Properties.hasTiedOpsRewritten());598}599