brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.5 KiB · 8c36377 Raw
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