1 #include "llvm/ADT/STLExtras.h" 2 #include "llvm/CodeGen/LiveIntervals.h" 3 #include "llvm/CodeGen/MIRParser/MIRParser.h" 4 #include "llvm/CodeGen/MachineFunction.h" 5 #include "llvm/CodeGen/MachineModuleInfo.h" 6 #include "llvm/CodeGen/TargetRegisterInfo.h" 7 #include "llvm/IR/LegacyPassManager.h" 8 #include "llvm/InitializePasses.h" 9 #include "llvm/Support/MemoryBuffer.h" 10 #include "llvm/Support/SourceMgr.h" 11 #include "llvm/Support/TargetRegistry.h" 12 #include "llvm/Support/TargetSelect.h" 13 #include "llvm/Target/TargetMachine.h" 14 #include "llvm/Target/TargetOptions.h" 15 #include "gtest/gtest.h" 16 17 using namespace llvm; 18 19 namespace llvm { 20 void initializeTestPassPass(PassRegistry &); 21 } 22 23 namespace { 24 25 void initLLVM() { 26 InitializeAllTargets(); 27 InitializeAllTargetMCs(); 28 InitializeAllAsmPrinters(); 29 InitializeAllAsmParsers(); 30 31 PassRegistry *Registry = PassRegistry::getPassRegistry(); 32 initializeCore(*Registry); 33 initializeCodeGen(*Registry); 34 } 35 36 /// Create a TargetMachine. As we lack a dedicated always available target for 37 /// unittests, we go for "AMDGPU" to be able to test normal and subregister 38 /// liveranges. 39 std::unique_ptr<LLVMTargetMachine> createTargetMachine() { 40 Triple TargetTriple("amdgcn--"); 41 std::string Error; 42 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); 43 if (!T) 44 return nullptr; 45 46 TargetOptions Options; 47 return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine*>( 48 T->createTargetMachine("AMDGPU", "", "", Options, None, None, 49 CodeGenOpt::Aggressive))); 50 } 51 52 std::unique_ptr<Module> parseMIR(LLVMContext &Context, 53 legacy::PassManagerBase &PM, std::unique_ptr<MIRParser> &MIR, 54 const LLVMTargetMachine &TM, StringRef MIRCode, const char *FuncName) { 55 SMDiagnostic Diagnostic; 56 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode); 57 MIR = createMIRParser(std::move(MBuffer), Context); 58 if (!MIR) 59 return nullptr; 60 61 std::unique_ptr<Module> M = MIR->parseIRModule(); 62 if (!M) 63 return nullptr; 64 65 M->setDataLayout(TM.createDataLayout()); 66 67 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(&TM); 68 if (MIR->parseMachineFunctions(*M, MMIWP->getMMI())) 69 return nullptr; 70 PM.add(MMIWP); 71 72 return M; 73 } 74 75 typedef std::function<void(MachineFunction&,LiveIntervals&)> LiveIntervalTest; 76 77 struct TestPass : public MachineFunctionPass { 78 static char ID; 79 TestPass() : MachineFunctionPass(ID) { 80 // We should never call this but always use PM.add(new TestPass(...)) 81 abort(); 82 } 83 TestPass(LiveIntervalTest T) : MachineFunctionPass(ID), T(T) { 84 initializeTestPassPass(*PassRegistry::getPassRegistry()); 85 } 86 87 bool runOnMachineFunction(MachineFunction &MF) override { 88 LiveIntervals &LIS = getAnalysis<LiveIntervals>(); 89 T(MF, LIS); 90 EXPECT_TRUE(MF.verify(this)); 91 return true; 92 } 93 94 void getAnalysisUsage(AnalysisUsage &AU) const override { 95 AU.setPreservesAll(); 96 AU.addRequired<LiveIntervals>(); 97 AU.addPreserved<LiveIntervals>(); 98 MachineFunctionPass::getAnalysisUsage(AU); 99 } 100 private: 101 LiveIntervalTest T; 102 }; 103 104 static MachineInstr &getMI(MachineFunction &MF, unsigned At, 105 unsigned BlockNum) { 106 MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum); 107 108 unsigned I = 0; 109 for (MachineInstr &MI : MBB) { 110 if (I == At) 111 return MI; 112 ++I; 113 } 114 llvm_unreachable("Instruction not found"); 115 } 116 117 /** 118 * Move instruction number \p From in front of instruction number \p To and 119 * update affected liveness intervals with LiveIntervalAnalysis::handleMove(). 120 */ 121 static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS, 122 unsigned From, unsigned To, unsigned BlockNum = 0) { 123 MachineInstr &FromInstr = getMI(MF, From, BlockNum); 124 MachineInstr &ToInstr = getMI(MF, To, BlockNum); 125 126 MachineBasicBlock &MBB = *FromInstr.getParent(); 127 MBB.splice(ToInstr.getIterator(), &MBB, FromInstr.getIterator()); 128 LIS.handleMove(FromInstr, true); 129 } 130 131 /** 132 * Move instructions numbered \p From inclusive through instruction number 133 * \p To into a newly formed bundle and update affected liveness intervals 134 * with LiveIntervalAnalysis::handleMoveIntoNewBundle(). 135 */ 136 static void testHandleMoveIntoNewBundle(MachineFunction &MF, LiveIntervals &LIS, 137 unsigned From, unsigned To, 138 unsigned BlockNum = 0) { 139 MachineInstr &FromInstr = getMI(MF, From, BlockNum); 140 MachineInstr &ToInstr = getMI(MF, To, BlockNum); 141 MachineBasicBlock &MBB = *FromInstr.getParent(); 142 MachineBasicBlock::instr_iterator I = FromInstr.getIterator(); 143 144 // Build bundle 145 finalizeBundle(MBB, I, std::next(ToInstr.getIterator())); 146 147 // Update LiveIntervals 148 MachineBasicBlock::instr_iterator BundleStart = std::prev(I); 149 LIS.handleMoveIntoNewBundle(*BundleStart, true); 150 } 151 152 static void liveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) { 153 LLVMContext Context; 154 std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine(); 155 // This test is designed for the X86 backend; stop if it is not available. 156 if (!TM) 157 return; 158 159 legacy::PassManager PM; 160 161 SmallString<160> S; 162 StringRef MIRString = (Twine(R"MIR( 163 --- 164 ... 165 name: func 166 registers: 167 - { id: 0, class: sreg_64 } 168 body: | 169 bb.0: 170 )MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S); 171 std::unique_ptr<MIRParser> MIR; 172 std::unique_ptr<Module> M = parseMIR(Context, PM, MIR, *TM, MIRString, 173 "func"); 174 ASSERT_TRUE(M); 175 176 PM.add(new TestPass(T)); 177 178 PM.run(*M); 179 } 180 181 } // End of anonymous namespace. 182 183 char TestPass::ID = 0; 184 INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false) 185 186 TEST(LiveIntervalTest, MoveUpDef) { 187 // Value defined. 188 liveIntervalTest(R"MIR( 189 S_NOP 0 190 S_NOP 0 191 early-clobber %0 = IMPLICIT_DEF 192 S_NOP 0, implicit %0 193 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 194 testHandleMove(MF, LIS, 2, 1); 195 }); 196 } 197 198 TEST(LiveIntervalTest, MoveUpRedef) { 199 liveIntervalTest(R"MIR( 200 %0 = IMPLICIT_DEF 201 S_NOP 0 202 %0 = IMPLICIT_DEF implicit %0(tied-def 0) 203 S_NOP 0, implicit %0 204 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 205 testHandleMove(MF, LIS, 2, 1); 206 }); 207 } 208 209 TEST(LiveIntervalTest, MoveUpEarlyDef) { 210 liveIntervalTest(R"MIR( 211 S_NOP 0 212 S_NOP 0 213 early-clobber %0 = IMPLICIT_DEF 214 S_NOP 0, implicit %0 215 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 216 testHandleMove(MF, LIS, 2, 1); 217 }); 218 } 219 220 TEST(LiveIntervalTest, MoveUpEarlyRedef) { 221 liveIntervalTest(R"MIR( 222 %0 = IMPLICIT_DEF 223 S_NOP 0 224 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0) 225 S_NOP 0, implicit %0 226 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 227 testHandleMove(MF, LIS, 2, 1); 228 }); 229 } 230 231 TEST(LiveIntervalTest, MoveUpKill) { 232 liveIntervalTest(R"MIR( 233 %0 = IMPLICIT_DEF 234 S_NOP 0 235 S_NOP 0, implicit %0 236 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 237 testHandleMove(MF, LIS, 2, 1); 238 }); 239 } 240 241 TEST(LiveIntervalTest, MoveUpKillFollowing) { 242 liveIntervalTest(R"MIR( 243 %0 = IMPLICIT_DEF 244 S_NOP 0 245 S_NOP 0, implicit %0 246 S_NOP 0, implicit %0 247 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 248 testHandleMove(MF, LIS, 2, 1); 249 }); 250 } 251 252 // TODO: Construct a situation where we have intervals following a hole 253 // while still having connected components. 254 255 TEST(LiveIntervalTest, MoveDownDef) { 256 // Value defined. 257 liveIntervalTest(R"MIR( 258 S_NOP 0 259 early-clobber %0 = IMPLICIT_DEF 260 S_NOP 0 261 S_NOP 0, implicit %0 262 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 263 testHandleMove(MF, LIS, 1, 2); 264 }); 265 } 266 267 TEST(LiveIntervalTest, MoveDownRedef) { 268 liveIntervalTest(R"MIR( 269 %0 = IMPLICIT_DEF 270 %0 = IMPLICIT_DEF implicit %0(tied-def 0) 271 S_NOP 0 272 S_NOP 0, implicit %0 273 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 274 testHandleMove(MF, LIS, 1, 2); 275 }); 276 } 277 278 TEST(LiveIntervalTest, MoveDownEarlyDef) { 279 liveIntervalTest(R"MIR( 280 S_NOP 0 281 early-clobber %0 = IMPLICIT_DEF 282 S_NOP 0 283 S_NOP 0, implicit %0 284 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 285 testHandleMove(MF, LIS, 1, 2); 286 }); 287 } 288 289 TEST(LiveIntervalTest, MoveDownEarlyRedef) { 290 liveIntervalTest(R"MIR( 291 %0 = IMPLICIT_DEF 292 early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0) 293 S_NOP 0 294 S_NOP 0, implicit %0 295 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 296 testHandleMove(MF, LIS, 1, 2); 297 }); 298 } 299 300 TEST(LiveIntervalTest, MoveDownKill) { 301 liveIntervalTest(R"MIR( 302 %0 = IMPLICIT_DEF 303 S_NOP 0, implicit %0 304 S_NOP 0 305 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 306 testHandleMove(MF, LIS, 1, 2); 307 }); 308 } 309 310 TEST(LiveIntervalTest, MoveDownKillFollowing) { 311 liveIntervalTest(R"MIR( 312 %0 = IMPLICIT_DEF 313 S_NOP 0 314 S_NOP 0, implicit %0 315 S_NOP 0, implicit %0 316 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 317 testHandleMove(MF, LIS, 1, 2); 318 }); 319 } 320 321 TEST(LiveIntervalTest, MoveUndefUse) { 322 liveIntervalTest(R"MIR( 323 %0 = IMPLICIT_DEF 324 S_NOP 0, implicit undef %0 325 S_NOP 0, implicit %0 326 S_NOP 0 327 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 328 testHandleMove(MF, LIS, 1, 3); 329 }); 330 } 331 332 TEST(LiveIntervalTest, MoveUpValNos) { 333 // handleMoveUp() had a bug where it would reuse the value number of the 334 // destination segment, even though we have no guarantee that this valno 335 // wasn't used in other segments. 336 liveIntervalTest(R"MIR( 337 successors: %bb.1, %bb.2 338 %0 = IMPLICIT_DEF 339 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc 340 S_BRANCH %bb.1 341 bb.2: 342 S_NOP 0, implicit %0 343 bb.1: 344 successors: %bb.2 345 %0 = IMPLICIT_DEF implicit %0(tied-def 0) 346 %0 = IMPLICIT_DEF implicit %0(tied-def 0) 347 %0 = IMPLICIT_DEF implicit %0(tied-def 0) 348 S_BRANCH %bb.2 349 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 350 testHandleMove(MF, LIS, 2, 0, 2); 351 }); 352 } 353 354 TEST(LiveIntervalTest, MoveOverUndefUse0) { 355 // findLastUseBefore() used by handleMoveUp() must ignore undef operands. 356 liveIntervalTest(R"MIR( 357 %0 = IMPLICIT_DEF 358 S_NOP 0 359 S_NOP 0, implicit undef %0 360 %0 = IMPLICIT_DEF implicit %0(tied-def 0) 361 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 362 testHandleMove(MF, LIS, 3, 1); 363 }); 364 } 365 366 TEST(LiveIntervalTest, MoveOverUndefUse1) { 367 // findLastUseBefore() used by handleMoveUp() must ignore undef operands. 368 liveIntervalTest(R"MIR( 369 $sgpr0 = IMPLICIT_DEF 370 S_NOP 0 371 S_NOP 0, implicit undef $sgpr0 372 $sgpr0 = IMPLICIT_DEF implicit $sgpr0(tied-def 0) 373 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 374 testHandleMove(MF, LIS, 3, 1); 375 }); 376 } 377 378 TEST(LiveIntervalTest, SubRegMoveDown) { 379 // Subregister ranges can have holes inside a basic block. Check for a 380 // movement of the form 32->150 in a liverange [16, 32) [100,200). 381 liveIntervalTest(R"MIR( 382 successors: %bb.1, %bb.2 383 %0 = IMPLICIT_DEF 384 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc 385 S_BRANCH %bb.1 386 bb.2: 387 successors: %bb.1 388 S_NOP 0, implicit %0.sub0 389 S_NOP 0, implicit %0.sub1 390 S_NOP 0 391 undef %0.sub0 = IMPLICIT_DEF 392 %0.sub1 = IMPLICIT_DEF 393 bb.1: 394 S_NOP 0, implicit %0 395 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 396 // Scheduler behaviour: Clear def,read-undef flag and move. 397 MachineInstr &MI = getMI(MF, 3, /*BlockNum=*/1); 398 MI.getOperand(0).setIsUndef(false); 399 testHandleMove(MF, LIS, 1, 4, /*BlockNum=*/1); 400 }); 401 } 402 403 TEST(LiveIntervalTest, SubRegMoveUp) { 404 // handleMoveUp had a bug not updating valno of segment incoming to bb.2 405 // after swapping subreg definitions. 406 liveIntervalTest(R"MIR( 407 successors: %bb.1, %bb.2 408 undef %0.sub0 = IMPLICIT_DEF 409 %0.sub1 = IMPLICIT_DEF 410 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc 411 S_BRANCH %bb.1 412 bb.1: 413 S_NOP 0, implicit %0.sub1 414 bb.2: 415 S_NOP 0, implicit %0.sub1 416 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 417 testHandleMove(MF, LIS, 1, 0); 418 }); 419 } 420 421 TEST(LiveIntervalTest, DeadSubRegMoveUp) { 422 // handleMoveUp had a bug where moving a dead subreg def into the middle of 423 // an earlier segment resulted in an invalid live range. 424 liveIntervalTest(R"MIR( 425 undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec 426 %125.sub1:vreg_128 = COPY %125.sub0 427 %125.sub2:vreg_128 = COPY %125.sub0 428 undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec 429 %51.sub1:vreg_128 = COPY %51.sub0 430 %51.sub2:vreg_128 = COPY %51.sub0 431 %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec 432 %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec 433 %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec 434 %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec 435 %60:vgpr_32 = V_MAD_F32 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $exec 436 %63:vgpr_32 = V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $exec 437 dead %66:vgpr_32 = V_MAD_F32 0, %60, 0, undef %67:vgpr_32, 0, %125.sub2, 0, 0, implicit $exec 438 undef %124.sub1:vreg_128 = V_MAD_F32 0, %57, 0, undef %70:vgpr_32, 0, %125.sub1, 0, 0, implicit $exec 439 %124.sub0:vreg_128 = V_MAD_F32 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $exec 440 dead undef %125.sub3:vreg_128 = V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $exec 441 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 442 testHandleMove(MF, LIS, 15, 12); 443 }); 444 } 445 446 TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDef) { 447 liveIntervalTest(R"MIR( 448 %1:vreg_64 = IMPLICIT_DEF 449 450 bb.1: 451 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec 452 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec 453 undef %1.sub0:vreg_64 = V_ADD_U32_e32 %2, %2, implicit $exec 454 %1.sub1:vreg_64 = COPY %2 455 S_NOP 0, implicit %1.sub1 456 S_BRANCH %bb.1 457 458 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 459 MachineInstr &UndefSubregDef = getMI(MF, 2, 1); 460 // The scheduler clears undef from subregister defs before moving 461 UndefSubregDef.getOperand(0).setIsUndef(false); 462 testHandleMove(MF, LIS, 3, 1, 1); 463 }); 464 } 465 466 TEST(LiveIntervalTest, TestMoveSubRegDefAcrossUseDefMulti) { 467 liveIntervalTest(R"MIR( 468 %1:vreg_96 = IMPLICIT_DEF 469 470 bb.1: 471 %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec 472 %3:vgpr_32 = V_ADD_U32_e32 %2, %1.sub0, implicit $exec 473 undef %1.sub0:vreg_96 = V_ADD_U32_e32 %2, %2, implicit $exec 474 %1.sub1:vreg_96 = COPY %2 475 %1.sub2:vreg_96 = COPY %2 476 S_NOP 0, implicit %1.sub1, implicit %1.sub2 477 S_BRANCH %bb.1 478 479 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 480 MachineInstr &UndefSubregDef = getMI(MF, 2, 1); 481 // The scheduler clears undef from subregister defs before moving 482 UndefSubregDef.getOperand(0).setIsUndef(false); 483 testHandleMove(MF, LIS, 4, 1, 1); 484 }); 485 } 486 487 TEST(LiveIntervalTest, BundleUse) { 488 liveIntervalTest(R"MIR( 489 %0 = IMPLICIT_DEF 490 S_NOP 0 491 S_NOP 0, implicit %0 492 S_NOP 0 493 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 494 testHandleMoveIntoNewBundle(MF, LIS, 1, 2); 495 }); 496 } 497 498 TEST(LiveIntervalTest, BundleDef) { 499 liveIntervalTest(R"MIR( 500 %0 = IMPLICIT_DEF 501 S_NOP 0 502 S_NOP 0, implicit %0 503 S_NOP 0 504 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 505 testHandleMoveIntoNewBundle(MF, LIS, 0, 1); 506 }); 507 } 508 509 TEST(LiveIntervalTest, BundleRedef) { 510 liveIntervalTest(R"MIR( 511 %0 = IMPLICIT_DEF 512 S_NOP 0 513 %0 = IMPLICIT_DEF implicit %0(tied-def 0) 514 S_NOP 0, implicit %0 515 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 516 testHandleMoveIntoNewBundle(MF, LIS, 1, 2); 517 }); 518 } 519 520 TEST(LiveIntervalTest, BundleInternalUse) { 521 liveIntervalTest(R"MIR( 522 %0 = IMPLICIT_DEF 523 S_NOP 0 524 S_NOP 0, implicit %0 525 S_NOP 0 526 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 527 testHandleMoveIntoNewBundle(MF, LIS, 0, 2); 528 }); 529 } 530 531 TEST(LiveIntervalTest, BundleUndefUse) { 532 liveIntervalTest(R"MIR( 533 %0 = IMPLICIT_DEF 534 S_NOP 0 535 S_NOP 0, implicit undef %0 536 S_NOP 0 537 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 538 testHandleMoveIntoNewBundle(MF, LIS, 1, 2); 539 }); 540 } 541 542 TEST(LiveIntervalTest, BundleSubRegUse) { 543 liveIntervalTest(R"MIR( 544 successors: %bb.1, %bb.2 545 undef %0.sub0 = IMPLICIT_DEF 546 %0.sub1 = IMPLICIT_DEF 547 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc 548 S_BRANCH %bb.1 549 bb.1: 550 S_NOP 0 551 S_NOP 0, implicit %0.sub1 552 bb.2: 553 S_NOP 0, implicit %0.sub1 554 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 555 testHandleMoveIntoNewBundle(MF, LIS, 0, 1, 1); 556 }); 557 } 558 559 TEST(LiveIntervalTest, BundleSubRegDef) { 560 liveIntervalTest(R"MIR( 561 successors: %bb.1, %bb.2 562 undef %0.sub0 = IMPLICIT_DEF 563 %0.sub1 = IMPLICIT_DEF 564 S_CBRANCH_VCCNZ %bb.2, implicit undef $vcc 565 S_BRANCH %bb.1 566 bb.1: 567 S_NOP 0 568 S_NOP 0, implicit %0.sub1 569 bb.2: 570 S_NOP 0, implicit %0.sub1 571 )MIR", [](MachineFunction &MF, LiveIntervals &LIS) { 572 testHandleMoveIntoNewBundle(MF, LIS, 0, 1, 0); 573 }); 574 } 575 576 int main(int argc, char **argv) { 577 ::testing::InitGoogleTest(&argc, argv); 578 initLLVM(); 579 return RUN_ALL_TESTS(); 580 } 581