brintos

brintos / llvm-project-archived public Read only

0
0
Text · 22.9 KiB · ab28963 Raw
617 lines · cpp
1//===- MachineInstrTest.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/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"33 34using namespace llvm;35 36namespace {37// Include helper functions to ease the manipulation of MachineFunctions.38#include "MFCommon.inc"39 40std::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);45}46 47// This test makes sure that MachineInstr::isIdenticalTo handles Defs correctly48// for various combinations of IgnoreDefs, and also that it is symmetrical.49TEST(IsIdenticalToTest, DifferentDefs) {50  LLVMContext Ctx;51  Module Mod("Module", Ctx);52  auto MF = createMachineFunction(Ctx, Mod);53 54  unsigned short NumOps = 2;55  unsigned char NumDefs = 1;56  struct {57    MCInstrDesc MCID;58    MCOperandInfo OpInfo[2];59  } Table = {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}}};63 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;68 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));72 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));76 77  // Check that they are identical when we ignore virtual register defs, but not78  // when we check defs.79  ASSERT_FALSE(MI1->isIdenticalTo(*MI2, MachineInstr::CheckDefs));80  ASSERT_FALSE(MI2->isIdenticalTo(*MI1, MachineInstr::CheckDefs));81 82  ASSERT_TRUE(MI1->isIdenticalTo(*MI2, MachineInstr::IgnoreVRegDefs));83  ASSERT_TRUE(MI2->isIdenticalTo(*MI1, MachineInstr::IgnoreVRegDefs));84 85  // Create two MIs with different virtual reg defs, and a def or use of a86  // sentinel register.87  unsigned SentinelReg = 0;88 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));92 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));96 97  // Check that they are never identical.98  ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::CheckDefs));99  ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::CheckDefs));100 101  ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::IgnoreVRegDefs));102  ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::IgnoreVRegDefs));103}104 105// Check that MachineInstrExpressionTrait::isEqual is symmetric and in sync with106// MachineInstrExpressionTrait::getHashValue107void checkHashAndIsEqualMatch(MachineInstr *MI1, MachineInstr *MI2) {108  bool IsEqual1 = MachineInstrExpressionTrait::isEqual(MI1, MI2);109  bool IsEqual2 = MachineInstrExpressionTrait::isEqual(MI2, MI1);110 111  ASSERT_EQ(IsEqual1, IsEqual2);112 113  auto Hash1 = MachineInstrExpressionTrait::getHashValue(MI1);114  auto Hash2 = MachineInstrExpressionTrait::getHashValue(MI2);115 116  ASSERT_EQ(IsEqual1, Hash1 == Hash2);117}118 119// This test makes sure that MachineInstrExpressionTraits::isEqual is in sync120// with MachineInstrExpressionTraits::getHashValue.121TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {122  LLVMContext Ctx;123  Module Mod("Module", Ctx);124  auto MF = createMachineFunction(Ctx, Mod);125 126  unsigned short NumOps = 2;127  unsigned char NumDefs = 1;128  struct {129    MCInstrDesc MCID;130    MCOperandInfo OpInfo[2];131  } Table = {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}}};135 136  // Define a series of instructions with different kinds of operands and make137  // sure that the hash function is consistent with isEqual for various138  // combinations of them.139  unsigned VirtualDef1 = -42;140  unsigned VirtualDef2 = -43;141  unsigned VirtualReg = -44;142  unsigned SentinelReg = 0;143  unsigned PhysicalReg = 45;144 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));150 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));156 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));162 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));168 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));174 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));180 181  checkHashAndIsEqualMatch(VD1VU, VD2VU);182  checkHashAndIsEqualMatch(VD1VU, VD1SU);183  checkHashAndIsEqualMatch(VD1VU, VD1SD);184  checkHashAndIsEqualMatch(VD1VU, VD2PU);185  checkHashAndIsEqualMatch(VD1VU, VD2PD);186 187  checkHashAndIsEqualMatch(VD2VU, VD1SU);188  checkHashAndIsEqualMatch(VD2VU, VD1SD);189  checkHashAndIsEqualMatch(VD2VU, VD2PU);190  checkHashAndIsEqualMatch(VD2VU, VD2PD);191 192  checkHashAndIsEqualMatch(VD1SU, VD1SD);193  checkHashAndIsEqualMatch(VD1SU, VD2PU);194  checkHashAndIsEqualMatch(VD1SU, VD2PD);195 196  checkHashAndIsEqualMatch(VD1SD, VD2PU);197  checkHashAndIsEqualMatch(VD1SD, VD2PD);198 199  checkHashAndIsEqualMatch(VD2PU, VD2PD);200}201 202TEST(MachineInstrPrintingTest, DebugLocPrinting) {203  LLVMContext Ctx;204  Module Mod("Module", Ctx);205  auto MF = createMachineFunction(Ctx, Mod);206 207  struct {208    MCInstrDesc MCID;209    MCOperandInfo OpInfo;210  } Table = {{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},211             {0, 0, MCOI::OPERAND_REGISTER, 0}};212 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);218  DebugLoc DL(DIL);219  MachineInstr *MI = MF->CreateMachineInstr(Table.MCID, DL);220  MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ true));221 222  std::string str;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"));228}229 230TEST(MachineInstrSpan, DistanceBegin) {231  LLVMContext Ctx;232  Module Mod("Module", Ctx);233  auto MF = createMachineFunction(Ctx, Mod);234  auto MBB = MF->CreateMachineBasicBlock();235 236  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};237 238  auto MII = MBB->begin();239  MachineInstrSpan MIS(MII, MBB);240  ASSERT_TRUE(MIS.empty());241 242  auto MI = MF->CreateMachineInstr(MCID, DebugLoc());243  MBB->insert(MII, MI);244  ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);245}246 247TEST(MachineInstrSpan, DistanceEnd) {248  LLVMContext Ctx;249  Module Mod("Module", Ctx);250  auto MF = createMachineFunction(Ctx, Mod);251  auto MBB = MF->CreateMachineBasicBlock();252 253  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};254 255  auto MII = MBB->end();256  MachineInstrSpan MIS(MII, MBB);257  ASSERT_TRUE(MIS.empty());258 259  auto MI = MF->CreateMachineInstr(MCID, DebugLoc());260  MBB->insert(MII, MI);261  ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);262}263 264TEST(MachineInstrExtraInfo, AddExtraInfo) {265  LLVMContext Ctx;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};269 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;276  MMOs.push_back(MMO);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");282 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());289 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());297 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());305 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());313 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());321 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());329 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);337 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);343}344 345TEST(MachineInstrExtraInfo, ChangeExtraInfo) {346  LLVMContext Ctx;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};350 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;357  MMOs.push_back(MMO);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, {});362 363  MDNode *MMRA1 = MMRAMetadata::getTagMD(Ctx, "foo", "bar");364  MDNode *MMRA2 = MMRAMetadata::getTagMD(Ctx, "bar", "bux");365 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);372 373  MMOs.push_back(MMO);374 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);382 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);390 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);398}399 400TEST(MachineInstrExtraInfo, RemoveExtraInfo) {401  LLVMContext Ctx;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};405 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;412  MMOs.push_back(MMO);413  MMOs.push_back(MMO);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, {});418 419  MDNode *MMRA = MDTuple::get(Ctx, {});420 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);427 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);435 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);443 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);451 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);459 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);467 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());475}476 477TEST(MachineInstrDebugValue, AddDebugValueOperand) {478  LLVMContext Ctx;479  Module Mod("Module", Ctx);480  auto MF = createMachineFunction(Ctx, Mod);481 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 = {487        Opcode, 0, 0, 0, 0,488        0,      0, 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),489        0};490 491    auto *MI = MF->CreateMachineInstr(MCID, DebugLoc());492    MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false));493 494    MI->addOperand(*MF, MachineOperand::CreateImm(0));495    MI->getOperand(1).ChangeToRegister(0, false);496 497    ASSERT_TRUE(MI->getOperand(0).isDebug());498    ASSERT_TRUE(MI->getOperand(1).isDebug());499  }500}501 502MATCHER_P(HasMIMetadata, MIMD, "") {503  return arg->getDebugLoc() == MIMD.getDL() &&504         arg->getPCSections() == MIMD.getPCSections();505}506 507TEST(MachineInstrBuilder, BuildMI) {508  LLVMContext Ctx;509  MDNode *PCS = MDNode::getDistinct(Ctx, {});510  MDNode *DI = MDNode::getDistinct(Ctx, {});511  DebugLoc DL(DI);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));528}529 530static_assert(std::is_trivially_copyable_v<MCOperand>, "trivially copyable");531 532TEST(MachineInstrTest, SpliceOperands) {533  LLVMContext Ctx;534  Module Mod("Module", Ctx);535  std::unique_ptr<MachineFunction> MF = createMachineFunction(Ctx, Mod);536  MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();537  MCInstrDesc MCID = {TargetOpcode::INLINEASM,538                      0,539                      0,540                      0,541                      0,542                      0,543                      0,544                      0,545                      0,546                      (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),547                      0};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));555 556  MI->removeOperand(1);557  EXPECT_EQ(MI->getOperand(1).getImm(), MachineOperand::CreateImm(2).getImm());558  EXPECT_EQ(MI->getNumOperands(), 4U);559 560  MachineOperand Ops[] = {561      MachineOperand::CreateImm(42),   MachineOperand::CreateImm(1024),562      MachineOperand::CreateImm(2048), MachineOperand::CreateImm(4096),563      MachineOperand::CreateImm(8192),564  };565  auto *It = MI->operands_begin();566  ++It;567  MI->insert(It, Ops);568 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());583 584  // test tied operands585  MCRegisterClass MRC{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, 0};588  // MachineRegisterInfo will be very upset if these registers aren't589  // allocatable.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);609 610  // bad inputs611  EXPECT_EQ(MI->getNumOperands(), 10U);612  MI->insert(MI->operands_begin(), {});613  EXPECT_EQ(MI->getNumOperands(), 10U);614}615 616} // end namespace617