brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.6 KiB · 0373c7a Raw
448 lines · cpp
1//===- MachineOperandTest.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/MachineOperand.h"10#include "llvm/ADT/ilist_node.h"11#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"12#include "llvm/CodeGen/MachineFunction.h"13#include "llvm/CodeGen/MachineModuleInfo.h"14#include "llvm/CodeGen/TargetFrameLowering.h"15#include "llvm/CodeGen/TargetInstrInfo.h"16#include "llvm/CodeGen/TargetLowering.h"17#include "llvm/CodeGenTypes/LowLevelType.h"18#include "llvm/IR/Constants.h"19#include "llvm/IR/InstrTypes.h"20#include "llvm/IR/LLVMContext.h"21#include "llvm/IR/Module.h"22#include "llvm/IR/ModuleSlotTracker.h"23#include "llvm/MC/MCAsmInfo.h"24#include "llvm/MC/MCContext.h"25#include "llvm/MC/TargetRegistry.h"26#include "llvm/Support/raw_ostream.h"27#include "gtest/gtest.h"28 29using namespace llvm;30 31namespace {32 33// Include helper functions to ease the manipulation of MachineFunctions.34#include "MFCommon.inc"35 36TEST(MachineOperandTest, ChangeToTargetIndexTest) {37  // Creating a MachineOperand to change it to TargetIndex38  MachineOperand MO = MachineOperand::CreateImm(50);39 40  // Checking some precondition on the newly created41  // MachineOperand.42  ASSERT_TRUE(MO.isImm());43  ASSERT_TRUE(MO.getImm() == 50);44  ASSERT_FALSE(MO.isTargetIndex());45 46  // Changing to TargetIndex with some arbitrary values47  // for index, offset and flags.48  MO.ChangeToTargetIndex(74, 57, 12);49 50  // Checking that the mutation to TargetIndex happened51  // correctly.52  ASSERT_TRUE(MO.isTargetIndex());53  ASSERT_TRUE(MO.getIndex() == 74);54  ASSERT_TRUE(MO.getOffset() == 57);55  ASSERT_TRUE(MO.getTargetFlags() == 12);56}57 58TEST(MachineOperandTest, PrintRegisterMask) {59  LLVMContext Ctx;60  Module Mod("Module", Ctx);61  auto MF = createMachineFunction(Ctx, Mod);62 63  uint32_t *Dummy = MF->allocateRegMask();64  MachineOperand MO = MachineOperand::CreateRegMask(Dummy);65 66  // Checking some preconditions on the newly created67  // MachineOperand.68  ASSERT_TRUE(MO.isRegMask());69  ASSERT_TRUE(MO.getRegMask() == Dummy);70 71  // Print a MachineOperand containing a RegMask. Here we check that without a72  // TRI we still print a less detailed regmask.73  std::string str;74  raw_string_ostream OS(str);75  MO.print(OS, /*TRI=*/nullptr);76  ASSERT_TRUE(str == "<regmask ...>");77}78 79TEST(MachineOperandTest, PrintSubReg) {80  // Create a MachineOperand with RegNum=1 and SubReg=5.81  MachineOperand MO = MachineOperand::CreateReg(82      /*Reg=*/1, /*isDef=*/false, /*isImp=*/false, /*isKill=*/false,83      /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/false,84      /*SubReg=*/5, /*isDebug=*/false, /*isInternalRead=*/false);85 86  // Checking some preconditions on the newly created87  // MachineOperand.88  ASSERT_TRUE(MO.isReg());89  ASSERT_TRUE(MO.getReg() == 1);90  ASSERT_TRUE(MO.getSubReg() == 5);91 92  // Print a MachineOperand containing a SubReg. Here we check that without a93  // TRI we can still print the subreg index.94  std::string str;95  raw_string_ostream OS(str);96  MO.print(OS, /*TRI=*/nullptr);97  ASSERT_TRUE(str == "$physreg1.subreg5");98}99 100TEST(MachineOperandTest, PrintCImm) {101  LLVMContext Context;102  APInt Int(128, UINT64_MAX);103  ++Int;104  ConstantInt *CImm = ConstantInt::get(Context, Int);105  // Create a MachineOperand with an Imm=(UINT64_MAX + 1)106  MachineOperand MO = MachineOperand::CreateCImm(CImm);107 108  // Checking some preconditions on the newly created109  // MachineOperand.110  ASSERT_TRUE(MO.isCImm());111  ASSERT_TRUE(MO.getCImm() == CImm);112  ASSERT_TRUE(MO.getCImm()->getValue() == Int);113 114  // Print a MachineOperand containing a SubReg. Here we check that without a115  // TRI we can still print the subreg index.116  std::string str;117  raw_string_ostream OS(str);118  MO.print(OS, /*TRI=*/nullptr);119  ASSERT_TRUE(str == "i128 18446744073709551616");120}121 122TEST(MachineOperandTest, PrintSubRegIndex) {123  // Create a MachineOperand with an immediate and print it as a subreg index.124  MachineOperand MO = MachineOperand::CreateImm(3);125 126  // Checking some preconditions on the newly created127  // MachineOperand.128  ASSERT_TRUE(MO.isImm());129  ASSERT_TRUE(MO.getImm() == 3);130 131  // Print a MachineOperand containing a SubRegIdx. Here we check that without a132  // TRI we can print the operand as a subreg index.133  std::string str;134  raw_string_ostream OS(str);135  MachineOperand::printSubRegIdx(OS, MO.getImm(), nullptr);136  ASSERT_TRUE(str == "%subreg.3");137}138 139TEST(MachineOperandTest, PrintCPI) {140  // Create a MachineOperand with a constant pool index and print it.141  MachineOperand MO = MachineOperand::CreateCPI(0, 8);142 143  // Checking some preconditions on the newly created144  // MachineOperand.145  ASSERT_TRUE(MO.isCPI());146  ASSERT_TRUE(MO.getIndex() == 0);147  ASSERT_TRUE(MO.getOffset() == 8);148 149  // Print a MachineOperand containing a constant pool index and a positive150  // offset.151  std::string str;152  {153    raw_string_ostream OS(str);154    MO.print(OS, /*TRI=*/nullptr);155    ASSERT_TRUE(str == "%const.0 + 8");156  }157 158  str.clear();159 160  MO.setOffset(-12);161 162  // Print a MachineOperand containing a constant pool index and a negative163  // offset.164  {165    raw_string_ostream OS(str);166    MO.print(OS, /*TRI=*/nullptr);167    ASSERT_TRUE(str == "%const.0 - 12");168  }169}170 171TEST(MachineOperandTest, PrintTargetIndexName) {172  // Create a MachineOperand with a target index and print it.173  MachineOperand MO = MachineOperand::CreateTargetIndex(0, 8);174 175  // Checking some preconditions on the newly created176  // MachineOperand.177  ASSERT_TRUE(MO.isTargetIndex());178  ASSERT_TRUE(MO.getIndex() == 0);179  ASSERT_TRUE(MO.getOffset() == 8);180 181  // Print a MachineOperand containing a target index and a positive offset.182  std::string str;183  {184    raw_string_ostream OS(str);185    MO.print(OS, /*TRI=*/nullptr);186    ASSERT_TRUE(str == "target-index(<unknown>) + 8");187  }188 189  str.clear();190 191  MO.setOffset(-12);192 193  // Print a MachineOperand containing a target index and a negative offset.194  {195    raw_string_ostream OS(str);196    MO.print(OS, /*TRI=*/nullptr);197    ASSERT_TRUE(str == "target-index(<unknown>) - 12");198  }199}200 201TEST(MachineOperandTest, PrintJumpTableIndex) {202  // Create a MachineOperand with a jump-table index and print it.203  MachineOperand MO = MachineOperand::CreateJTI(3);204 205  // Checking some preconditions on the newly created206  // MachineOperand.207  ASSERT_TRUE(MO.isJTI());208  ASSERT_TRUE(MO.getIndex() == 3);209 210  // Print a MachineOperand containing a jump-table index.211  std::string str;212  raw_string_ostream OS(str);213  MO.print(OS, /*TRI=*/nullptr);214  ASSERT_TRUE(str == "%jump-table.3");215}216 217TEST(MachineOperandTest, PrintExternalSymbol) {218  // Create a MachineOperand with an external symbol and print it.219  MachineOperand MO = MachineOperand::CreateES("foo");220 221  // Checking some preconditions on the newly created222  // MachineOperand.223  ASSERT_TRUE(MO.isSymbol());224  ASSERT_TRUE(MO.getSymbolName() == StringRef("foo"));225 226  // Print a MachineOperand containing an external symbol and no offset.227  std::string str;228  {229    raw_string_ostream OS(str);230    MO.print(OS, /*TRI=*/nullptr);231    ASSERT_TRUE(str == "&foo");232  }233 234  str.clear();235  MO.setOffset(12);236 237  // Print a MachineOperand containing an external symbol and a positive offset.238  {239    raw_string_ostream OS(str);240    MO.print(OS, /*TRI=*/nullptr);241    ASSERT_TRUE(str == "&foo + 12");242  }243 244  str.clear();245  MO.setOffset(-12);246 247  // Print a MachineOperand containing an external symbol and a negative offset.248  {249    raw_string_ostream OS(str);250    MO.print(OS, /*TRI=*/nullptr);251    ASSERT_TRUE(str == "&foo - 12");252  }253}254 255TEST(MachineOperandTest, PrintGlobalAddress) {256  LLVMContext Ctx;257  Module M("MachineOperandGVTest", Ctx);258  M.getOrInsertGlobal("foo", Type::getInt32Ty(Ctx));259 260  GlobalValue *GV = M.getNamedValue("foo");261 262  // Create a MachineOperand with a global address and a positive offset and263  // print it.264  MachineOperand MO = MachineOperand::CreateGA(GV, 12);265 266  // Checking some preconditions on the newly created267  // MachineOperand.268  ASSERT_TRUE(MO.isGlobal());269  ASSERT_TRUE(MO.getGlobal() == GV);270  ASSERT_TRUE(MO.getOffset() == 12);271 272  std::string str;273  // Print a MachineOperand containing a global address and a positive offset.274  {275    raw_string_ostream OS(str);276    MO.print(OS, /*TRI=*/nullptr);277    ASSERT_TRUE(str == "@foo + 12");278  }279 280  str.clear();281  MO.setOffset(-12);282 283  // Print a MachineOperand containing a global address and a negative offset.284  {285    raw_string_ostream OS(str);286    MO.print(OS, /*TRI=*/nullptr);287    ASSERT_TRUE(str == "@foo - 12");288  }289}290 291TEST(MachineOperandTest, PrintRegisterLiveOut) {292  // Create a MachineOperand with a register live out list and print it.293  uint32_t Mask = 0;294  MachineOperand MO = MachineOperand::CreateRegLiveOut(&Mask);295 296  // Checking some preconditions on the newly created297  // MachineOperand.298  ASSERT_TRUE(MO.isRegLiveOut());299  ASSERT_TRUE(MO.getRegLiveOut() == &Mask);300 301  std::string str;302  // Print a MachineOperand containing a register live out list without a TRI.303  raw_string_ostream OS(str);304  MO.print(OS, /*TRI=*/nullptr);305  ASSERT_TRUE(str == "liveout(<unknown>)");306}307 308TEST(MachineOperandTest, PrintMetadata) {309  LLVMContext Ctx;310  Module M("MachineOperandMDNodeTest", Ctx);311  NamedMDNode *MD = M.getOrInsertNamedMetadata("namedmd");312  ModuleSlotTracker MST(&M);313  Metadata *MDS = MDString::get(Ctx, "foo");314  MDNode *Node = MDNode::get(Ctx, MDS);315  MD->addOperand(Node);316 317  // Create a MachineOperand with a metadata and print it.318  MachineOperand MO = MachineOperand::CreateMetadata(Node);319 320  // Checking some preconditions on the newly created321  // MachineOperand.322  ASSERT_TRUE(MO.isMetadata());323  ASSERT_TRUE(MO.getMetadata() == Node);324 325  std::string str;326  // Print a MachineOperand containing a metadata node.327  raw_string_ostream OS(str);328  MO.print(OS, MST, LLT{}, /*OpIdx*/ ~0U, /*PrintDef=*/false,329           /*IsStandalone=*/false,330           /*ShouldPrintRegisterTies=*/false, 0, /*TRI=*/nullptr);331  ASSERT_TRUE(str == "!0");332}333 334TEST(MachineOperandTest, PrintMCSymbol) {335  MCAsmInfo MAI;336  Triple T = Triple("unknown-unknown-unknown");337  MCContext Ctx(T, &MAI, /*MRI=*/nullptr, /*MSTI=*/nullptr);338  MCSymbol *Sym = Ctx.getOrCreateSymbol("foo");339 340  // Create a MachineOperand with a metadata and print it.341  MachineOperand MO = MachineOperand::CreateMCSymbol(Sym);342 343  // Checking some preconditions on the newly created344  // MachineOperand.345  ASSERT_TRUE(MO.isMCSymbol());346  ASSERT_TRUE(MO.getMCSymbol() == Sym);347 348  std::string str;349  // Print a MachineOperand containing a metadata node.350  raw_string_ostream OS(str);351  MO.print(OS, /*TRI=*/nullptr);352  ASSERT_TRUE(str == "<mcsymbol foo>");353}354 355TEST(MachineOperandTest, PrintCFI) {356  // Create a MachineOperand with a CFI index but no function and print it.357  MachineOperand MO = MachineOperand::CreateCFIIndex(8);358 359  // Checking some preconditions on the newly created360  // MachineOperand.361  ASSERT_TRUE(MO.isCFIIndex());362  ASSERT_TRUE(MO.getCFIIndex() == 8);363 364  std::string str;365  // Print a MachineOperand containing a CFI Index node but no machine function366  // attached to it.367  raw_string_ostream OS(str);368  MO.print(OS, /*TRI=*/nullptr);369  ASSERT_TRUE(str == "<cfi directive>");370}371 372TEST(MachineOperandTest, PrintIntrinsicID) {373  // Create a MachineOperand with a generic intrinsic ID.374  MachineOperand MO = MachineOperand::CreateIntrinsicID(Intrinsic::bswap);375 376  // Checking some preconditions on the newly created377  // MachineOperand.378  ASSERT_TRUE(MO.isIntrinsicID());379  ASSERT_TRUE(MO.getIntrinsicID() == Intrinsic::bswap);380 381  std::string str;382  {383    // Print a MachineOperand containing a generic intrinsic ID.384    raw_string_ostream OS(str);385    MO.print(OS, /*TRI=*/nullptr);386    ASSERT_TRUE(str == "intrinsic(@llvm.bswap)");387  }388 389  str.clear();390  // Set a target-specific intrinsic.391  MO = MachineOperand::CreateIntrinsicID((Intrinsic::ID)-1);392  {393    // Print a MachineOperand containing a target-specific intrinsic ID but not394    // IntrinsicInfo.395    raw_string_ostream OS(str);396    MO.print(OS, /*TRI=*/nullptr);397    ASSERT_TRUE(str == "intrinsic(4294967295)");398  }399}400 401TEST(MachineOperandTest, PrintPredicate) {402  // Create a MachineOperand with a generic intrinsic ID.403  MachineOperand MO = MachineOperand::CreatePredicate(CmpInst::ICMP_EQ);404 405  // Checking some preconditions on the newly created406  // MachineOperand.407  ASSERT_TRUE(MO.isPredicate());408  ASSERT_TRUE(MO.getPredicate() == CmpInst::ICMP_EQ);409 410  std::string str;411  // Print a MachineOperand containing a int predicate ICMP_EQ.412  raw_string_ostream OS(str);413  MO.print(OS, /*TRI=*/nullptr);414  ASSERT_TRUE(str == "intpred(eq)");415}416 417TEST(MachineOperandTest, HashValue) {418  char SymName1[] = "test";419  char SymName2[] = "test";420  MachineOperand MO1 = MachineOperand::CreateES(SymName1);421  MachineOperand MO2 = MachineOperand::CreateES(SymName2);422  ASSERT_NE(SymName1, SymName2);423  ASSERT_EQ(hash_value(MO1), hash_value(MO2));424  ASSERT_TRUE(MO1.isIdenticalTo(MO2));425}426 427TEST(MachineOperandTest, RegisterLiveOutHashValue) {428  LLVMContext Ctx;429  Module Mod("Module", Ctx);430  auto MF = createMachineFunction(Ctx, Mod);431  MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();432  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};433  auto *MI1 = MF->CreateMachineInstr(MCID, DebugLoc());434  auto *MI2 = MF->CreateMachineInstr(MCID, DebugLoc());435  MBB->insert(MBB->begin(), MI1);436  MBB->insert(MBB->begin(), MI2);437  uint32_t Mask1 = 0;438  uint32_t Mask2 = 0;439  MI1->addOperand(*MF, MachineOperand::CreateRegLiveOut(&Mask1));440  MI2->addOperand(*MF, MachineOperand::CreateRegLiveOut(&Mask2));441  auto MO1 = MI1->getOperand(0);442  auto MO2 = MI2->getOperand(0);443  EXPECT_EQ(hash_value(MO1), hash_value(MO2));444  EXPECT_TRUE(MO1.isIdenticalTo(MO2));445}446 447} // end namespace448