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