1 //===- CrashDebugger.cpp - Debug compilation crashes ----------------------===// 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 // This file defines the bugpoint internals that narrow down compilation crashes 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "BugDriver.h" 15 #include "ListReducer.h" 16 #include "ToolRunner.h" 17 #include "llvm/ADT/SmallPtrSet.h" 18 #include "llvm/ADT/StringSet.h" 19 #include "llvm/Analysis/TargetTransformInfo.h" 20 #include "llvm/IR/CFG.h" 21 #include "llvm/IR/Constants.h" 22 #include "llvm/IR/DebugInfo.h" 23 #include "llvm/IR/DerivedTypes.h" 24 #include "llvm/IR/Instructions.h" 25 #include "llvm/IR/LegacyPassManager.h" 26 #include "llvm/IR/Module.h" 27 #include "llvm/IR/ValueSymbolTable.h" 28 #include "llvm/IR/Verifier.h" 29 #include "llvm/Pass.h" 30 #include "llvm/Support/CommandLine.h" 31 #include "llvm/Support/FileUtilities.h" 32 #include "llvm/Transforms/Scalar.h" 33 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 34 #include "llvm/Transforms/Utils/Cloning.h" 35 #include "llvm/Transforms/Utils/Local.h" 36 #include <set> 37 using namespace llvm; 38 39 namespace { 40 cl::opt<bool> KeepMain("keep-main", 41 cl::desc("Force function reduction to keep main"), 42 cl::init(false)); 43 cl::opt<bool> NoGlobalRM("disable-global-remove", 44 cl::desc("Do not remove global variables"), 45 cl::init(false)); 46 47 cl::opt<bool> ReplaceFuncsWithNull( 48 "replace-funcs-with-null", 49 cl::desc("When stubbing functions, replace all uses will null"), 50 cl::init(false)); 51 cl::opt<bool> DontReducePassList("disable-pass-list-reduction", 52 cl::desc("Skip pass list reduction steps"), 53 cl::init(false)); 54 55 cl::opt<bool> NoNamedMDRM("disable-namedmd-remove", 56 cl::desc("Do not remove global named metadata"), 57 cl::init(false)); 58 cl::opt<bool> NoStripDebugInfo("disable-strip-debuginfo", 59 cl::desc("Do not strip debug info metadata"), 60 cl::init(false)); 61 cl::opt<bool> NoStripDebugTypeInfo("disable-strip-debug-types", 62 cl::desc("Do not strip debug type info metadata"), 63 cl::init(false)); 64 cl::opt<bool> VerboseErrors("verbose-errors", 65 cl::desc("Print the output of crashing program"), 66 cl::init(false)); 67 } 68 69 namespace llvm { 70 class ReducePassList : public ListReducer<std::string> { 71 BugDriver &BD; 72 73 public: 74 ReducePassList(BugDriver &bd) : BD(bd) {} 75 76 // Return true iff running the "removed" passes succeeds, and running the 77 // "Kept" passes fail when run on the output of the "removed" passes. If we 78 // return true, we update the current module of bugpoint. 79 Expected<TestResult> doTest(std::vector<std::string> &Removed, 80 std::vector<std::string> &Kept) override; 81 }; 82 } 83 84 Expected<ReducePassList::TestResult> 85 ReducePassList::doTest(std::vector<std::string> &Prefix, 86 std::vector<std::string> &Suffix) { 87 std::string PrefixOutput; 88 Module *OrigProgram = nullptr; 89 if (!Prefix.empty()) { 90 outs() << "Checking to see if these passes crash: " 91 << getPassesString(Prefix) << ": "; 92 if (BD.runPasses(BD.getProgram(), Prefix, PrefixOutput)) 93 return KeepPrefix; 94 95 OrigProgram = BD.Program; 96 97 BD.Program = parseInputFile(PrefixOutput, BD.getContext()).release(); 98 if (BD.Program == nullptr) { 99 errs() << BD.getToolName() << ": Error reading bitcode file '" 100 << PrefixOutput << "'!\n"; 101 exit(1); 102 } 103 sys::fs::remove(PrefixOutput); 104 } 105 106 outs() << "Checking to see if these passes crash: " << getPassesString(Suffix) 107 << ": "; 108 109 if (BD.runPasses(BD.getProgram(), Suffix)) { 110 delete OrigProgram; // The suffix crashes alone... 111 return KeepSuffix; 112 } 113 114 // Nothing failed, restore state... 115 if (OrigProgram) { 116 delete BD.Program; 117 BD.Program = OrigProgram; 118 } 119 return NoFailure; 120 } 121 122 namespace { 123 /// ReduceCrashingGlobalVariables - This works by removing the global 124 /// variable's initializer and seeing if the program still crashes. If it 125 /// does, then we keep that program and try again. 126 /// 127 class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable *> { 128 BugDriver &BD; 129 bool (*TestFn)(const BugDriver &, Module *); 130 131 public: 132 ReduceCrashingGlobalVariables(BugDriver &bd, 133 bool (*testFn)(const BugDriver &, Module *)) 134 : BD(bd), TestFn(testFn) {} 135 136 Expected<TestResult> doTest(std::vector<GlobalVariable *> &Prefix, 137 std::vector<GlobalVariable *> &Kept) override { 138 if (!Kept.empty() && TestGlobalVariables(Kept)) 139 return KeepSuffix; 140 if (!Prefix.empty() && TestGlobalVariables(Prefix)) 141 return KeepPrefix; 142 return NoFailure; 143 } 144 145 bool TestGlobalVariables(std::vector<GlobalVariable *> &GVs); 146 }; 147 } 148 149 bool ReduceCrashingGlobalVariables::TestGlobalVariables( 150 std::vector<GlobalVariable *> &GVs) { 151 // Clone the program to try hacking it apart... 152 ValueToValueMapTy VMap; 153 Module *M = CloneModule(BD.getProgram(), VMap).release(); 154 155 // Convert list to set for fast lookup... 156 std::set<GlobalVariable *> GVSet; 157 158 for (unsigned i = 0, e = GVs.size(); i != e; ++i) { 159 GlobalVariable *CMGV = cast<GlobalVariable>(VMap[GVs[i]]); 160 assert(CMGV && "Global Variable not in module?!"); 161 GVSet.insert(CMGV); 162 } 163 164 outs() << "Checking for crash with only these global variables: "; 165 PrintGlobalVariableList(GVs); 166 outs() << ": "; 167 168 // Loop over and delete any global variables which we aren't supposed to be 169 // playing with... 170 for (GlobalVariable &I : M->globals()) 171 if (I.hasInitializer() && !GVSet.count(&I)) { 172 DeleteGlobalInitializer(&I); 173 I.setLinkage(GlobalValue::ExternalLinkage); 174 I.setComdat(nullptr); 175 } 176 177 // Try running the hacked up program... 178 if (TestFn(BD, M)) { 179 BD.setNewProgram(M); // It crashed, keep the trimmed version... 180 181 // Make sure to use global variable pointers that point into the now-current 182 // module. 183 GVs.assign(GVSet.begin(), GVSet.end()); 184 return true; 185 } 186 187 delete M; 188 return false; 189 } 190 191 namespace { 192 /// ReduceCrashingFunctions reducer - This works by removing functions and 193 /// seeing if the program still crashes. If it does, then keep the newer, 194 /// smaller program. 195 /// 196 class ReduceCrashingFunctions : public ListReducer<Function *> { 197 BugDriver &BD; 198 bool (*TestFn)(const BugDriver &, Module *); 199 200 public: 201 ReduceCrashingFunctions(BugDriver &bd, 202 bool (*testFn)(const BugDriver &, Module *)) 203 : BD(bd), TestFn(testFn) {} 204 205 Expected<TestResult> doTest(std::vector<Function *> &Prefix, 206 std::vector<Function *> &Kept) override { 207 if (!Kept.empty() && TestFuncs(Kept)) 208 return KeepSuffix; 209 if (!Prefix.empty() && TestFuncs(Prefix)) 210 return KeepPrefix; 211 return NoFailure; 212 } 213 214 bool TestFuncs(std::vector<Function *> &Prefix); 215 }; 216 } 217 218 static void RemoveFunctionReferences(Module *M, const char *Name) { 219 auto *UsedVar = M->getGlobalVariable(Name, true); 220 if (!UsedVar || !UsedVar->hasInitializer()) 221 return; 222 if (isa<ConstantAggregateZero>(UsedVar->getInitializer())) { 223 assert(UsedVar->use_empty()); 224 UsedVar->eraseFromParent(); 225 return; 226 } 227 auto *OldUsedVal = cast<ConstantArray>(UsedVar->getInitializer()); 228 std::vector<Constant *> Used; 229 for (Value *V : OldUsedVal->operand_values()) { 230 Constant *Op = cast<Constant>(V->stripPointerCasts()); 231 if (!Op->isNullValue()) { 232 Used.push_back(cast<Constant>(V)); 233 } 234 } 235 auto *NewValElemTy = OldUsedVal->getType()->getElementType(); 236 auto *NewValTy = ArrayType::get(NewValElemTy, Used.size()); 237 auto *NewUsedVal = ConstantArray::get(NewValTy, Used); 238 UsedVar->mutateType(NewUsedVal->getType()->getPointerTo()); 239 UsedVar->setInitializer(NewUsedVal); 240 } 241 242 bool ReduceCrashingFunctions::TestFuncs(std::vector<Function *> &Funcs) { 243 // If main isn't present, claim there is no problem. 244 if (KeepMain && !is_contained(Funcs, BD.getProgram()->getFunction("main"))) 245 return false; 246 247 // Clone the program to try hacking it apart... 248 ValueToValueMapTy VMap; 249 Module *M = CloneModule(BD.getProgram(), VMap).release(); 250 251 // Convert list to set for fast lookup... 252 std::set<Function *> Functions; 253 for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { 254 Function *CMF = cast<Function>(VMap[Funcs[i]]); 255 assert(CMF && "Function not in module?!"); 256 assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty"); 257 assert(CMF->getName() == Funcs[i]->getName() && "wrong name"); 258 Functions.insert(CMF); 259 } 260 261 outs() << "Checking for crash with only these functions: "; 262 PrintFunctionList(Funcs); 263 outs() << ": "; 264 if (!ReplaceFuncsWithNull) { 265 // Loop over and delete any functions which we aren't supposed to be playing 266 // with... 267 for (Function &I : *M) 268 if (!I.isDeclaration() && !Functions.count(&I)) 269 DeleteFunctionBody(&I); 270 } else { 271 std::vector<GlobalValue *> ToRemove; 272 // First, remove aliases to functions we're about to purge. 273 for (GlobalAlias &Alias : M->aliases()) { 274 GlobalObject *Root = Alias.getBaseObject(); 275 Function *F = dyn_cast_or_null<Function>(Root); 276 if (F) { 277 if (Functions.count(F)) 278 // We're keeping this function. 279 continue; 280 } else if (Root->isNullValue()) { 281 // This referenced a globalalias that we've already replaced, 282 // so we still need to replace this alias. 283 } else if (!F) { 284 // Not a function, therefore not something we mess with. 285 continue; 286 } 287 288 PointerType *Ty = cast<PointerType>(Alias.getType()); 289 Constant *Replacement = ConstantPointerNull::get(Ty); 290 Alias.replaceAllUsesWith(Replacement); 291 ToRemove.push_back(&Alias); 292 } 293 294 for (Function &I : *M) { 295 if (!I.isDeclaration() && !Functions.count(&I)) { 296 PointerType *Ty = cast<PointerType>(I.getType()); 297 Constant *Replacement = ConstantPointerNull::get(Ty); 298 I.replaceAllUsesWith(Replacement); 299 ToRemove.push_back(&I); 300 } 301 } 302 303 for (auto *F : ToRemove) { 304 F->eraseFromParent(); 305 } 306 307 // Finally, remove any null members from any global intrinsic. 308 RemoveFunctionReferences(M, "llvm.used"); 309 RemoveFunctionReferences(M, "llvm.compiler.used"); 310 } 311 // Try running the hacked up program... 312 if (TestFn(BD, M)) { 313 BD.setNewProgram(M); // It crashed, keep the trimmed version... 314 315 // Make sure to use function pointers that point into the now-current 316 // module. 317 Funcs.assign(Functions.begin(), Functions.end()); 318 return true; 319 } 320 delete M; 321 return false; 322 } 323 324 namespace { 325 /// Simplify the CFG without completely destroying it. 326 /// This is not well defined, but basically comes down to "try to eliminate 327 /// unreachable blocks and constant fold terminators without deciding that 328 /// certain undefined behavior cuts off the program at the legs". 329 void simpleSimplifyCfg(Function &F, SmallVectorImpl<BasicBlock *> &BBs) { 330 if (F.empty()) 331 return; 332 333 for (auto *BB : BBs) { 334 ConstantFoldTerminator(BB); 335 MergeBlockIntoPredecessor(BB); 336 } 337 338 // Remove unreachable blocks 339 // removeUnreachableBlocks can't be used here, it will turn various 340 // undefined behavior into unreachables, but bugpoint was the thing that 341 // generated the undefined behavior, and we don't want it to kill the entire 342 // program. 343 SmallPtrSet<BasicBlock *, 16> Visited; 344 for (auto *BB : depth_first(&F.getEntryBlock())) 345 Visited.insert(BB); 346 347 SmallVector<BasicBlock *, 16> Unreachable; 348 for (auto &BB : F) 349 if (!Visited.count(&BB)) 350 Unreachable.push_back(&BB); 351 352 // The dead BB's may be in a dead cycle or otherwise have references to each 353 // other. Because of this, we have to drop all references first, then delete 354 // them all at once. 355 for (auto *BB : Unreachable) { 356 for (BasicBlock *Successor : successors(&*BB)) 357 if (Visited.count(Successor)) 358 Successor->removePredecessor(&*BB); 359 BB->dropAllReferences(); 360 } 361 for (auto *BB : Unreachable) 362 BB->eraseFromParent(); 363 } 364 /// ReduceCrashingBlocks reducer - This works by setting the terminators of 365 /// all terminators except the specified basic blocks to a 'ret' instruction, 366 /// then running the simplify-cfg pass. This has the effect of chopping up 367 /// the CFG really fast which can reduce large functions quickly. 368 /// 369 class ReduceCrashingBlocks : public ListReducer<const BasicBlock *> { 370 BugDriver &BD; 371 bool (*TestFn)(const BugDriver &, Module *); 372 373 public: 374 ReduceCrashingBlocks(BugDriver &BD, 375 bool (*testFn)(const BugDriver &, Module *)) 376 : BD(BD), TestFn(testFn) {} 377 378 Expected<TestResult> doTest(std::vector<const BasicBlock *> &Prefix, 379 std::vector<const BasicBlock *> &Kept) override { 380 if (!Kept.empty() && TestBlocks(Kept)) 381 return KeepSuffix; 382 if (!Prefix.empty() && TestBlocks(Prefix)) 383 return KeepPrefix; 384 return NoFailure; 385 } 386 387 bool TestBlocks(std::vector<const BasicBlock *> &Prefix); 388 }; 389 } 390 391 bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock *> &BBs) { 392 // Clone the program to try hacking it apart... 393 ValueToValueMapTy VMap; 394 Module *M = CloneModule(BD.getProgram(), VMap).release(); 395 396 // Convert list to set for fast lookup... 397 SmallPtrSet<BasicBlock *, 8> Blocks; 398 for (unsigned i = 0, e = BBs.size(); i != e; ++i) 399 Blocks.insert(cast<BasicBlock>(VMap[BBs[i]])); 400 401 outs() << "Checking for crash with only these blocks:"; 402 unsigned NumPrint = Blocks.size(); 403 if (NumPrint > 10) 404 NumPrint = 10; 405 for (unsigned i = 0, e = NumPrint; i != e; ++i) 406 outs() << " " << BBs[i]->getName(); 407 if (NumPrint < Blocks.size()) 408 outs() << "... <" << Blocks.size() << " total>"; 409 outs() << ": "; 410 411 // Loop over and delete any hack up any blocks that are not listed... 412 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 413 for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB) 414 if (!Blocks.count(&*BB) && BB->getTerminator()->getNumSuccessors()) { 415 // Loop over all of the successors of this block, deleting any PHI nodes 416 // that might include it. 417 for (succ_iterator SI = succ_begin(&*BB), E = succ_end(&*BB); SI != E; 418 ++SI) 419 (*SI)->removePredecessor(&*BB); 420 421 TerminatorInst *BBTerm = BB->getTerminator(); 422 if (BBTerm->isEHPad() || BBTerm->getType()->isTokenTy()) 423 continue; 424 if (!BBTerm->getType()->isVoidTy()) 425 BBTerm->replaceAllUsesWith(Constant::getNullValue(BBTerm->getType())); 426 427 // Replace the old terminator instruction. 428 BB->getInstList().pop_back(); 429 new UnreachableInst(BB->getContext(), &*BB); 430 } 431 432 // The CFG Simplifier pass may delete one of the basic blocks we are 433 // interested in. If it does we need to take the block out of the list. Make 434 // a "persistent mapping" by turning basic blocks into <function, name> pairs. 435 // This won't work well if blocks are unnamed, but that is just the risk we 436 // have to take. 437 std::vector<std::pair<std::string, std::string>> BlockInfo; 438 439 for (BasicBlock *BB : Blocks) 440 BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName()); 441 442 SmallVector<BasicBlock *, 16> ToProcess; 443 for (auto &F : *M) { 444 for (auto &BB : F) 445 if (!Blocks.count(&BB)) 446 ToProcess.push_back(&BB); 447 simpleSimplifyCfg(F, ToProcess); 448 ToProcess.clear(); 449 } 450 // Verify we didn't break anything 451 std::vector<std::string> Passes; 452 Passes.push_back("verify"); 453 std::unique_ptr<Module> New = BD.runPassesOn(M, Passes); 454 delete M; 455 if (!New) { 456 errs() << "verify failed!\n"; 457 exit(1); 458 } 459 M = New.release(); 460 461 // Try running on the hacked up program... 462 if (TestFn(BD, M)) { 463 BD.setNewProgram(M); // It crashed, keep the trimmed version... 464 465 // Make sure to use basic block pointers that point into the now-current 466 // module, and that they don't include any deleted blocks. 467 BBs.clear(); 468 const ValueSymbolTable &GST = M->getValueSymbolTable(); 469 for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) { 470 Function *F = cast<Function>(GST.lookup(BlockInfo[i].first)); 471 Value *V = F->getValueSymbolTable()->lookup(BlockInfo[i].second); 472 if (V && V->getType() == Type::getLabelTy(V->getContext())) 473 BBs.push_back(cast<BasicBlock>(V)); 474 } 475 return true; 476 } 477 delete M; // It didn't crash, try something else. 478 return false; 479 } 480 481 namespace { 482 /// ReduceCrashingConditionals reducer - This works by changing 483 /// conditional branches to unconditional ones, then simplifying the CFG 484 /// This has the effect of chopping up the CFG really fast which can reduce 485 /// large functions quickly. 486 /// 487 class ReduceCrashingConditionals : public ListReducer<const BasicBlock *> { 488 BugDriver &BD; 489 bool (*TestFn)(const BugDriver &, Module *); 490 bool Direction; 491 492 public: 493 ReduceCrashingConditionals(BugDriver &bd, 494 bool (*testFn)(const BugDriver &, Module *), 495 bool Direction) 496 : BD(bd), TestFn(testFn), Direction(Direction) {} 497 498 Expected<TestResult> doTest(std::vector<const BasicBlock *> &Prefix, 499 std::vector<const BasicBlock *> &Kept) override { 500 if (!Kept.empty() && TestBlocks(Kept)) 501 return KeepSuffix; 502 if (!Prefix.empty() && TestBlocks(Prefix)) 503 return KeepPrefix; 504 return NoFailure; 505 } 506 507 bool TestBlocks(std::vector<const BasicBlock *> &Prefix); 508 }; 509 } 510 511 bool ReduceCrashingConditionals::TestBlocks( 512 std::vector<const BasicBlock *> &BBs) { 513 // Clone the program to try hacking it apart... 514 ValueToValueMapTy VMap; 515 Module *M = CloneModule(BD.getProgram(), VMap).release(); 516 517 // Convert list to set for fast lookup... 518 SmallPtrSet<const BasicBlock *, 8> Blocks; 519 for (const auto *BB : BBs) 520 Blocks.insert(cast<BasicBlock>(VMap[BB])); 521 522 outs() << "Checking for crash with changing conditionals to always jump to " 523 << (Direction ? "true" : "false") << ":"; 524 unsigned NumPrint = Blocks.size(); 525 if (NumPrint > 10) 526 NumPrint = 10; 527 for (unsigned i = 0, e = NumPrint; i != e; ++i) 528 outs() << " " << BBs[i]->getName(); 529 if (NumPrint < Blocks.size()) 530 outs() << "... <" << Blocks.size() << " total>"; 531 outs() << ": "; 532 533 // Loop over and delete any hack up any blocks that are not listed... 534 for (auto &F : *M) 535 for (auto &BB : F) 536 if (!Blocks.count(&BB)) { 537 auto *BR = dyn_cast<BranchInst>(BB.getTerminator()); 538 if (!BR || !BR->isConditional()) 539 continue; 540 if (Direction) 541 BR->setCondition(ConstantInt::getTrue(BR->getContext())); 542 else 543 BR->setCondition(ConstantInt::getFalse(BR->getContext())); 544 } 545 546 // The following may destroy some blocks, so we save them first 547 std::vector<std::pair<std::string, std::string>> BlockInfo; 548 549 for (const BasicBlock *BB : Blocks) 550 BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName()); 551 552 SmallVector<BasicBlock *, 16> ToProcess; 553 for (auto &F : *M) { 554 for (auto &BB : F) 555 if (!Blocks.count(&BB)) 556 ToProcess.push_back(&BB); 557 simpleSimplifyCfg(F, ToProcess); 558 ToProcess.clear(); 559 } 560 // Verify we didn't break anything 561 std::vector<std::string> Passes; 562 Passes.push_back("verify"); 563 std::unique_ptr<Module> New = BD.runPassesOn(M, Passes); 564 delete M; 565 if (!New) { 566 errs() << "verify failed!\n"; 567 exit(1); 568 } 569 M = New.release(); 570 571 // Try running on the hacked up program... 572 if (TestFn(BD, M)) { 573 BD.setNewProgram(M); // It crashed, keep the trimmed version... 574 575 // Make sure to use basic block pointers that point into the now-current 576 // module, and that they don't include any deleted blocks. 577 BBs.clear(); 578 const ValueSymbolTable &GST = M->getValueSymbolTable(); 579 for (auto &BI : BlockInfo) { 580 auto *F = cast<Function>(GST.lookup(BI.first)); 581 Value *V = F->getValueSymbolTable()->lookup(BI.second); 582 if (V && V->getType() == Type::getLabelTy(V->getContext())) 583 BBs.push_back(cast<BasicBlock>(V)); 584 } 585 return true; 586 } 587 delete M; // It didn't crash, try something else. 588 return false; 589 } 590 591 namespace { 592 /// SimplifyCFG reducer - This works by calling SimplifyCFG on each basic block 593 /// in the program. 594 595 class ReduceSimplifyCFG : public ListReducer<const BasicBlock *> { 596 BugDriver &BD; 597 bool (*TestFn)(const BugDriver &, Module *); 598 TargetTransformInfo TTI; 599 600 public: 601 ReduceSimplifyCFG(BugDriver &bd, bool (*testFn)(const BugDriver &, Module *)) 602 : BD(bd), TestFn(testFn), TTI(bd.getProgram()->getDataLayout()) {} 603 604 Expected<TestResult> doTest(std::vector<const BasicBlock *> &Prefix, 605 std::vector<const BasicBlock *> &Kept) override { 606 if (!Kept.empty() && TestBlocks(Kept)) 607 return KeepSuffix; 608 if (!Prefix.empty() && TestBlocks(Prefix)) 609 return KeepPrefix; 610 return NoFailure; 611 } 612 613 bool TestBlocks(std::vector<const BasicBlock *> &Prefix); 614 }; 615 } 616 617 bool ReduceSimplifyCFG::TestBlocks(std::vector<const BasicBlock *> &BBs) { 618 // Clone the program to try hacking it apart... 619 ValueToValueMapTy VMap; 620 Module *M = CloneModule(BD.getProgram(), VMap).release(); 621 622 // Convert list to set for fast lookup... 623 SmallPtrSet<const BasicBlock *, 8> Blocks; 624 for (const auto *BB : BBs) 625 Blocks.insert(cast<BasicBlock>(VMap[BB])); 626 627 outs() << "Checking for crash with CFG simplifying:"; 628 unsigned NumPrint = Blocks.size(); 629 if (NumPrint > 10) 630 NumPrint = 10; 631 for (unsigned i = 0, e = NumPrint; i != e; ++i) 632 outs() << " " << BBs[i]->getName(); 633 if (NumPrint < Blocks.size()) 634 outs() << "... <" << Blocks.size() << " total>"; 635 outs() << ": "; 636 637 // The following may destroy some blocks, so we save them first 638 std::vector<std::pair<std::string, std::string>> BlockInfo; 639 640 for (const BasicBlock *BB : Blocks) 641 BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName()); 642 643 // Loop over and delete any hack up any blocks that are not listed... 644 for (auto &F : *M) 645 // Loop over all of the basic blocks and remove them if they are unneeded. 646 for (Function::iterator BBIt = F.begin(); BBIt != F.end();) { 647 if (!Blocks.count(&*BBIt)) { 648 ++BBIt; 649 continue; 650 } 651 SimplifyCFG(&*BBIt++, TTI, 1); 652 } 653 // Verify we didn't break anything 654 std::vector<std::string> Passes; 655 Passes.push_back("verify"); 656 std::unique_ptr<Module> New = BD.runPassesOn(M, Passes); 657 delete M; 658 if (!New) { 659 errs() << "verify failed!\n"; 660 exit(1); 661 } 662 M = New.release(); 663 664 // Try running on the hacked up program... 665 if (TestFn(BD, M)) { 666 BD.setNewProgram(M); // It crashed, keep the trimmed version... 667 668 // Make sure to use basic block pointers that point into the now-current 669 // module, and that they don't include any deleted blocks. 670 BBs.clear(); 671 const ValueSymbolTable &GST = M->getValueSymbolTable(); 672 for (auto &BI : BlockInfo) { 673 auto *F = cast<Function>(GST.lookup(BI.first)); 674 Value *V = F->getValueSymbolTable()->lookup(BI.second); 675 if (V && V->getType() == Type::getLabelTy(V->getContext())) 676 BBs.push_back(cast<BasicBlock>(V)); 677 } 678 return true; 679 } 680 delete M; // It didn't crash, try something else. 681 return false; 682 } 683 684 namespace { 685 /// ReduceCrashingInstructions reducer - This works by removing the specified 686 /// non-terminator instructions and replacing them with undef. 687 /// 688 class ReduceCrashingInstructions : public ListReducer<const Instruction *> { 689 BugDriver &BD; 690 bool (*TestFn)(const BugDriver &, Module *); 691 692 public: 693 ReduceCrashingInstructions(BugDriver &bd, 694 bool (*testFn)(const BugDriver &, Module *)) 695 : BD(bd), TestFn(testFn) {} 696 697 Expected<TestResult> doTest(std::vector<const Instruction *> &Prefix, 698 std::vector<const Instruction *> &Kept) override { 699 if (!Kept.empty() && TestInsts(Kept)) 700 return KeepSuffix; 701 if (!Prefix.empty() && TestInsts(Prefix)) 702 return KeepPrefix; 703 return NoFailure; 704 } 705 706 bool TestInsts(std::vector<const Instruction *> &Prefix); 707 }; 708 } 709 710 bool ReduceCrashingInstructions::TestInsts( 711 std::vector<const Instruction *> &Insts) { 712 // Clone the program to try hacking it apart... 713 ValueToValueMapTy VMap; 714 Module *M = CloneModule(BD.getProgram(), VMap).release(); 715 716 // Convert list to set for fast lookup... 717 SmallPtrSet<Instruction *, 32> Instructions; 718 for (unsigned i = 0, e = Insts.size(); i != e; ++i) { 719 assert(!isa<TerminatorInst>(Insts[i])); 720 Instructions.insert(cast<Instruction>(VMap[Insts[i]])); 721 } 722 723 outs() << "Checking for crash with only " << Instructions.size(); 724 if (Instructions.size() == 1) 725 outs() << " instruction: "; 726 else 727 outs() << " instructions: "; 728 729 for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) 730 for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) 731 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) { 732 Instruction *Inst = &*I++; 733 if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst) && 734 !Inst->isEHPad() && !Inst->getType()->isTokenTy()) { 735 if (!Inst->getType()->isVoidTy()) 736 Inst->replaceAllUsesWith(UndefValue::get(Inst->getType())); 737 Inst->eraseFromParent(); 738 } 739 } 740 741 // Verify that this is still valid. 742 legacy::PassManager Passes; 743 Passes.add(createVerifierPass(/*FatalErrors=*/false)); 744 Passes.run(*M); 745 746 // Try running on the hacked up program... 747 if (TestFn(BD, M)) { 748 BD.setNewProgram(M); // It crashed, keep the trimmed version... 749 750 // Make sure to use instruction pointers that point into the now-current 751 // module, and that they don't include any deleted blocks. 752 Insts.clear(); 753 for (Instruction *Inst : Instructions) 754 Insts.push_back(Inst); 755 return true; 756 } 757 delete M; // It didn't crash, try something else. 758 return false; 759 } 760 761 namespace { 762 // Reduce the list of Named Metadata nodes. We keep this as a list of 763 // names to avoid having to convert back and forth every time. 764 class ReduceCrashingNamedMD : public ListReducer<std::string> { 765 BugDriver &BD; 766 bool (*TestFn)(const BugDriver &, Module *); 767 768 public: 769 ReduceCrashingNamedMD(BugDriver &bd, 770 bool (*testFn)(const BugDriver &, Module *)) 771 : BD(bd), TestFn(testFn) {} 772 773 Expected<TestResult> doTest(std::vector<std::string> &Prefix, 774 std::vector<std::string> &Kept) override { 775 if (!Kept.empty() && TestNamedMDs(Kept)) 776 return KeepSuffix; 777 if (!Prefix.empty() && TestNamedMDs(Prefix)) 778 return KeepPrefix; 779 return NoFailure; 780 } 781 782 bool TestNamedMDs(std::vector<std::string> &NamedMDs); 783 }; 784 } 785 786 bool ReduceCrashingNamedMD::TestNamedMDs(std::vector<std::string> &NamedMDs) { 787 788 ValueToValueMapTy VMap; 789 Module *M = CloneModule(BD.getProgram(), VMap).release(); 790 791 outs() << "Checking for crash with only these named metadata nodes:"; 792 unsigned NumPrint = std::min<size_t>(NamedMDs.size(), 10); 793 for (unsigned i = 0, e = NumPrint; i != e; ++i) 794 outs() << " " << NamedMDs[i]; 795 if (NumPrint < NamedMDs.size()) 796 outs() << "... <" << NamedMDs.size() << " total>"; 797 outs() << ": "; 798 799 // Make a StringMap for faster lookup 800 StringSet<> Names; 801 for (const std::string &Name : NamedMDs) 802 Names.insert(Name); 803 804 // First collect all the metadata to delete in a vector, then 805 // delete them all at once to avoid invalidating the iterator 806 std::vector<NamedMDNode *> ToDelete; 807 ToDelete.reserve(M->named_metadata_size() - Names.size()); 808 for (auto &NamedMD : M->named_metadata()) 809 // Always keep a nonempty llvm.dbg.cu because the Verifier would complain. 810 if (!Names.count(NamedMD.getName()) && 811 (!(NamedMD.getName() == "llvm.dbg.cu" && NamedMD.getNumOperands() > 0))) 812 ToDelete.push_back(&NamedMD); 813 814 for (auto *NamedMD : ToDelete) 815 NamedMD->eraseFromParent(); 816 817 // Verify that this is still valid. 818 legacy::PassManager Passes; 819 Passes.add(createVerifierPass(/*FatalErrors=*/false)); 820 Passes.run(*M); 821 822 // Try running on the hacked up program... 823 if (TestFn(BD, M)) { 824 BD.setNewProgram(M); // It crashed, keep the trimmed version... 825 return true; 826 } 827 delete M; // It didn't crash, try something else. 828 return false; 829 } 830 831 namespace { 832 // Reduce the list of operands to named metadata nodes 833 class ReduceCrashingNamedMDOps : public ListReducer<const MDNode *> { 834 BugDriver &BD; 835 bool (*TestFn)(const BugDriver &, Module *); 836 837 public: 838 ReduceCrashingNamedMDOps(BugDriver &bd, 839 bool (*testFn)(const BugDriver &, Module *)) 840 : BD(bd), TestFn(testFn) {} 841 842 Expected<TestResult> doTest(std::vector<const MDNode *> &Prefix, 843 std::vector<const MDNode *> &Kept) override { 844 if (!Kept.empty() && TestNamedMDOps(Kept)) 845 return KeepSuffix; 846 if (!Prefix.empty() && TestNamedMDOps(Prefix)) 847 return KeepPrefix; 848 return NoFailure; 849 } 850 851 bool TestNamedMDOps(std::vector<const MDNode *> &NamedMDOps); 852 }; 853 } 854 855 bool ReduceCrashingNamedMDOps::TestNamedMDOps( 856 std::vector<const MDNode *> &NamedMDOps) { 857 // Convert list to set for fast lookup... 858 SmallPtrSet<const MDNode *, 32> OldMDNodeOps; 859 for (unsigned i = 0, e = NamedMDOps.size(); i != e; ++i) { 860 OldMDNodeOps.insert(NamedMDOps[i]); 861 } 862 863 outs() << "Checking for crash with only " << OldMDNodeOps.size(); 864 if (OldMDNodeOps.size() == 1) 865 outs() << " named metadata operand: "; 866 else 867 outs() << " named metadata operands: "; 868 869 ValueToValueMapTy VMap; 870 Module *M = CloneModule(BD.getProgram(), VMap).release(); 871 872 // This is a little wasteful. In the future it might be good if we could have 873 // these dropped during cloning. 874 for (auto &NamedMD : BD.getProgram()->named_metadata()) { 875 // Drop the old one and create a new one 876 M->eraseNamedMetadata(M->getNamedMetadata(NamedMD.getName())); 877 NamedMDNode *NewNamedMDNode = 878 M->getOrInsertNamedMetadata(NamedMD.getName()); 879 for (MDNode *op : NamedMD.operands()) 880 if (OldMDNodeOps.count(op)) 881 NewNamedMDNode->addOperand(cast<MDNode>(MapMetadata(op, VMap))); 882 } 883 884 // Verify that this is still valid. 885 legacy::PassManager Passes; 886 Passes.add(createVerifierPass(/*FatalErrors=*/false)); 887 Passes.run(*M); 888 889 // Try running on the hacked up program... 890 if (TestFn(BD, M)) { 891 // Make sure to use instruction pointers that point into the now-current 892 // module, and that they don't include any deleted blocks. 893 NamedMDOps.clear(); 894 for (const MDNode *Node : OldMDNodeOps) 895 NamedMDOps.push_back(cast<MDNode>(*VMap.getMappedMD(Node))); 896 897 BD.setNewProgram(M); // It crashed, keep the trimmed version... 898 return true; 899 } 900 delete M; // It didn't crash, try something else. 901 return false; 902 } 903 904 static Error ReduceGlobalInitializers(BugDriver &BD, 905 bool (*TestFn)(const BugDriver &, 906 Module *)) { 907 if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) { 908 // Now try to reduce the number of global variable initializers in the 909 // module to something small. 910 Module *M = CloneModule(BD.getProgram()).release(); 911 bool DeletedInit = false; 912 913 for (Module::global_iterator I = M->global_begin(), E = M->global_end(); 914 I != E; ++I) 915 if (I->hasInitializer()) { 916 DeleteGlobalInitializer(&*I); 917 I->setLinkage(GlobalValue::ExternalLinkage); 918 I->setComdat(nullptr); 919 DeletedInit = true; 920 } 921 922 if (!DeletedInit) { 923 delete M; // No change made... 924 } else { 925 // See if the program still causes a crash... 926 outs() << "\nChecking to see if we can delete global inits: "; 927 928 if (TestFn(BD, M)) { // Still crashes? 929 BD.setNewProgram(M); 930 outs() << "\n*** Able to remove all global initializers!\n"; 931 } else { // No longer crashes? 932 outs() << " - Removing all global inits hides problem!\n"; 933 delete M; 934 935 std::vector<GlobalVariable *> GVs; 936 937 for (Module::global_iterator I = BD.getProgram()->global_begin(), 938 E = BD.getProgram()->global_end(); 939 I != E; ++I) 940 if (I->hasInitializer()) 941 GVs.push_back(&*I); 942 943 if (GVs.size() > 1 && !BugpointIsInterrupted) { 944 outs() << "\n*** Attempting to reduce the number of global " 945 << "variables in the testcase\n"; 946 947 unsigned OldSize = GVs.size(); 948 Expected<bool> Result = 949 ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs); 950 if (Error E = Result.takeError()) 951 return E; 952 953 if (GVs.size() < OldSize) 954 BD.EmitProgressBitcode(BD.getProgram(), "reduced-global-variables"); 955 } 956 } 957 } 958 } 959 return Error::success(); 960 } 961 962 static Error ReduceInsts(BugDriver &BD, 963 bool (*TestFn)(const BugDriver &, Module *)) { 964 // Attempt to delete instructions using bisection. This should help out nasty 965 // cases with large basic blocks where the problem is at one end. 966 if (!BugpointIsInterrupted) { 967 std::vector<const Instruction *> Insts; 968 for (const Function &F : *BD.getProgram()) 969 for (const BasicBlock &BB : F) 970 for (const Instruction &I : BB) 971 if (!isa<TerminatorInst>(&I)) 972 Insts.push_back(&I); 973 974 Expected<bool> Result = 975 ReduceCrashingInstructions(BD, TestFn).reduceList(Insts); 976 if (Error E = Result.takeError()) 977 return E; 978 } 979 980 unsigned Simplification = 2; 981 do { 982 if (BugpointIsInterrupted) 983 // TODO: Should we distinguish this with an "interrupted error"? 984 return Error::success(); 985 --Simplification; 986 outs() << "\n*** Attempting to reduce testcase by deleting instruc" 987 << "tions: Simplification Level #" << Simplification << '\n'; 988 989 // Now that we have deleted the functions that are unnecessary for the 990 // program, try to remove instructions that are not necessary to cause the 991 // crash. To do this, we loop through all of the instructions in the 992 // remaining functions, deleting them (replacing any values produced with 993 // nulls), and then running ADCE and SimplifyCFG. If the transformed input 994 // still triggers failure, keep deleting until we cannot trigger failure 995 // anymore. 996 // 997 unsigned InstructionsToSkipBeforeDeleting = 0; 998 TryAgain: 999 1000 // Loop over all of the (non-terminator) instructions remaining in the 1001 // function, attempting to delete them. 1002 unsigned CurInstructionNum = 0; 1003 for (Module::const_iterator FI = BD.getProgram()->begin(), 1004 E = BD.getProgram()->end(); 1005 FI != E; ++FI) 1006 if (!FI->isDeclaration()) 1007 for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E; 1008 ++BI) 1009 for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end(); 1010 I != E; ++I, ++CurInstructionNum) { 1011 if (InstructionsToSkipBeforeDeleting) { 1012 --InstructionsToSkipBeforeDeleting; 1013 } else { 1014 if (BugpointIsInterrupted) 1015 // TODO: Should this be some kind of interrupted error? 1016 return Error::success(); 1017 1018 if (I->isEHPad() || I->getType()->isTokenTy()) 1019 continue; 1020 1021 outs() << "Checking instruction: " << *I; 1022 std::unique_ptr<Module> M = 1023 BD.deleteInstructionFromProgram(&*I, Simplification); 1024 1025 // Find out if the pass still crashes on this pass... 1026 if (TestFn(BD, M.get())) { 1027 // Yup, it does, we delete the old module, and continue trying 1028 // to reduce the testcase... 1029 BD.setNewProgram(M.release()); 1030 InstructionsToSkipBeforeDeleting = CurInstructionNum; 1031 goto TryAgain; // I wish I had a multi-level break here! 1032 } 1033 } 1034 } 1035 1036 if (InstructionsToSkipBeforeDeleting) { 1037 InstructionsToSkipBeforeDeleting = 0; 1038 goto TryAgain; 1039 } 1040 1041 } while (Simplification); 1042 BD.EmitProgressBitcode(BD.getProgram(), "reduced-instructions"); 1043 return Error::success(); 1044 } 1045 1046 /// DebugACrash - Given a predicate that determines whether a component crashes 1047 /// on a program, try to destructively reduce the program while still keeping 1048 /// the predicate true. 1049 static Error DebugACrash(BugDriver &BD, 1050 bool (*TestFn)(const BugDriver &, Module *)) { 1051 // See if we can get away with nuking some of the global variable initializers 1052 // in the program... 1053 if (!NoGlobalRM) 1054 if (Error E = ReduceGlobalInitializers(BD, TestFn)) 1055 return E; 1056 1057 // Now try to reduce the number of functions in the module to something small. 1058 std::vector<Function *> Functions; 1059 for (Function &F : *BD.getProgram()) 1060 if (!F.isDeclaration()) 1061 Functions.push_back(&F); 1062 1063 if (Functions.size() > 1 && !BugpointIsInterrupted) { 1064 outs() << "\n*** Attempting to reduce the number of functions " 1065 "in the testcase\n"; 1066 1067 unsigned OldSize = Functions.size(); 1068 Expected<bool> Result = 1069 ReduceCrashingFunctions(BD, TestFn).reduceList(Functions); 1070 if (Error E = Result.takeError()) 1071 return E; 1072 1073 if (Functions.size() < OldSize) 1074 BD.EmitProgressBitcode(BD.getProgram(), "reduced-function"); 1075 } 1076 1077 // Attempt to change conditional branches into unconditional branches to 1078 // eliminate blocks. 1079 if (!DisableSimplifyCFG && !BugpointIsInterrupted) { 1080 std::vector<const BasicBlock *> Blocks; 1081 for (Function &F : *BD.getProgram()) 1082 for (BasicBlock &BB : F) 1083 Blocks.push_back(&BB); 1084 unsigned OldSize = Blocks.size(); 1085 Expected<bool> Result = 1086 ReduceCrashingConditionals(BD, TestFn, true).reduceList(Blocks); 1087 if (Error E = Result.takeError()) 1088 return E; 1089 Result = ReduceCrashingConditionals(BD, TestFn, false).reduceList(Blocks); 1090 if (Error E = Result.takeError()) 1091 return E; 1092 if (Blocks.size() < OldSize) 1093 BD.EmitProgressBitcode(BD.getProgram(), "reduced-conditionals"); 1094 } 1095 1096 // Attempt to delete entire basic blocks at a time to speed up 1097 // convergence... this actually works by setting the terminator of the blocks 1098 // to a return instruction then running simplifycfg, which can potentially 1099 // shrinks the code dramatically quickly 1100 // 1101 if (!DisableSimplifyCFG && !BugpointIsInterrupted) { 1102 std::vector<const BasicBlock *> Blocks; 1103 for (Function &F : *BD.getProgram()) 1104 for (BasicBlock &BB : F) 1105 Blocks.push_back(&BB); 1106 unsigned OldSize = Blocks.size(); 1107 Expected<bool> Result = ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks); 1108 if (Error E = Result.takeError()) 1109 return E; 1110 if (Blocks.size() < OldSize) 1111 BD.EmitProgressBitcode(BD.getProgram(), "reduced-blocks"); 1112 } 1113 1114 if (!DisableSimplifyCFG & !BugpointIsInterrupted) { 1115 std::vector<const BasicBlock *> Blocks; 1116 for (Function &F : *BD.getProgram()) 1117 for (BasicBlock &BB : F) 1118 Blocks.push_back(&BB); 1119 unsigned OldSize = Blocks.size(); 1120 Expected<bool> Result = ReduceSimplifyCFG(BD, TestFn).reduceList(Blocks); 1121 if (Error E = Result.takeError()) 1122 return E; 1123 if (Blocks.size() < OldSize) 1124 BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplifycfg"); 1125 } 1126 1127 // Attempt to delete instructions using bisection. This should help out nasty 1128 // cases with large basic blocks where the problem is at one end. 1129 if (!BugpointIsInterrupted) 1130 if (Error E = ReduceInsts(BD, TestFn)) 1131 return E; 1132 1133 // Attempt to strip debug info metadata. 1134 auto stripMetadata = [&](std::function<bool(Module &)> strip) { 1135 std::unique_ptr<Module> M = CloneModule(BD.getProgram()); 1136 strip(*M); 1137 if (TestFn(BD, M.get())) 1138 BD.setNewProgram(M.release()); 1139 }; 1140 if (!NoStripDebugInfo && !BugpointIsInterrupted) { 1141 outs() << "\n*** Attempting to strip the debug info: "; 1142 stripMetadata(StripDebugInfo); 1143 } 1144 if (!NoStripDebugTypeInfo && !BugpointIsInterrupted) { 1145 outs() << "\n*** Attempting to strip the debug type info: "; 1146 stripMetadata(stripNonLineTableDebugInfo); 1147 } 1148 1149 if (!NoNamedMDRM) { 1150 if (!BugpointIsInterrupted) { 1151 // Try to reduce the amount of global metadata (particularly debug info), 1152 // by dropping global named metadata that anchors them 1153 outs() << "\n*** Attempting to remove named metadata: "; 1154 std::vector<std::string> NamedMDNames; 1155 for (auto &NamedMD : BD.getProgram()->named_metadata()) 1156 NamedMDNames.push_back(NamedMD.getName().str()); 1157 Expected<bool> Result = 1158 ReduceCrashingNamedMD(BD, TestFn).reduceList(NamedMDNames); 1159 if (Error E = Result.takeError()) 1160 return E; 1161 } 1162 1163 if (!BugpointIsInterrupted) { 1164 // Now that we quickly dropped all the named metadata that doesn't 1165 // contribute to the crash, bisect the operands of the remaining ones 1166 std::vector<const MDNode *> NamedMDOps; 1167 for (auto &NamedMD : BD.getProgram()->named_metadata()) 1168 for (auto op : NamedMD.operands()) 1169 NamedMDOps.push_back(op); 1170 Expected<bool> Result = 1171 ReduceCrashingNamedMDOps(BD, TestFn).reduceList(NamedMDOps); 1172 if (Error E = Result.takeError()) 1173 return E; 1174 } 1175 BD.EmitProgressBitcode(BD.getProgram(), "reduced-named-md"); 1176 } 1177 1178 // Try to clean up the testcase by running funcresolve and globaldce... 1179 if (!BugpointIsInterrupted) { 1180 outs() << "\n*** Attempting to perform final cleanups: "; 1181 Module *M = CloneModule(BD.getProgram()).release(); 1182 M = BD.performFinalCleanups(M, true).release(); 1183 1184 // Find out if the pass still crashes on the cleaned up program... 1185 if (TestFn(BD, M)) { 1186 BD.setNewProgram(M); // Yup, it does, keep the reduced version... 1187 } else { 1188 delete M; 1189 } 1190 } 1191 1192 BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplified"); 1193 1194 return Error::success(); 1195 } 1196 1197 static bool TestForOptimizerCrash(const BugDriver &BD, Module *M) { 1198 return BD.runPasses(M, BD.getPassesToRun()); 1199 } 1200 1201 /// debugOptimizerCrash - This method is called when some pass crashes on input. 1202 /// It attempts to prune down the testcase to something reasonable, and figure 1203 /// out exactly which pass is crashing. 1204 /// 1205 Error BugDriver::debugOptimizerCrash(const std::string &ID) { 1206 outs() << "\n*** Debugging optimizer crash!\n"; 1207 1208 // Reduce the list of passes which causes the optimizer to crash... 1209 if (!BugpointIsInterrupted && !DontReducePassList) { 1210 Expected<bool> Result = ReducePassList(*this).reduceList(PassesToRun); 1211 if (Error E = Result.takeError()) 1212 return E; 1213 } 1214 1215 outs() << "\n*** Found crashing pass" 1216 << (PassesToRun.size() == 1 ? ": " : "es: ") 1217 << getPassesString(PassesToRun) << '\n'; 1218 1219 EmitProgressBitcode(Program, ID); 1220 1221 return DebugACrash(*this, TestForOptimizerCrash); 1222 } 1223 1224 static bool TestForCodeGenCrash(const BugDriver &BD, Module *M) { 1225 if (Error E = BD.compileProgram(M)) { 1226 if (VerboseErrors) 1227 errs() << toString(std::move(E)) << "\n"; 1228 else { 1229 consumeError(std::move(E)); 1230 errs() << "<crash>\n"; 1231 } 1232 return true; // Tool is still crashing. 1233 } 1234 errs() << '\n'; 1235 return false; 1236 } 1237 1238 /// debugCodeGeneratorCrash - This method is called when the code generator 1239 /// crashes on an input. It attempts to reduce the input as much as possible 1240 /// while still causing the code generator to crash. 1241 Error BugDriver::debugCodeGeneratorCrash() { 1242 errs() << "*** Debugging code generator crash!\n"; 1243 1244 return DebugACrash(*this, TestForCodeGenCrash); 1245 } 1246