1 //===- MachineOperandTest.cpp ---------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/CodeGen/MachineOperand.h" 11 #include "llvm/ADT/ilist_node.h" 12 #include "llvm/IR/Constants.h" 13 #include "llvm/IR/LLVMContext.h" 14 #include "llvm/IR/Module.h" 15 #include "llvm/IR/ModuleSlotTracker.h" 16 #include "llvm/Support/raw_ostream.h" 17 #include "gtest/gtest.h" 18 19 using namespace llvm; 20 21 namespace { 22 23 TEST(MachineOperandTest, ChangeToTargetIndexTest) { 24 // Creating a MachineOperand to change it to TargetIndex 25 MachineOperand MO = MachineOperand::CreateImm(50); 26 27 // Checking some precondition on the newly created 28 // MachineOperand. 29 ASSERT_TRUE(MO.isImm()); 30 ASSERT_TRUE(MO.getImm() == 50); 31 ASSERT_FALSE(MO.isTargetIndex()); 32 33 // Changing to TargetIndex with some arbitrary values 34 // for index, offset and flags. 35 MO.ChangeToTargetIndex(74, 57, 12); 36 37 // Checking that the mutation to TargetIndex happened 38 // correctly. 39 ASSERT_TRUE(MO.isTargetIndex()); 40 ASSERT_TRUE(MO.getIndex() == 74); 41 ASSERT_TRUE(MO.getOffset() == 57); 42 ASSERT_TRUE(MO.getTargetFlags() == 12); 43 } 44 45 TEST(MachineOperandTest, PrintRegisterMask) { 46 uint32_t Dummy; 47 MachineOperand MO = MachineOperand::CreateRegMask(&Dummy); 48 49 // Checking some preconditions on the newly created 50 // MachineOperand. 51 ASSERT_TRUE(MO.isRegMask()); 52 ASSERT_TRUE(MO.getRegMask() == &Dummy); 53 54 // Print a MachineOperand containing a RegMask. Here we check that without a 55 // TRI and IntrinsicInfo we still print a less detailed regmask. 56 std::string str; 57 raw_string_ostream OS(str); 58 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 59 ASSERT_TRUE(OS.str() == "<regmask ...>"); 60 } 61 62 TEST(MachineOperandTest, PrintSubReg) { 63 // Create a MachineOperand with RegNum=1 and SubReg=5. 64 MachineOperand MO = MachineOperand::CreateReg( 65 /*Reg=*/1, /*isDef=*/false, /*isImp=*/false, /*isKill=*/false, 66 /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/false, 67 /*SubReg=*/5, /*isDebug=*/false, /*isInternalRead=*/false); 68 69 // Checking some preconditions on the newly created 70 // MachineOperand. 71 ASSERT_TRUE(MO.isReg()); 72 ASSERT_TRUE(MO.getReg() == 1); 73 ASSERT_TRUE(MO.getSubReg() == 5); 74 75 // Print a MachineOperand containing a SubReg. Here we check that without a 76 // TRI and IntrinsicInfo we can still print the subreg index. 77 std::string str; 78 raw_string_ostream OS(str); 79 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 80 ASSERT_TRUE(OS.str() == "%physreg1.subreg5"); 81 } 82 83 TEST(MachineOperandTest, PrintCImm) { 84 LLVMContext Context; 85 APInt Int(128, UINT64_MAX); 86 ++Int; 87 ConstantInt *CImm = ConstantInt::get(Context, Int); 88 // Create a MachineOperand with an Imm=(UINT64_MAX + 1) 89 MachineOperand MO = MachineOperand::CreateCImm(CImm); 90 91 // Checking some preconditions on the newly created 92 // MachineOperand. 93 ASSERT_TRUE(MO.isCImm()); 94 ASSERT_TRUE(MO.getCImm() == CImm); 95 ASSERT_TRUE(MO.getCImm()->getValue() == Int); 96 97 // Print a MachineOperand containing a SubReg. Here we check that without a 98 // TRI and IntrinsicInfo we can still print the subreg index. 99 std::string str; 100 raw_string_ostream OS(str); 101 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 102 ASSERT_TRUE(OS.str() == "i128 18446744073709551616"); 103 } 104 105 TEST(MachineOperandTest, PrintSubRegIndex) { 106 // Create a MachineOperand with an immediate and print it as a subreg index. 107 MachineOperand MO = MachineOperand::CreateImm(3); 108 109 // Checking some preconditions on the newly created 110 // MachineOperand. 111 ASSERT_TRUE(MO.isImm()); 112 ASSERT_TRUE(MO.getImm() == 3); 113 114 // Print a MachineOperand containing a SubRegIdx. Here we check that without a 115 // TRI and IntrinsicInfo we can print the operand as a subreg index. 116 std::string str; 117 raw_string_ostream OS(str); 118 ModuleSlotTracker DummyMST(nullptr); 119 MachineOperand::printSubregIdx(OS, MO.getImm(), nullptr); 120 ASSERT_TRUE(OS.str() == "%subreg.3"); 121 } 122 123 TEST(MachineOperandTest, PrintCPI) { 124 // Create a MachineOperand with a constant pool index and print it. 125 MachineOperand MO = MachineOperand::CreateCPI(0, 8); 126 127 // Checking some preconditions on the newly created 128 // MachineOperand. 129 ASSERT_TRUE(MO.isCPI()); 130 ASSERT_TRUE(MO.getIndex() == 0); 131 ASSERT_TRUE(MO.getOffset() == 8); 132 133 // Print a MachineOperand containing a constant pool index and a positive 134 // offset. 135 std::string str; 136 { 137 raw_string_ostream OS(str); 138 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 139 ASSERT_TRUE(OS.str() == "%const.0 + 8"); 140 } 141 142 str.clear(); 143 144 MO.setOffset(-12); 145 146 // Print a MachineOperand containing a constant pool index and a negative 147 // offset. 148 { 149 raw_string_ostream OS(str); 150 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 151 ASSERT_TRUE(OS.str() == "%const.0 - 12"); 152 } 153 } 154 155 TEST(MachineOperandTest, PrintTargetIndexName) { 156 // Create a MachineOperand with a target index and print it. 157 MachineOperand MO = MachineOperand::CreateTargetIndex(0, 8); 158 159 // Checking some preconditions on the newly created 160 // MachineOperand. 161 ASSERT_TRUE(MO.isTargetIndex()); 162 ASSERT_TRUE(MO.getIndex() == 0); 163 ASSERT_TRUE(MO.getOffset() == 8); 164 165 // Print a MachineOperand containing a target index and a positive offset. 166 std::string str; 167 { 168 raw_string_ostream OS(str); 169 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 170 ASSERT_TRUE(OS.str() == "target-index(<unknown>) + 8"); 171 } 172 173 str.clear(); 174 175 MO.setOffset(-12); 176 177 // Print a MachineOperand containing a target index and a negative offset. 178 { 179 raw_string_ostream OS(str); 180 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 181 ASSERT_TRUE(OS.str() == "target-index(<unknown>) - 12"); 182 } 183 } 184 185 TEST(MachineOperandTest, PrintJumpTableIndex) { 186 // Create a MachineOperand with a jump-table index and print it. 187 MachineOperand MO = MachineOperand::CreateJTI(3); 188 189 // Checking some preconditions on the newly created 190 // MachineOperand. 191 ASSERT_TRUE(MO.isJTI()); 192 ASSERT_TRUE(MO.getIndex() == 3); 193 194 // Print a MachineOperand containing a jump-table index. 195 std::string str; 196 raw_string_ostream OS(str); 197 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 198 ASSERT_TRUE(OS.str() == "%jump-table.3"); 199 } 200 201 TEST(MachineOperandTest, PrintExternalSymbol) { 202 // Create a MachineOperand with an external symbol and print it. 203 MachineOperand MO = MachineOperand::CreateES("foo"); 204 205 // Checking some preconditions on the newly created 206 // MachineOperand. 207 ASSERT_TRUE(MO.isSymbol()); 208 ASSERT_TRUE(MO.getSymbolName() == StringRef("foo")); 209 210 // Print a MachineOperand containing an external symbol and no offset. 211 std::string str; 212 { 213 raw_string_ostream OS(str); 214 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 215 ASSERT_TRUE(OS.str() == "$foo"); 216 } 217 218 str.clear(); 219 MO.setOffset(12); 220 221 // Print a MachineOperand containing an external symbol and a positive offset. 222 { 223 raw_string_ostream OS(str); 224 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 225 ASSERT_TRUE(OS.str() == "$foo + 12"); 226 } 227 228 str.clear(); 229 MO.setOffset(-12); 230 231 // Print a MachineOperand containing an external symbol and a negative offset. 232 { 233 raw_string_ostream OS(str); 234 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 235 ASSERT_TRUE(OS.str() == "$foo - 12"); 236 } 237 } 238 239 TEST(MachineOperandTest, PrintGlobalAddress) { 240 LLVMContext Ctx; 241 Module M("MachineOperandGVTest", Ctx); 242 M.getOrInsertGlobal("foo", Type::getInt32Ty(Ctx)); 243 244 GlobalValue *GV = M.getNamedValue("foo"); 245 246 // Create a MachineOperand with a global address and a positive offset and 247 // print it. 248 MachineOperand MO = MachineOperand::CreateGA(GV, 12); 249 250 // Checking some preconditions on the newly created 251 // MachineOperand. 252 ASSERT_TRUE(MO.isGlobal()); 253 ASSERT_TRUE(MO.getGlobal() == GV); 254 ASSERT_TRUE(MO.getOffset() == 12); 255 256 std::string str; 257 // Print a MachineOperand containing a global address and a positive offset. 258 { 259 raw_string_ostream OS(str); 260 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 261 ASSERT_TRUE(OS.str() == "@foo + 12"); 262 } 263 264 str.clear(); 265 MO.setOffset(-12); 266 267 // Print a MachineOperand containing a global address and a negative offset. 268 { 269 raw_string_ostream OS(str); 270 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 271 ASSERT_TRUE(OS.str() == "@foo - 12"); 272 } 273 } 274 275 TEST(MachineOperandTest, PrintRegisterLiveOut) { 276 // Create a MachineOperand with a register live out list and print it. 277 uint32_t Mask = 0; 278 MachineOperand MO = MachineOperand::CreateRegLiveOut(&Mask); 279 280 // Checking some preconditions on the newly created 281 // MachineOperand. 282 ASSERT_TRUE(MO.isRegLiveOut()); 283 ASSERT_TRUE(MO.getRegLiveOut() == &Mask); 284 285 std::string str; 286 // Print a MachineOperand containing a register live out list without a TRI. 287 raw_string_ostream OS(str); 288 MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr); 289 ASSERT_TRUE(OS.str() == "liveout(<unknown>)"); 290 } 291 292 TEST(MachineOperandTest, PrintMetadata) { 293 LLVMContext Ctx; 294 Module M("MachineOperandMDNodeTest", Ctx); 295 NamedMDNode *MD = M.getOrInsertNamedMetadata("namedmd"); 296 ModuleSlotTracker DummyMST(&M); 297 Metadata *MDS = MDString::get(Ctx, "foo"); 298 MDNode *Node = MDNode::get(Ctx, MDS); 299 MD->addOperand(Node); 300 301 // Create a MachineOperand with a metadata and print it. 302 MachineOperand MO = MachineOperand::CreateMetadata(Node); 303 304 // Checking some preconditions on the newly created 305 // MachineOperand. 306 ASSERT_TRUE(MO.isMetadata()); 307 ASSERT_TRUE(MO.getMetadata() == Node); 308 309 std::string str; 310 // Print a MachineOperand containing a metadata node. 311 raw_string_ostream OS(str); 312 MO.print(OS, DummyMST, LLT{}, false, false, 0, /*TRI=*/nullptr, 313 /*IntrinsicInfo=*/nullptr); 314 ASSERT_TRUE(OS.str() == "!0"); 315 } 316 317 } // end namespace 318