blob: a472fff0975e9cb56989c11ea52d9abeac79e19f [file] [log] [blame]
Chris Lattner73a6bdd2002-11-20 22:28:10 +00001//===- CrashDebugger.cpp - Debug compilation crashes ----------------------===//
Misha Brukman650ba8e2005-04-22 00:00:37 +00002//
John Criswell09344dc2003-10-20 17:47:21 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner345353d2007-12-29 20:44:31 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Misha Brukman650ba8e2005-04-22 00:00:37 +00007//
John Criswell09344dc2003-10-20 17:47:21 +00008//===----------------------------------------------------------------------===//
Chris Lattner73a6bdd2002-11-20 22:28:10 +00009//
10// This file defines the bugpoint internals that narrow down compilation crashes
11//
12//===----------------------------------------------------------------------===//
13
14#include "BugDriver.h"
Chris Lattner1d080f22003-04-24 22:24:58 +000015#include "ListReducer.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000016#include "ToolRunner.h"
17#include "llvm/ADT/SmallPtrSet.h"
Keno Fischer34ca8312015-11-06 00:12:50 +000018#include "llvm/ADT/StringSet.h"
Justin Bogner8d0a0812016-09-02 01:21:37 +000019#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruth1305dc32014-03-04 11:45:46 +000020#include "llvm/IR/CFG.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000021#include "llvm/IR/Constants.h"
22#include "llvm/IR/DerivedTypes.h"
23#include "llvm/IR/Instructions.h"
Chandler Carruth30d69c22015-02-13 10:01:29 +000024#include "llvm/IR/LegacyPassManager.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000025#include "llvm/IR/Module.h"
26#include "llvm/IR/ValueSymbolTable.h"
Chandler Carruth5ad5f152014-01-13 09:26:24 +000027#include "llvm/IR/Verifier.h"
Misha Brukman0c2305b2003-08-07 21:19:30 +000028#include "llvm/Pass.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000029#include "llvm/Support/CommandLine.h"
30#include "llvm/Support/FileUtilities.h"
Chris Lattnerf32939b2003-04-24 23:51:38 +000031#include "llvm/Transforms/Scalar.h"
Daniel Berlin271ca402016-07-27 16:13:25 +000032#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Chris Lattner1d080f22003-04-24 22:24:58 +000033#include "llvm/Transforms/Utils/Cloning.h"
Daniel Berlin271ca402016-07-27 16:13:25 +000034#include "llvm/Transforms/Utils/Local.h"
Chris Lattner1d080f22003-04-24 22:24:58 +000035#include <set>
Chris Lattner2f1aa112004-01-14 03:38:37 +000036using namespace llvm;
Chris Lattner73a6bdd2002-11-20 22:28:10 +000037
Andrew Lenharthef9aa122006-03-05 22:21:36 +000038namespace {
Justin Bogner8d0a0812016-09-02 01:21:37 +000039cl::opt<bool> KeepMain("keep-main",
40 cl::desc("Force function reduction to keep main"),
41 cl::init(false));
42cl::opt<bool> NoGlobalRM("disable-global-remove",
43 cl::desc("Do not remove global variables"),
44 cl::init(false));
JF Bastienf87e20d2015-04-20 23:42:22 +000045
Justin Bogner8d0a0812016-09-02 01:21:37 +000046cl::opt<bool> ReplaceFuncsWithNull(
47 "replace-funcs-with-null",
48 cl::desc("When stubbing functions, replace all uses will null"),
49 cl::init(false));
50cl::opt<bool> DontReducePassList("disable-pass-list-reduction",
51 cl::desc("Skip pass list reduction steps"),
52 cl::init(false));
Keno Fischer34ca8312015-11-06 00:12:50 +000053
Justin Bogner8d0a0812016-09-02 01:21:37 +000054cl::opt<bool> NoNamedMDRM("disable-namedmd-remove",
55 cl::desc("Do not remove global named metadata"),
56 cl::init(false));
57cl::opt<bool> VerboseErrors("verbose-errors",
Sebastian Pop8f7d0192016-07-15 23:15:06 +000058 cl::desc("Print the output of crashing program"),
59 cl::init(false));
Andrew Lenharthef9aa122006-03-05 22:21:36 +000060}
61
Brian Gaeke960707c2003-11-11 22:41:34 +000062namespace llvm {
Justin Bogner8d0a0812016-09-02 01:21:37 +000063class ReducePassList : public ListReducer<std::string> {
64 BugDriver &BD;
Misha Brukman650ba8e2005-04-22 00:00:37 +000065
Justin Bogner8d0a0812016-09-02 01:21:37 +000066public:
67 ReducePassList(BugDriver &bd) : BD(bd) {}
68
Justin Bogner1c039152016-09-06 17:18:22 +000069 // Return true iff running the "removed" passes succeeds, and running the
70 // "Kept" passes fail when run on the output of the "removed" passes. If we
71 // return true, we update the current module of bugpoint.
72 Expected<TestResult> doTest(std::vector<std::string> &Removed,
73 std::vector<std::string> &Kept) override;
Justin Bogner8d0a0812016-09-02 01:21:37 +000074};
Chris Lattner2f1aa112004-01-14 03:38:37 +000075}
Chris Lattner1d080f22003-04-24 22:24:58 +000076
Justin Bogner1c039152016-09-06 17:18:22 +000077Expected<ReducePassList::TestResult>
Rafael Espindola33e81a82010-08-08 03:55:08 +000078ReducePassList::doTest(std::vector<std::string> &Prefix,
Justin Bogner1c039152016-09-06 17:18:22 +000079 std::vector<std::string> &Suffix) {
Rafael Espindolabb876652013-06-17 19:33:18 +000080 std::string PrefixOutput;
Craig Toppere6cb63e2014-04-25 04:24:47 +000081 Module *OrigProgram = nullptr;
Chris Lattner1d080f22003-04-24 22:24:58 +000082 if (!Prefix.empty()) {
Dan Gohmanee051522009-07-16 15:30:09 +000083 outs() << "Checking to see if these passes crash: "
84 << getPassesString(Prefix) << ": ";
Rafael Espindolabb876652013-06-17 19:33:18 +000085 if (BD.runPasses(BD.getProgram(), Prefix, PrefixOutput))
Chris Lattner1d080f22003-04-24 22:24:58 +000086 return KeepPrefix;
Chris Lattnera9656312003-06-02 04:54:29 +000087
88 OrigProgram = BD.Program;
89
Rafael Espindola28b351a2014-08-26 17:19:03 +000090 BD.Program = parseInputFile(PrefixOutput, BD.getContext()).release();
Craig Toppere6cb63e2014-04-25 04:24:47 +000091 if (BD.Program == nullptr) {
Dan Gohmand8db3762009-07-15 16:35:29 +000092 errs() << BD.getToolName() << ": Error reading bitcode file '"
Rafael Espindolabb876652013-06-17 19:33:18 +000093 << PrefixOutput << "'!\n";
Chris Lattnera9656312003-06-02 04:54:29 +000094 exit(1);
95 }
Rafael Espindolabb876652013-06-17 19:33:18 +000096 sys::fs::remove(PrefixOutput);
Chris Lattner1d080f22003-04-24 22:24:58 +000097 }
98
Justin Bogner8d0a0812016-09-02 01:21:37 +000099 outs() << "Checking to see if these passes crash: " << getPassesString(Suffix)
100 << ": ";
Misha Brukman650ba8e2005-04-22 00:00:37 +0000101
Rafael Espindola37302ea2010-08-05 02:16:32 +0000102 if (BD.runPasses(BD.getProgram(), Suffix)) {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000103 delete OrigProgram; // The suffix crashes alone...
Chris Lattner1d080f22003-04-24 22:24:58 +0000104 return KeepSuffix;
105 }
106
107 // Nothing failed, restore state...
Chris Lattnera9656312003-06-02 04:54:29 +0000108 if (OrigProgram) {
109 delete BD.Program;
110 BD.Program = OrigProgram;
111 }
Chris Lattner1d080f22003-04-24 22:24:58 +0000112 return NoFailure;
113}
114
Bill Wendling3f833432006-10-25 18:36:14 +0000115namespace {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000116/// ReduceCrashingGlobalVariables - This works by removing the global
117/// variable's initializer and seeing if the program still crashes. If it
118/// does, then we keep that program and try again.
119///
120class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable *> {
121 BugDriver &BD;
122 bool (*TestFn)(const BugDriver &, Module *);
123
124public:
125 ReduceCrashingGlobalVariables(BugDriver &bd,
126 bool (*testFn)(const BugDriver &, Module *))
Bill Wendling3f833432006-10-25 18:36:14 +0000127 : BD(bd), TestFn(testFn) {}
128
Justin Bogner1c039152016-09-06 17:18:22 +0000129 Expected<TestResult> doTest(std::vector<GlobalVariable *> &Prefix,
130 std::vector<GlobalVariable *> &Kept) override {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000131 if (!Kept.empty() && TestGlobalVariables(Kept))
132 return KeepSuffix;
133 if (!Prefix.empty() && TestGlobalVariables(Prefix))
134 return KeepPrefix;
135 return NoFailure;
136 }
Bill Wendling3f833432006-10-25 18:36:14 +0000137
Justin Bogner8d0a0812016-09-02 01:21:37 +0000138 bool TestGlobalVariables(std::vector<GlobalVariable *> &GVs);
139};
Bill Wendling3f833432006-10-25 18:36:14 +0000140}
141
Justin Bogner8d0a0812016-09-02 01:21:37 +0000142bool ReduceCrashingGlobalVariables::TestGlobalVariables(
143 std::vector<GlobalVariable *> &GVs) {
Bill Wendling3f833432006-10-25 18:36:14 +0000144 // Clone the program to try hacking it apart...
Rafael Espindola229e38f2010-10-13 01:36:30 +0000145 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000146 Module *M = CloneModule(BD.getProgram(), VMap).release();
Bill Wendling3f833432006-10-25 18:36:14 +0000147
148 // Convert list to set for fast lookup...
Justin Bogner8d0a0812016-09-02 01:21:37 +0000149 std::set<GlobalVariable *> GVSet;
Bill Wendling3f833432006-10-25 18:36:14 +0000150
151 for (unsigned i = 0, e = GVs.size(); i != e; ++i) {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000152 GlobalVariable *CMGV = cast<GlobalVariable>(VMap[GVs[i]]);
Bill Wendling3f833432006-10-25 18:36:14 +0000153 assert(CMGV && "Global Variable not in module?!");
154 GVSet.insert(CMGV);
155 }
156
Dan Gohmanee051522009-07-16 15:30:09 +0000157 outs() << "Checking for crash with only these global variables: ";
Bill Wendling3f833432006-10-25 18:36:14 +0000158 PrintGlobalVariableList(GVs);
Dan Gohmanee051522009-07-16 15:30:09 +0000159 outs() << ": ";
Bill Wendling3f833432006-10-25 18:36:14 +0000160
161 // Loop over and delete any global variables which we aren't supposed to be
162 // playing with...
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000163 for (GlobalVariable &I : M->globals())
164 if (I.hasInitializer() && !GVSet.count(&I)) {
Hal Finkel28ad2b42015-11-26 19:23:49 +0000165 DeleteGlobalInitializer(&I);
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000166 I.setLinkage(GlobalValue::ExternalLinkage);
Justin Lebar2a445cf2016-06-15 23:20:12 +0000167 I.setComdat(nullptr);
Bill Wendling3f833432006-10-25 18:36:14 +0000168 }
169
170 // Try running the hacked up program...
171 if (TestFn(BD, M)) {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000172 BD.setNewProgram(M); // It crashed, keep the trimmed version...
Bill Wendling3f833432006-10-25 18:36:14 +0000173
174 // Make sure to use global variable pointers that point into the now-current
175 // module.
176 GVs.assign(GVSet.begin(), GVSet.end());
177 return true;
178 }
179
180 delete M;
181 return false;
182}
183
David Blaikiea379b1812011-12-20 02:50:00 +0000184namespace {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000185/// ReduceCrashingFunctions reducer - This works by removing functions and
186/// seeing if the program still crashes. If it does, then keep the newer,
187/// smaller program.
188///
189class ReduceCrashingFunctions : public ListReducer<Function *> {
190 BugDriver &BD;
191 bool (*TestFn)(const BugDriver &, Module *);
192
193public:
194 ReduceCrashingFunctions(BugDriver &bd,
195 bool (*testFn)(const BugDriver &, Module *))
Chris Lattner8bda4c42004-02-18 23:26:28 +0000196 : BD(bd), TestFn(testFn) {}
Misha Brukman650ba8e2005-04-22 00:00:37 +0000197
Justin Bogner1c039152016-09-06 17:18:22 +0000198 Expected<TestResult> doTest(std::vector<Function *> &Prefix,
199 std::vector<Function *> &Kept) override {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000200 if (!Kept.empty() && TestFuncs(Kept))
201 return KeepSuffix;
202 if (!Prefix.empty() && TestFuncs(Prefix))
203 return KeepPrefix;
204 return NoFailure;
205 }
Misha Brukman650ba8e2005-04-22 00:00:37 +0000206
Justin Bogner8d0a0812016-09-02 01:21:37 +0000207 bool TestFuncs(std::vector<Function *> &Prefix);
208};
Chris Lattner2f1aa112004-01-14 03:38:37 +0000209}
Chris Lattner1d080f22003-04-24 22:24:58 +0000210
Justin Bogner8d0a0812016-09-02 01:21:37 +0000211static void RemoveFunctionReferences(Module *M, const char *Name) {
JF Bastienf87e20d2015-04-20 23:42:22 +0000212 auto *UsedVar = M->getGlobalVariable(Name, true);
Justin Bogner8d0a0812016-09-02 01:21:37 +0000213 if (!UsedVar || !UsedVar->hasInitializer())
214 return;
JF Bastienf87e20d2015-04-20 23:42:22 +0000215 if (isa<ConstantAggregateZero>(UsedVar->getInitializer())) {
216 assert(UsedVar->use_empty());
217 UsedVar->eraseFromParent();
218 return;
219 }
220 auto *OldUsedVal = cast<ConstantArray>(UsedVar->getInitializer());
Justin Bogner8d0a0812016-09-02 01:21:37 +0000221 std::vector<Constant *> Used;
222 for (Value *V : OldUsedVal->operand_values()) {
JF Bastienf87e20d2015-04-20 23:42:22 +0000223 Constant *Op = cast<Constant>(V->stripPointerCasts());
Justin Bogner8d0a0812016-09-02 01:21:37 +0000224 if (!Op->isNullValue()) {
JF Bastienf87e20d2015-04-20 23:42:22 +0000225 Used.push_back(cast<Constant>(V));
226 }
227 }
228 auto *NewValElemTy = OldUsedVal->getType()->getElementType();
229 auto *NewValTy = ArrayType::get(NewValElemTy, Used.size());
230 auto *NewUsedVal = ConstantArray::get(NewValTy, Used);
231 UsedVar->mutateType(NewUsedVal->getType()->getPointerTo());
232 UsedVar->setInitializer(NewUsedVal);
233}
234
Justin Bogner8d0a0812016-09-02 01:21:37 +0000235bool ReduceCrashingFunctions::TestFuncs(std::vector<Function *> &Funcs) {
Dmitri Gribenko6e0520e2013-09-02 01:18:56 +0000236 // If main isn't present, claim there is no problem.
David Majnemer0d955d02016-08-11 22:21:41 +0000237 if (KeepMain && !is_contained(Funcs, BD.getProgram()->getFunction("main")))
Andrew Lenharthef9aa122006-03-05 22:21:36 +0000238 return false;
239
Misha Brukman8b2bd4e2003-10-10 17:57:28 +0000240 // Clone the program to try hacking it apart...
Rafael Espindola229e38f2010-10-13 01:36:30 +0000241 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000242 Module *M = CloneModule(BD.getProgram(), VMap).release();
Misha Brukman650ba8e2005-04-22 00:00:37 +0000243
Chris Lattner1d080f22003-04-24 22:24:58 +0000244 // Convert list to set for fast lookup...
Justin Bogner8d0a0812016-09-02 01:21:37 +0000245 std::set<Function *> Functions;
Chris Lattner1d080f22003-04-24 22:24:58 +0000246 for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
Devang Patel0dc3c2d2010-06-24 00:33:28 +0000247 Function *CMF = cast<Function>(VMap[Funcs[i]]);
Chris Lattner1d080f22003-04-24 22:24:58 +0000248 assert(CMF && "Function not in module?!");
Reid Spencer3aaaa0b2007-02-05 20:47:22 +0000249 assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty");
Dan Gohmanbcad7182009-03-06 02:16:23 +0000250 assert(CMF->getName() == Funcs[i]->getName() && "wrong name");
Chris Lattnerde39f2b2003-04-24 22:54:06 +0000251 Functions.insert(CMF);
Chris Lattner1d080f22003-04-24 22:24:58 +0000252 }
253
Dan Gohmanee051522009-07-16 15:30:09 +0000254 outs() << "Checking for crash with only these functions: ";
Chris Lattnerfd72bed2004-03-14 20:50:42 +0000255 PrintFunctionList(Funcs);
Dan Gohmanee051522009-07-16 15:30:09 +0000256 outs() << ": ";
JF Bastienf87e20d2015-04-20 23:42:22 +0000257 if (!ReplaceFuncsWithNull) {
258 // Loop over and delete any functions which we aren't supposed to be playing
259 // with...
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000260 for (Function &I : *M)
261 if (!I.isDeclaration() && !Functions.count(&I))
262 DeleteFunctionBody(&I);
JF Bastienf87e20d2015-04-20 23:42:22 +0000263 } else {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000264 std::vector<GlobalValue *> ToRemove;
JF Bastienf87e20d2015-04-20 23:42:22 +0000265 // First, remove aliases to functions we're about to purge.
266 for (GlobalAlias &Alias : M->aliases()) {
David Majnemer95549492016-05-04 00:20:48 +0000267 GlobalObject *Root = Alias.getBaseObject();
268 Function *F = dyn_cast_or_null<Function>(Root);
JF Bastienf87e20d2015-04-20 23:42:22 +0000269 if (F) {
270 if (Functions.count(F))
271 // We're keeping this function.
272 continue;
273 } else if (Root->isNullValue()) {
274 // This referenced a globalalias that we've already replaced,
275 // so we still need to replace this alias.
276 } else if (!F) {
277 // Not a function, therefore not something we mess with.
278 continue;
279 }
Chris Lattner1d080f22003-04-24 22:24:58 +0000280
JF Bastienf87e20d2015-04-20 23:42:22 +0000281 PointerType *Ty = cast<PointerType>(Alias.getType());
282 Constant *Replacement = ConstantPointerNull::get(Ty);
283 Alias.replaceAllUsesWith(Replacement);
284 ToRemove.push_back(&Alias);
285 }
Chris Lattner1d080f22003-04-24 22:24:58 +0000286
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000287 for (Function &I : *M) {
288 if (!I.isDeclaration() && !Functions.count(&I)) {
289 PointerType *Ty = cast<PointerType>(I.getType());
JF Bastienf87e20d2015-04-20 23:42:22 +0000290 Constant *Replacement = ConstantPointerNull::get(Ty);
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000291 I.replaceAllUsesWith(Replacement);
292 ToRemove.push_back(&I);
JF Bastienf87e20d2015-04-20 23:42:22 +0000293 }
294 }
295
296 for (auto *F : ToRemove) {
297 F->eraseFromParent();
298 }
299
300 // Finally, remove any null members from any global intrinsic.
301 RemoveFunctionReferences(M, "llvm.used");
302 RemoveFunctionReferences(M, "llvm.compiler.used");
303 }
Chris Lattner1d080f22003-04-24 22:24:58 +0000304 // Try running the hacked up program...
Chris Lattner8bda4c42004-02-18 23:26:28 +0000305 if (TestFn(BD, M)) {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000306 BD.setNewProgram(M); // It crashed, keep the trimmed version...
Chris Lattner1d080f22003-04-24 22:24:58 +0000307
308 // Make sure to use function pointers that point into the now-current
309 // module.
310 Funcs.assign(Functions.begin(), Functions.end());
311 return true;
312 }
Chris Lattner327019b2004-02-18 21:24:48 +0000313 delete M;
Chris Lattner1d080f22003-04-24 22:24:58 +0000314 return false;
315}
316
Chris Lattner1942f982004-02-18 21:29:46 +0000317namespace {
Daniel Berlin60606262016-07-28 22:29:25 +0000318/// Simplify the CFG without completely destroying it.
319/// This is not well defined, but basically comes down to "try to eliminate
320/// unreachable blocks and constant fold terminators without deciding that
321/// certain undefined behavior cuts off the program at the legs".
322void simpleSimplifyCfg(Function &F, SmallVectorImpl<BasicBlock *> &BBs) {
323 if (F.empty())
324 return;
325
326 for (auto *BB : BBs) {
327 ConstantFoldTerminator(BB);
328 MergeBlockIntoPredecessor(BB);
329 }
330
331 // Remove unreachable blocks
332 // removeUnreachableBlocks can't be used here, it will turn various
333 // undefined behavior into unreachables, but bugpoint was the thing that
334 // generated the undefined behavior, and we don't want it to kill the entire
335 // program.
336 SmallPtrSet<BasicBlock *, 16> Visited;
337 for (auto *BB : depth_first(&F.getEntryBlock()))
338 Visited.insert(BB);
339
340 SmallVector<BasicBlock *, 16> Unreachable;
341 for (auto &BB : F)
342 if (!Visited.count(&BB))
343 Unreachable.push_back(&BB);
344
345 // The dead BB's may be in a dead cycle or otherwise have references to each
346 // other. Because of this, we have to drop all references first, then delete
347 // them all at once.
Justin Bogner8d0a0812016-09-02 01:21:37 +0000348 for (auto *BB : Unreachable) {
Daniel Berlin60606262016-07-28 22:29:25 +0000349 for (BasicBlock *Successor : successors(&*BB))
350 if (Visited.count(Successor))
351 Successor->removePredecessor(&*BB);
352 BB->dropAllReferences();
353 }
354 for (auto *BB : Unreachable)
355 BB->eraseFromParent();
356}
Justin Bogner8d0a0812016-09-02 01:21:37 +0000357/// ReduceCrashingBlocks reducer - This works by setting the terminators of
358/// all terminators except the specified basic blocks to a 'ret' instruction,
359/// then running the simplify-cfg pass. This has the effect of chopping up
360/// the CFG really fast which can reduce large functions quickly.
361///
362class ReduceCrashingBlocks : public ListReducer<const BasicBlock *> {
363 BugDriver &BD;
364 bool (*TestFn)(const BugDriver &, Module *);
365
366public:
367 ReduceCrashingBlocks(BugDriver &BD,
368 bool (*testFn)(const BugDriver &, Module *))
Daniel Berlin60606262016-07-28 22:29:25 +0000369 : BD(BD), TestFn(testFn) {}
Misha Brukman650ba8e2005-04-22 00:00:37 +0000370
Justin Bogner1c039152016-09-06 17:18:22 +0000371 Expected<TestResult> doTest(std::vector<const BasicBlock *> &Prefix,
372 std::vector<const BasicBlock *> &Kept) override {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000373 if (!Kept.empty() && TestBlocks(Kept))
374 return KeepSuffix;
375 if (!Prefix.empty() && TestBlocks(Prefix))
376 return KeepPrefix;
377 return NoFailure;
378 }
Misha Brukman650ba8e2005-04-22 00:00:37 +0000379
Justin Bogner8d0a0812016-09-02 01:21:37 +0000380 bool TestBlocks(std::vector<const BasicBlock *> &Prefix);
381};
Chris Lattner2f1aa112004-01-14 03:38:37 +0000382}
Chris Lattnerf32939b2003-04-24 23:51:38 +0000383
Justin Bogner8d0a0812016-09-02 01:21:37 +0000384bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock *> &BBs) {
Misha Brukman8b2bd4e2003-10-10 17:57:28 +0000385 // Clone the program to try hacking it apart...
Rafael Espindola229e38f2010-10-13 01:36:30 +0000386 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000387 Module *M = CloneModule(BD.getProgram(), VMap).release();
Misha Brukman650ba8e2005-04-22 00:00:37 +0000388
Chris Lattnerf32939b2003-04-24 23:51:38 +0000389 // Convert list to set for fast lookup...
Justin Bogner8d0a0812016-09-02 01:21:37 +0000390 SmallPtrSet<BasicBlock *, 8> Blocks;
Nick Lewyckyb294e312009-04-04 09:39:23 +0000391 for (unsigned i = 0, e = BBs.size(); i != e; ++i)
Devang Patel0dc3c2d2010-06-24 00:33:28 +0000392 Blocks.insert(cast<BasicBlock>(VMap[BBs[i]]));
Chris Lattnerf32939b2003-04-24 23:51:38 +0000393
Dan Gohmanee051522009-07-16 15:30:09 +0000394 outs() << "Checking for crash with only these blocks:";
Chris Lattner4f50ebd2003-10-27 04:44:59 +0000395 unsigned NumPrint = Blocks.size();
Justin Bogner8d0a0812016-09-02 01:21:37 +0000396 if (NumPrint > 10)
397 NumPrint = 10;
Chris Lattner4f50ebd2003-10-27 04:44:59 +0000398 for (unsigned i = 0, e = NumPrint; i != e; ++i)
Dan Gohmanee051522009-07-16 15:30:09 +0000399 outs() << " " << BBs[i]->getName();
Chris Lattner4f50ebd2003-10-27 04:44:59 +0000400 if (NumPrint < Blocks.size())
Dan Gohmanee051522009-07-16 15:30:09 +0000401 outs() << "... <" << Blocks.size() << " total>";
402 outs() << ": ";
Chris Lattnerf32939b2003-04-24 23:51:38 +0000403
404 // Loop over and delete any hack up any blocks that are not listed...
405 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
406 for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB)
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000407 if (!Blocks.count(&*BB) && BB->getTerminator()->getNumSuccessors()) {
Chris Lattnerf32939b2003-04-24 23:51:38 +0000408 // Loop over all of the successors of this block, deleting any PHI nodes
409 // that might include it.
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000410 for (succ_iterator SI = succ_begin(&*BB), E = succ_end(&*BB); SI != E;
411 ++SI)
412 (*SI)->removePredecessor(&*BB);
Chris Lattnerf32939b2003-04-24 23:51:38 +0000413
Chris Lattner7855a5c2008-04-28 00:04:58 +0000414 TerminatorInst *BBTerm = BB->getTerminator();
Philip Reames29e641c2016-06-29 00:15:35 +0000415 if (BBTerm->isEHPad() || BBTerm->getType()->isTokenTy())
David Majnemer189d7da2015-11-08 04:16:12 +0000416 continue;
Philip Reames29e641c2016-06-29 00:15:35 +0000417 if (!BBTerm->getType()->isVoidTy())
Owen Anderson5a1acd92009-07-31 20:28:14 +0000418 BBTerm->replaceAllUsesWith(Constant::getNullValue(BBTerm->getType()));
Chris Lattner7b233af2003-11-22 02:10:38 +0000419
Chris Lattner7855a5c2008-04-28 00:04:58 +0000420 // Replace the old terminator instruction.
Chris Lattnerf32939b2003-04-24 23:51:38 +0000421 BB->getInstList().pop_back();
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000422 new UnreachableInst(BB->getContext(), &*BB);
Chris Lattnerf32939b2003-04-24 23:51:38 +0000423 }
424
425 // The CFG Simplifier pass may delete one of the basic blocks we are
426 // interested in. If it does we need to take the block out of the list. Make
427 // a "persistent mapping" by turning basic blocks into <function, name> pairs.
428 // This won't work well if blocks are unnamed, but that is just the risk we
429 // have to take.
Justin Bogner8d0a0812016-09-02 01:21:37 +0000430 std::vector<std::pair<std::string, std::string>> BlockInfo;
Chris Lattnerf32939b2003-04-24 23:51:38 +0000431
Craig Topper46276792014-08-24 23:23:06 +0000432 for (BasicBlock *BB : Blocks)
Benjamin Kramerf5e2fc42015-05-29 19:43:39 +0000433 BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName());
Justin Bogner8d0a0812016-09-02 01:21:37 +0000434
Daniel Berlin60606262016-07-28 22:29:25 +0000435 SmallVector<BasicBlock *, 16> ToProcess;
Justin Bogner8d0a0812016-09-02 01:21:37 +0000436 for (auto &F : *M) {
Daniel Berlin60606262016-07-28 22:29:25 +0000437 for (auto &BB : F)
438 if (!Blocks.count(&BB))
439 ToProcess.push_back(&BB);
440 simpleSimplifyCfg(F, ToProcess);
441 ToProcess.clear();
442 }
443 // Verify we didn't break anything
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000444 std::vector<std::string> Passes;
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000445 Passes.push_back("verify");
Rafael Espindola28b351a2014-08-26 17:19:03 +0000446 std::unique_ptr<Module> New = BD.runPassesOn(M, Passes);
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000447 delete M;
448 if (!New) {
Daniel Berlin60606262016-07-28 22:29:25 +0000449 errs() << "verify failed!\n";
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000450 exit(1);
451 }
Rafael Espindola28b351a2014-08-26 17:19:03 +0000452 M = New.release();
Justin Bogner8d0a0812016-09-02 01:21:37 +0000453
Chris Lattnerf32939b2003-04-24 23:51:38 +0000454 // Try running on the hacked up program...
Chris Lattner8bda4c42004-02-18 23:26:28 +0000455 if (TestFn(BD, M)) {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000456 BD.setNewProgram(M); // It crashed, keep the trimmed version...
Chris Lattnerf32939b2003-04-24 23:51:38 +0000457
458 // Make sure to use basic block pointers that point into the now-current
459 // module, and that they don't include any deleted blocks.
460 BBs.clear();
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000461 const ValueSymbolTable &GST = M->getValueSymbolTable();
Chris Lattnerf32939b2003-04-24 23:51:38 +0000462 for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000463 Function *F = cast<Function>(GST.lookup(BlockInfo[i].first));
Mehdi Aminia53d49e2016-09-17 06:00:02 +0000464 Value *V = F->getValueSymbolTable()->lookup(BlockInfo[i].second);
Owen Anderson55f1c092009-08-13 21:58:54 +0000465 if (V && V->getType() == Type::getLabelTy(V->getContext()))
Reid Spencer3aaaa0b2007-02-05 20:47:22 +0000466 BBs.push_back(cast<BasicBlock>(V));
Chris Lattnerf32939b2003-04-24 23:51:38 +0000467 }
468 return true;
469 }
Justin Bogner8d0a0812016-09-02 01:21:37 +0000470 delete M; // It didn't crash, try something else.
Chris Lattnerf32939b2003-04-24 23:51:38 +0000471 return false;
472}
473
Nick Lewycky6e090c92009-05-25 05:30:00 +0000474namespace {
Daniel Berlin271ca402016-07-27 16:13:25 +0000475/// ReduceCrashingConditionals reducer - This works by changing
476/// conditional branches to unconditional ones, then simplifying the CFG
477/// This has the effect of chopping up the CFG really fast which can reduce
478/// large functions quickly.
479///
480class ReduceCrashingConditionals : public ListReducer<const BasicBlock *> {
481 BugDriver &BD;
482 bool (*TestFn)(const BugDriver &, Module *);
483 bool Direction;
484
485public:
486 ReduceCrashingConditionals(BugDriver &bd,
487 bool (*testFn)(const BugDriver &, Module *),
488 bool Direction)
489 : BD(bd), TestFn(testFn), Direction(Direction) {}
490
Justin Bogner1c039152016-09-06 17:18:22 +0000491 Expected<TestResult> doTest(std::vector<const BasicBlock *> &Prefix,
492 std::vector<const BasicBlock *> &Kept) override {
Daniel Berlin271ca402016-07-27 16:13:25 +0000493 if (!Kept.empty() && TestBlocks(Kept))
494 return KeepSuffix;
495 if (!Prefix.empty() && TestBlocks(Prefix))
496 return KeepPrefix;
497 return NoFailure;
498 }
499
500 bool TestBlocks(std::vector<const BasicBlock *> &Prefix);
501};
502}
503
504bool ReduceCrashingConditionals::TestBlocks(
505 std::vector<const BasicBlock *> &BBs) {
506 // Clone the program to try hacking it apart...
507 ValueToValueMapTy VMap;
508 Module *M = CloneModule(BD.getProgram(), VMap).release();
509
510 // Convert list to set for fast lookup...
511 SmallPtrSet<const BasicBlock *, 8> Blocks;
Justin Bogner8d0a0812016-09-02 01:21:37 +0000512 for (const auto *BB : BBs)
Daniel Berlin271ca402016-07-27 16:13:25 +0000513 Blocks.insert(cast<BasicBlock>(VMap[BB]));
514
515 outs() << "Checking for crash with changing conditionals to always jump to "
516 << (Direction ? "true" : "false") << ":";
517 unsigned NumPrint = Blocks.size();
518 if (NumPrint > 10)
519 NumPrint = 10;
520 for (unsigned i = 0, e = NumPrint; i != e; ++i)
521 outs() << " " << BBs[i]->getName();
522 if (NumPrint < Blocks.size())
523 outs() << "... <" << Blocks.size() << " total>";
524 outs() << ": ";
525
526 // Loop over and delete any hack up any blocks that are not listed...
Justin Bogner8d0a0812016-09-02 01:21:37 +0000527 for (auto &F : *M)
Daniel Berlin271ca402016-07-27 16:13:25 +0000528 for (auto &BB : F)
529 if (!Blocks.count(&BB)) {
530 auto *BR = dyn_cast<BranchInst>(BB.getTerminator());
531 if (!BR || !BR->isConditional())
532 continue;
533 if (Direction)
534 BR->setCondition(ConstantInt::getTrue(BR->getContext()));
535 else
536 BR->setCondition(ConstantInt::getFalse(BR->getContext()));
537 }
538
539 // The following may destroy some blocks, so we save them first
540 std::vector<std::pair<std::string, std::string>> BlockInfo;
541
542 for (const BasicBlock *BB : Blocks)
543 BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName());
544
545 SmallVector<BasicBlock *, 16> ToProcess;
Justin Bogner8d0a0812016-09-02 01:21:37 +0000546 for (auto &F : *M) {
Daniel Berlin271ca402016-07-27 16:13:25 +0000547 for (auto &BB : F)
548 if (!Blocks.count(&BB))
549 ToProcess.push_back(&BB);
550 simpleSimplifyCfg(F, ToProcess);
551 ToProcess.clear();
552 }
553 // Verify we didn't break anything
554 std::vector<std::string> Passes;
555 Passes.push_back("verify");
556 std::unique_ptr<Module> New = BD.runPassesOn(M, Passes);
557 delete M;
558 if (!New) {
559 errs() << "verify failed!\n";
560 exit(1);
561 }
562 M = New.release();
563
564 // Try running on the hacked up program...
565 if (TestFn(BD, M)) {
566 BD.setNewProgram(M); // It crashed, keep the trimmed version...
567
568 // Make sure to use basic block pointers that point into the now-current
569 // module, and that they don't include any deleted blocks.
570 BBs.clear();
571 const ValueSymbolTable &GST = M->getValueSymbolTable();
572 for (auto &BI : BlockInfo) {
573 auto *F = cast<Function>(GST.lookup(BI.first));
Mehdi Aminia53d49e2016-09-17 06:00:02 +0000574 Value *V = F->getValueSymbolTable()->lookup(BI.second);
Daniel Berlin271ca402016-07-27 16:13:25 +0000575 if (V && V->getType() == Type::getLabelTy(V->getContext()))
576 BBs.push_back(cast<BasicBlock>(V));
577 }
578 return true;
579 }
580 delete M; // It didn't crash, try something else.
581 return false;
582}
583
584namespace {
Daniel Berlin60606262016-07-28 22:29:25 +0000585/// SimplifyCFG reducer - This works by calling SimplifyCFG on each basic block
586/// in the program.
587
588class ReduceSimplifyCFG : public ListReducer<const BasicBlock *> {
589 BugDriver &BD;
590 bool (*TestFn)(const BugDriver &, Module *);
591 TargetTransformInfo TTI;
Justin Bogner8d0a0812016-09-02 01:21:37 +0000592
Daniel Berlin60606262016-07-28 22:29:25 +0000593public:
Justin Bogner8d0a0812016-09-02 01:21:37 +0000594 ReduceSimplifyCFG(BugDriver &bd, bool (*testFn)(const BugDriver &, Module *))
595 : BD(bd), TestFn(testFn), TTI(bd.getProgram()->getDataLayout()) {}
Daniel Berlin60606262016-07-28 22:29:25 +0000596
Justin Bogner1c039152016-09-06 17:18:22 +0000597 Expected<TestResult> doTest(std::vector<const BasicBlock *> &Prefix,
598 std::vector<const BasicBlock *> &Kept) override {
Daniel Berlin60606262016-07-28 22:29:25 +0000599 if (!Kept.empty() && TestBlocks(Kept))
600 return KeepSuffix;
601 if (!Prefix.empty() && TestBlocks(Prefix))
602 return KeepPrefix;
603 return NoFailure;
604 }
605
606 bool TestBlocks(std::vector<const BasicBlock *> &Prefix);
607};
608}
609
Justin Bogner8d0a0812016-09-02 01:21:37 +0000610bool ReduceSimplifyCFG::TestBlocks(std::vector<const BasicBlock *> &BBs) {
Daniel Berlin60606262016-07-28 22:29:25 +0000611 // Clone the program to try hacking it apart...
612 ValueToValueMapTy VMap;
613 Module *M = CloneModule(BD.getProgram(), VMap).release();
614
615 // Convert list to set for fast lookup...
616 SmallPtrSet<const BasicBlock *, 8> Blocks;
Justin Bogner8d0a0812016-09-02 01:21:37 +0000617 for (const auto *BB : BBs)
Daniel Berlin60606262016-07-28 22:29:25 +0000618 Blocks.insert(cast<BasicBlock>(VMap[BB]));
619
620 outs() << "Checking for crash with CFG simplifying:";
621 unsigned NumPrint = Blocks.size();
622 if (NumPrint > 10)
623 NumPrint = 10;
624 for (unsigned i = 0, e = NumPrint; i != e; ++i)
625 outs() << " " << BBs[i]->getName();
626 if (NumPrint < Blocks.size())
627 outs() << "... <" << Blocks.size() << " total>";
628 outs() << ": ";
629
Justin Bogner8d0a0812016-09-02 01:21:37 +0000630 // The following may destroy some blocks, so we save them first
Daniel Berlin60606262016-07-28 22:29:25 +0000631 std::vector<std::pair<std::string, std::string>> BlockInfo;
632
633 for (const BasicBlock *BB : Blocks)
634 BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName());
635
Daniel Berlin60606262016-07-28 22:29:25 +0000636 // Loop over and delete any hack up any blocks that are not listed...
Justin Bogner8d0a0812016-09-02 01:21:37 +0000637 for (auto &F : *M)
638 // Loop over all of the basic blocks and remove them if they are unneeded.
639 for (Function::iterator BBIt = F.begin(); BBIt != F.end();) {
640 if (!Blocks.count(&*BBIt)) {
641 ++BBIt;
642 continue;
643 }
644 SimplifyCFG(&*BBIt++, TTI, 1);
645 }
Daniel Berlin60606262016-07-28 22:29:25 +0000646 // Verify we didn't break anything
647 std::vector<std::string> Passes;
648 Passes.push_back("verify");
649 std::unique_ptr<Module> New = BD.runPassesOn(M, Passes);
650 delete M;
651 if (!New) {
652 errs() << "verify failed!\n";
653 exit(1);
654 }
655 M = New.release();
656
657 // Try running on the hacked up program...
658 if (TestFn(BD, M)) {
659 BD.setNewProgram(M); // It crashed, keep the trimmed version...
660
661 // Make sure to use basic block pointers that point into the now-current
662 // module, and that they don't include any deleted blocks.
663 BBs.clear();
664 const ValueSymbolTable &GST = M->getValueSymbolTable();
Justin Bogner8d0a0812016-09-02 01:21:37 +0000665 for (auto &BI : BlockInfo) {
Daniel Berlin60606262016-07-28 22:29:25 +0000666 auto *F = cast<Function>(GST.lookup(BI.first));
Mehdi Aminia53d49e2016-09-17 06:00:02 +0000667 Value *V = F->getValueSymbolTable()->lookup(BI.second);
Daniel Berlin60606262016-07-28 22:29:25 +0000668 if (V && V->getType() == Type::getLabelTy(V->getContext()))
669 BBs.push_back(cast<BasicBlock>(V));
670 }
671 return true;
672 }
673 delete M; // It didn't crash, try something else.
674 return false;
675}
676
677namespace {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000678/// ReduceCrashingInstructions reducer - This works by removing the specified
679/// non-terminator instructions and replacing them with undef.
680///
681class ReduceCrashingInstructions : public ListReducer<const Instruction *> {
682 BugDriver &BD;
683 bool (*TestFn)(const BugDriver &, Module *);
684
685public:
686 ReduceCrashingInstructions(BugDriver &bd,
687 bool (*testFn)(const BugDriver &, Module *))
Nick Lewycky6e090c92009-05-25 05:30:00 +0000688 : BD(bd), TestFn(testFn) {}
689
Justin Bogner1c039152016-09-06 17:18:22 +0000690 Expected<TestResult> doTest(std::vector<const Instruction *> &Prefix,
691 std::vector<const Instruction *> &Kept) override {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000692 if (!Kept.empty() && TestInsts(Kept))
693 return KeepSuffix;
694 if (!Prefix.empty() && TestInsts(Prefix))
695 return KeepPrefix;
696 return NoFailure;
697 }
Nick Lewycky6e090c92009-05-25 05:30:00 +0000698
Justin Bogner8d0a0812016-09-02 01:21:37 +0000699 bool TestInsts(std::vector<const Instruction *> &Prefix);
700};
Nick Lewycky6e090c92009-05-25 05:30:00 +0000701}
702
Justin Bogner8d0a0812016-09-02 01:21:37 +0000703bool ReduceCrashingInstructions::TestInsts(
704 std::vector<const Instruction *> &Insts) {
Nick Lewycky6e090c92009-05-25 05:30:00 +0000705 // Clone the program to try hacking it apart...
Rafael Espindola229e38f2010-10-13 01:36:30 +0000706 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000707 Module *M = CloneModule(BD.getProgram(), VMap).release();
Nick Lewycky6e090c92009-05-25 05:30:00 +0000708
709 // Convert list to set for fast lookup...
Justin Bogner8d0a0812016-09-02 01:21:37 +0000710 SmallPtrSet<Instruction *, 32> Instructions;
Nick Lewycky6e090c92009-05-25 05:30:00 +0000711 for (unsigned i = 0, e = Insts.size(); i != e; ++i) {
712 assert(!isa<TerminatorInst>(Insts[i]));
Devang Patel0dc3c2d2010-06-24 00:33:28 +0000713 Instructions.insert(cast<Instruction>(VMap[Insts[i]]));
Nick Lewycky6e090c92009-05-25 05:30:00 +0000714 }
715
Dan Gohmanee051522009-07-16 15:30:09 +0000716 outs() << "Checking for crash with only " << Instructions.size();
Nick Lewycky6e090c92009-05-25 05:30:00 +0000717 if (Instructions.size() == 1)
Dan Gohmanee051522009-07-16 15:30:09 +0000718 outs() << " instruction: ";
Nick Lewycky6e090c92009-05-25 05:30:00 +0000719 else
Dan Gohmanee051522009-07-16 15:30:09 +0000720 outs() << " instructions: ";
Nick Lewycky6e090c92009-05-25 05:30:00 +0000721
722 for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
723 for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI)
724 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) {
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000725 Instruction *Inst = &*I++;
Eli Friedmand4e02a52011-11-01 04:40:56 +0000726 if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst) &&
Philip Reames29e641c2016-06-29 00:15:35 +0000727 !Inst->isEHPad() && !Inst->getType()->isTokenTy()) {
728 if (!Inst->getType()->isVoidTy())
Nick Lewycky6e090c92009-05-25 05:30:00 +0000729 Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
730 Inst->eraseFromParent();
731 }
732 }
733
734 // Verify that this is still valid.
Chandler Carruth30d69c22015-02-13 10:01:29 +0000735 legacy::PassManager Passes;
Adrian Prantl919bdf12016-10-18 16:24:43 +0000736 Passes.add(createVerifierPass(/*FatalErrors=*/false));
Nick Lewycky6e090c92009-05-25 05:30:00 +0000737 Passes.run(*M);
738
739 // Try running on the hacked up program...
740 if (TestFn(BD, M)) {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000741 BD.setNewProgram(M); // It crashed, keep the trimmed version...
Nick Lewycky6e090c92009-05-25 05:30:00 +0000742
743 // Make sure to use instruction pointers that point into the now-current
744 // module, and that they don't include any deleted blocks.
745 Insts.clear();
Craig Topper46276792014-08-24 23:23:06 +0000746 for (Instruction *Inst : Instructions)
747 Insts.push_back(Inst);
Nick Lewycky6e090c92009-05-25 05:30:00 +0000748 return true;
749 }
Justin Bogner8d0a0812016-09-02 01:21:37 +0000750 delete M; // It didn't crash, try something else.
Nick Lewycky6e090c92009-05-25 05:30:00 +0000751 return false;
752}
753
Keno Fischer34ca8312015-11-06 00:12:50 +0000754namespace {
755// Reduce the list of Named Metadata nodes. We keep this as a list of
756// names to avoid having to convert back and forth every time.
757class ReduceCrashingNamedMD : public ListReducer<std::string> {
758 BugDriver &BD;
759 bool (*TestFn)(const BugDriver &, Module *);
760
761public:
762 ReduceCrashingNamedMD(BugDriver &bd,
763 bool (*testFn)(const BugDriver &, Module *))
764 : BD(bd), TestFn(testFn) {}
765
Justin Bogner1c039152016-09-06 17:18:22 +0000766 Expected<TestResult> doTest(std::vector<std::string> &Prefix,
767 std::vector<std::string> &Kept) override {
Keno Fischer34ca8312015-11-06 00:12:50 +0000768 if (!Kept.empty() && TestNamedMDs(Kept))
769 return KeepSuffix;
770 if (!Prefix.empty() && TestNamedMDs(Prefix))
771 return KeepPrefix;
772 return NoFailure;
773 }
774
775 bool TestNamedMDs(std::vector<std::string> &NamedMDs);
776};
777}
778
779bool ReduceCrashingNamedMD::TestNamedMDs(std::vector<std::string> &NamedMDs) {
780
781 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000782 Module *M = CloneModule(BD.getProgram(), VMap).release();
Keno Fischer34ca8312015-11-06 00:12:50 +0000783
784 outs() << "Checking for crash with only these named metadata nodes:";
785 unsigned NumPrint = std::min<size_t>(NamedMDs.size(), 10);
786 for (unsigned i = 0, e = NumPrint; i != e; ++i)
787 outs() << " " << NamedMDs[i];
788 if (NumPrint < NamedMDs.size())
789 outs() << "... <" << NamedMDs.size() << " total>";
790 outs() << ": ";
791
792 // Make a StringMap for faster lookup
793 StringSet<> Names;
794 for (const std::string &Name : NamedMDs)
795 Names.insert(Name);
796
797 // First collect all the metadata to delete in a vector, then
798 // delete them all at once to avoid invalidating the iterator
799 std::vector<NamedMDNode *> ToDelete;
800 ToDelete.reserve(M->named_metadata_size() - Names.size());
801 for (auto &NamedMD : M->named_metadata())
Adrian Prantlfaebbb02016-03-28 21:06:26 +0000802 // Always keep a nonempty llvm.dbg.cu because the Verifier would complain.
803 if (!Names.count(NamedMD.getName()) &&
804 (!(NamedMD.getName() == "llvm.dbg.cu" && NamedMD.getNumOperands() > 0)))
Keno Fischer34ca8312015-11-06 00:12:50 +0000805 ToDelete.push_back(&NamedMD);
806
807 for (auto *NamedMD : ToDelete)
808 NamedMD->eraseFromParent();
809
810 // Verify that this is still valid.
811 legacy::PassManager Passes;
Adrian Prantl919bdf12016-10-18 16:24:43 +0000812 Passes.add(createVerifierPass(/*FatalErrors=*/false));
Keno Fischer34ca8312015-11-06 00:12:50 +0000813 Passes.run(*M);
814
815 // Try running on the hacked up program...
816 if (TestFn(BD, M)) {
817 BD.setNewProgram(M); // It crashed, keep the trimmed version...
818 return true;
819 }
820 delete M; // It didn't crash, try something else.
821 return false;
822}
823
824namespace {
825// Reduce the list of operands to named metadata nodes
826class ReduceCrashingNamedMDOps : public ListReducer<const MDNode *> {
827 BugDriver &BD;
828 bool (*TestFn)(const BugDriver &, Module *);
829
830public:
831 ReduceCrashingNamedMDOps(BugDriver &bd,
832 bool (*testFn)(const BugDriver &, Module *))
833 : BD(bd), TestFn(testFn) {}
834
Justin Bogner1c039152016-09-06 17:18:22 +0000835 Expected<TestResult> doTest(std::vector<const MDNode *> &Prefix,
836 std::vector<const MDNode *> &Kept) override {
Keno Fischer34ca8312015-11-06 00:12:50 +0000837 if (!Kept.empty() && TestNamedMDOps(Kept))
838 return KeepSuffix;
839 if (!Prefix.empty() && TestNamedMDOps(Prefix))
840 return KeepPrefix;
841 return NoFailure;
842 }
843
844 bool TestNamedMDOps(std::vector<const MDNode *> &NamedMDOps);
845};
846}
847
848bool ReduceCrashingNamedMDOps::TestNamedMDOps(
849 std::vector<const MDNode *> &NamedMDOps) {
850 // Convert list to set for fast lookup...
Matthias Braunb30f2f512016-01-30 01:24:31 +0000851 SmallPtrSet<const MDNode *, 32> OldMDNodeOps;
Keno Fischer34ca8312015-11-06 00:12:50 +0000852 for (unsigned i = 0, e = NamedMDOps.size(); i != e; ++i) {
853 OldMDNodeOps.insert(NamedMDOps[i]);
854 }
855
856 outs() << "Checking for crash with only " << OldMDNodeOps.size();
857 if (OldMDNodeOps.size() == 1)
858 outs() << " named metadata operand: ";
859 else
860 outs() << " named metadata operands: ";
861
862 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000863 Module *M = CloneModule(BD.getProgram(), VMap).release();
Keno Fischer34ca8312015-11-06 00:12:50 +0000864
865 // This is a little wasteful. In the future it might be good if we could have
866 // these dropped during cloning.
867 for (auto &NamedMD : BD.getProgram()->named_metadata()) {
868 // Drop the old one and create a new one
869 M->eraseNamedMetadata(M->getNamedMetadata(NamedMD.getName()));
870 NamedMDNode *NewNamedMDNode =
871 M->getOrInsertNamedMetadata(NamedMD.getName());
872 for (MDNode *op : NamedMD.operands())
873 if (OldMDNodeOps.count(op))
874 NewNamedMDNode->addOperand(cast<MDNode>(MapMetadata(op, VMap)));
875 }
876
877 // Verify that this is still valid.
878 legacy::PassManager Passes;
Adrian Prantl919bdf12016-10-18 16:24:43 +0000879 Passes.add(createVerifierPass(/*FatalErrors=*/false));
Keno Fischer34ca8312015-11-06 00:12:50 +0000880 Passes.run(*M);
881
882 // Try running on the hacked up program...
883 if (TestFn(BD, M)) {
884 // Make sure to use instruction pointers that point into the now-current
885 // module, and that they don't include any deleted blocks.
886 NamedMDOps.clear();
887 for (const MDNode *Node : OldMDNodeOps)
Duncan P. N. Exon Smithda4a56d2016-04-02 17:04:38 +0000888 NamedMDOps.push_back(cast<MDNode>(*VMap.getMappedMD(Node)));
Keno Fischer34ca8312015-11-06 00:12:50 +0000889
890 BD.setNewProgram(M); // It crashed, keep the trimmed version...
891 return true;
892 }
893 delete M; // It didn't crash, try something else.
894 return false;
895}
896
Justin Bogner1c039152016-09-06 17:18:22 +0000897static Error ReduceGlobalInitializers(BugDriver &BD,
898 bool (*TestFn)(const BugDriver &,
899 Module *)) {
Philip Reames1c232f92016-06-29 00:43:18 +0000900 if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
Bill Wendling3f833432006-10-25 18:36:14 +0000901 // Now try to reduce the number of global variable initializers in the
902 // module to something small.
Rafael Espindolacab951d2015-12-08 23:57:17 +0000903 Module *M = CloneModule(BD.getProgram()).release();
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000904 bool DeletedInit = false;
Misha Brukman650ba8e2005-04-22 00:00:37 +0000905
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000906 for (Module::global_iterator I = M->global_begin(), E = M->global_end();
907 I != E; ++I)
908 if (I->hasInitializer()) {
Hal Finkel28ad2b42015-11-26 19:23:49 +0000909 DeleteGlobalInitializer(&*I);
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000910 I->setLinkage(GlobalValue::ExternalLinkage);
Justin Lebar2a445cf2016-06-15 23:20:12 +0000911 I->setComdat(nullptr);
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000912 DeletedInit = true;
913 }
Bill Wendling3f833432006-10-25 18:36:14 +0000914
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000915 if (!DeletedInit) {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000916 delete M; // No change made...
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000917 } else {
918 // See if the program still causes a crash...
Dan Gohmanee051522009-07-16 15:30:09 +0000919 outs() << "\nChecking to see if we can delete global inits: ";
Bill Wendling3f833432006-10-25 18:36:14 +0000920
Justin Bogner8d0a0812016-09-02 01:21:37 +0000921 if (TestFn(BD, M)) { // Still crashes?
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000922 BD.setNewProgram(M);
Dan Gohmanee051522009-07-16 15:30:09 +0000923 outs() << "\n*** Able to remove all global initializers!\n";
Justin Bogner8d0a0812016-09-02 01:21:37 +0000924 } else { // No longer crashes?
Dan Gohmanee051522009-07-16 15:30:09 +0000925 outs() << " - Removing all global inits hides problem!\n";
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000926 delete M;
Bill Wendling3f833432006-10-25 18:36:14 +0000927
Justin Bogner8d0a0812016-09-02 01:21:37 +0000928 std::vector<GlobalVariable *> GVs;
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000929
930 for (Module::global_iterator I = BD.getProgram()->global_begin(),
Justin Bogner8d0a0812016-09-02 01:21:37 +0000931 E = BD.getProgram()->global_end();
932 I != E; ++I)
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000933 if (I->hasInitializer())
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000934 GVs.push_back(&*I);
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000935
936 if (GVs.size() > 1 && !BugpointIsInterrupted) {
Dan Gohmanee051522009-07-16 15:30:09 +0000937 outs() << "\n*** Attempting to reduce the number of global "
Justin Bogner8d0a0812016-09-02 01:21:37 +0000938 << "variables in the testcase\n";
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000939
940 unsigned OldSize = GVs.size();
Justin Bogner1c039152016-09-06 17:18:22 +0000941 Expected<bool> Result =
942 ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs);
943 if (Error E = Result.takeError())
944 return E;
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000945
946 if (GVs.size() < OldSize)
Rafael Espindola594994a2010-07-28 18:12:30 +0000947 BD.EmitProgressBitcode(BD.getProgram(), "reduced-global-variables");
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000948 }
Bill Wendlingce3afd62006-10-27 20:22:04 +0000949 }
Chris Lattner65e5f652003-04-25 00:53:05 +0000950 }
951 }
Justin Bogner1c039152016-09-06 17:18:22 +0000952 return Error::success();
Philip Reames1c232f92016-06-29 00:43:18 +0000953}
954
Justin Bogner1c039152016-09-06 17:18:22 +0000955static Error ReduceInsts(BugDriver &BD,
956 bool (*TestFn)(const BugDriver &, Module *)) {
Philip Reames1c232f92016-06-29 00:43:18 +0000957 // Attempt to delete instructions using bisection. This should help out nasty
958 // cases with large basic blocks where the problem is at one end.
959 if (!BugpointIsInterrupted) {
Justin Bogner8d0a0812016-09-02 01:21:37 +0000960 std::vector<const Instruction *> Insts;
Philip Reames1c232f92016-06-29 00:43:18 +0000961 for (const Function &F : *BD.getProgram())
962 for (const BasicBlock &BB : F)
963 for (const Instruction &I : BB)
964 if (!isa<TerminatorInst>(&I))
965 Insts.push_back(&I);
966
Justin Bogner1c039152016-09-06 17:18:22 +0000967 Expected<bool> Result =
968 ReduceCrashingInstructions(BD, TestFn).reduceList(Insts);
969 if (Error E = Result.takeError())
970 return E;
Philip Reames1c232f92016-06-29 00:43:18 +0000971 }
972
973 unsigned Simplification = 2;
974 do {
975 if (BugpointIsInterrupted)
Justin Bogner1c039152016-09-06 17:18:22 +0000976 // TODO: Should we distinguish this with an "interrupted error"?
977 return Error::success();
Philip Reames1c232f92016-06-29 00:43:18 +0000978 --Simplification;
979 outs() << "\n*** Attempting to reduce testcase by deleting instruc"
980 << "tions: Simplification Level #" << Simplification << '\n';
981
982 // Now that we have deleted the functions that are unnecessary for the
983 // program, try to remove instructions that are not necessary to cause the
984 // crash. To do this, we loop through all of the instructions in the
985 // remaining functions, deleting them (replacing any values produced with
986 // nulls), and then running ADCE and SimplifyCFG. If the transformed input
987 // still triggers failure, keep deleting until we cannot trigger failure
988 // anymore.
989 //
990 unsigned InstructionsToSkipBeforeDeleting = 0;
991 TryAgain:
992
993 // Loop over all of the (non-terminator) instructions remaining in the
994 // function, attempting to delete them.
995 unsigned CurInstructionNum = 0;
996 for (Module::const_iterator FI = BD.getProgram()->begin(),
Justin Bogner8d0a0812016-09-02 01:21:37 +0000997 E = BD.getProgram()->end();
998 FI != E; ++FI)
Philip Reames1c232f92016-06-29 00:43:18 +0000999 if (!FI->isDeclaration())
1000 for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E;
1001 ++BI)
1002 for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end();
1003 I != E; ++I, ++CurInstructionNum) {
1004 if (InstructionsToSkipBeforeDeleting) {
1005 --InstructionsToSkipBeforeDeleting;
1006 } else {
1007 if (BugpointIsInterrupted)
Justin Bogner1c039152016-09-06 17:18:22 +00001008 // TODO: Should this be some kind of interrupted error?
1009 return Error::success();
Philip Reames1c232f92016-06-29 00:43:18 +00001010
1011 if (I->isEHPad() || I->getType()->isTokenTy())
1012 continue;
1013
1014 outs() << "Checking instruction: " << *I;
1015 std::unique_ptr<Module> M =
1016 BD.deleteInstructionFromProgram(&*I, Simplification);
1017
1018 // Find out if the pass still crashes on this pass...
1019 if (TestFn(BD, M.get())) {
1020 // Yup, it does, we delete the old module, and continue trying
1021 // to reduce the testcase...
1022 BD.setNewProgram(M.release());
1023 InstructionsToSkipBeforeDeleting = CurInstructionNum;
Justin Bogner8d0a0812016-09-02 01:21:37 +00001024 goto TryAgain; // I wish I had a multi-level break here!
Philip Reames1c232f92016-06-29 00:43:18 +00001025 }
1026 }
1027 }
1028
1029 if (InstructionsToSkipBeforeDeleting) {
1030 InstructionsToSkipBeforeDeleting = 0;
1031 goto TryAgain;
1032 }
1033
1034 } while (Simplification);
1035 BD.EmitProgressBitcode(BD.getProgram(), "reduced-instructions");
Justin Bogner1c039152016-09-06 17:18:22 +00001036 return Error::success();
Philip Reames1c232f92016-06-29 00:43:18 +00001037}
1038
Philip Reames1c232f92016-06-29 00:43:18 +00001039/// DebugACrash - Given a predicate that determines whether a component crashes
1040/// on a program, try to destructively reduce the program while still keeping
1041/// the predicate true.
Justin Bogner1c039152016-09-06 17:18:22 +00001042static Error DebugACrash(BugDriver &BD,
1043 bool (*TestFn)(const BugDriver &, Module *)) {
Philip Reames1c232f92016-06-29 00:43:18 +00001044 // See if we can get away with nuking some of the global variable initializers
1045 // in the program...
1046 if (!NoGlobalRM)
Justin Bogner1c039152016-09-06 17:18:22 +00001047 if (Error E = ReduceGlobalInitializers(BD, TestFn))
1048 return E;
Misha Brukman650ba8e2005-04-22 00:00:37 +00001049
Chris Lattner1d080f22003-04-24 22:24:58 +00001050 // Now try to reduce the number of functions in the module to something small.
Justin Bogner8d0a0812016-09-02 01:21:37 +00001051 std::vector<Function *> Functions;
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +00001052 for (Function &F : *BD.getProgram())
1053 if (!F.isDeclaration())
1054 Functions.push_back(&F);
Chris Lattner73a6bdd2002-11-20 22:28:10 +00001055
Chris Lattnerbeb01fa2005-08-02 02:16:17 +00001056 if (Functions.size() > 1 && !BugpointIsInterrupted) {
Dan Gohmanee051522009-07-16 15:30:09 +00001057 outs() << "\n*** Attempting to reduce the number of functions "
Justin Bogner8d0a0812016-09-02 01:21:37 +00001058 "in the testcase\n";
Chris Lattner73a6bdd2002-11-20 22:28:10 +00001059
Chris Lattner8bda4c42004-02-18 23:26:28 +00001060 unsigned OldSize = Functions.size();
Justin Bogner1c039152016-09-06 17:18:22 +00001061 Expected<bool> Result =
1062 ReduceCrashingFunctions(BD, TestFn).reduceList(Functions);
1063 if (Error E = Result.takeError())
1064 return E;
Chris Lattner73a6bdd2002-11-20 22:28:10 +00001065
Chris Lattnerbeb01fa2005-08-02 02:16:17 +00001066 if (Functions.size() < OldSize)
Rafael Espindola594994a2010-07-28 18:12:30 +00001067 BD.EmitProgressBitcode(BD.getProgram(), "reduced-function");
Chris Lattner73a6bdd2002-11-20 22:28:10 +00001068 }
1069
Daniel Berlin271ca402016-07-27 16:13:25 +00001070 // Attempt to change conditional branches into unconditional branches to
1071 // eliminate blocks.
1072 if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
Justin Bogner8d0a0812016-09-02 01:21:37 +00001073 std::vector<const BasicBlock *> Blocks;
Daniel Berlin271ca402016-07-27 16:13:25 +00001074 for (Function &F : *BD.getProgram())
1075 for (BasicBlock &BB : F)
1076 Blocks.push_back(&BB);
1077 unsigned OldSize = Blocks.size();
Justin Bogner1c039152016-09-06 17:18:22 +00001078 Expected<bool> Result =
1079 ReduceCrashingConditionals(BD, TestFn, true).reduceList(Blocks);
1080 if (Error E = Result.takeError())
1081 return E;
1082 Result = ReduceCrashingConditionals(BD, TestFn, false).reduceList(Blocks);
1083 if (Error E = Result.takeError())
1084 return E;
Daniel Berlin271ca402016-07-27 16:13:25 +00001085 if (Blocks.size() < OldSize)
1086 BD.EmitProgressBitcode(BD.getProgram(), "reduced-conditionals");
1087 }
1088
Chris Lattnerf32939b2003-04-24 23:51:38 +00001089 // Attempt to delete entire basic blocks at a time to speed up
1090 // convergence... this actually works by setting the terminator of the blocks
1091 // to a return instruction then running simplifycfg, which can potentially
1092 // shrinks the code dramatically quickly
1093 //
Chris Lattnerbeb01fa2005-08-02 02:16:17 +00001094 if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
Justin Bogner8d0a0812016-09-02 01:21:37 +00001095 std::vector<const BasicBlock *> Blocks;
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +00001096 for (Function &F : *BD.getProgram())
1097 for (BasicBlock &BB : F)
1098 Blocks.push_back(&BB);
Torok Edwin6ee6f732009-05-24 09:40:47 +00001099 unsigned OldSize = Blocks.size();
Justin Bogner1c039152016-09-06 17:18:22 +00001100 Expected<bool> Result = ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks);
1101 if (Error E = Result.takeError())
1102 return E;
Torok Edwin6ee6f732009-05-24 09:40:47 +00001103 if (Blocks.size() < OldSize)
Rafael Espindola594994a2010-07-28 18:12:30 +00001104 BD.EmitProgressBitcode(BD.getProgram(), "reduced-blocks");
Chris Lattnerd1e2aae2003-08-05 15:51:05 +00001105 }
Chris Lattnerd4e04742002-12-23 23:49:59 +00001106
Daniel Berlin60606262016-07-28 22:29:25 +00001107 if (!DisableSimplifyCFG & !BugpointIsInterrupted) {
Justin Bogner8d0a0812016-09-02 01:21:37 +00001108 std::vector<const BasicBlock *> Blocks;
Daniel Berlin60606262016-07-28 22:29:25 +00001109 for (Function &F : *BD.getProgram())
1110 for (BasicBlock &BB : F)
1111 Blocks.push_back(&BB);
1112 unsigned OldSize = Blocks.size();
Justin Bogner1c039152016-09-06 17:18:22 +00001113 Expected<bool> Result = ReduceSimplifyCFG(BD, TestFn).reduceList(Blocks);
1114 if (Error E = Result.takeError())
1115 return E;
Daniel Berlin60606262016-07-28 22:29:25 +00001116 if (Blocks.size() < OldSize)
1117 BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplifycfg");
1118 }
Justin Bogner8d0a0812016-09-02 01:21:37 +00001119
Nick Lewycky6e090c92009-05-25 05:30:00 +00001120 // Attempt to delete instructions using bisection. This should help out nasty
1121 // cases with large basic blocks where the problem is at one end.
Philip Reames1c232f92016-06-29 00:43:18 +00001122 if (!BugpointIsInterrupted)
Justin Bogner1c039152016-09-06 17:18:22 +00001123 if (Error E = ReduceInsts(BD, TestFn))
1124 return E;
Keno Fischer34ca8312015-11-06 00:12:50 +00001125
1126 if (!NoNamedMDRM) {
Keno Fischer34ca8312015-11-06 00:12:50 +00001127 if (!BugpointIsInterrupted) {
1128 // Try to reduce the amount of global metadata (particularly debug info),
1129 // by dropping global named metadata that anchors them
1130 outs() << "\n*** Attempting to remove named metadata: ";
1131 std::vector<std::string> NamedMDNames;
1132 for (auto &NamedMD : BD.getProgram()->named_metadata())
1133 NamedMDNames.push_back(NamedMD.getName().str());
Justin Bogner1c039152016-09-06 17:18:22 +00001134 Expected<bool> Result =
1135 ReduceCrashingNamedMD(BD, TestFn).reduceList(NamedMDNames);
1136 if (Error E = Result.takeError())
1137 return E;
Keno Fischer34ca8312015-11-06 00:12:50 +00001138 }
1139
1140 if (!BugpointIsInterrupted) {
1141 // Now that we quickly dropped all the named metadata that doesn't
1142 // contribute to the crash, bisect the operands of the remaining ones
1143 std::vector<const MDNode *> NamedMDOps;
1144 for (auto &NamedMD : BD.getProgram()->named_metadata())
Keno Fischer256df862015-11-06 00:45:47 +00001145 for (auto op : NamedMD.operands())
1146 NamedMDOps.push_back(op);
Justin Bogner1c039152016-09-06 17:18:22 +00001147 Expected<bool> Result =
1148 ReduceCrashingNamedMDOps(BD, TestFn).reduceList(NamedMDOps);
1149 if (Error E = Result.takeError())
1150 return E;
Keno Fischer34ca8312015-11-06 00:12:50 +00001151 }
Philip Reamesac285cc2016-06-29 00:10:39 +00001152 BD.EmitProgressBitcode(BD.getProgram(), "reduced-named-md");
Keno Fischer34ca8312015-11-06 00:12:50 +00001153 }
1154
Chris Lattner514c02e2003-02-28 16:13:20 +00001155 // Try to clean up the testcase by running funcresolve and globaldce...
Chris Lattnerbeb01fa2005-08-02 02:16:17 +00001156 if (!BugpointIsInterrupted) {
Dan Gohmanee051522009-07-16 15:30:09 +00001157 outs() << "\n*** Attempting to perform final cleanups: ";
Rafael Espindolacab951d2015-12-08 23:57:17 +00001158 Module *M = CloneModule(BD.getProgram()).release();
Rafael Espindola28b351a2014-08-26 17:19:03 +00001159 M = BD.performFinalCleanups(M, true).release();
Misha Brukman650ba8e2005-04-22 00:00:37 +00001160
Chris Lattnerbeb01fa2005-08-02 02:16:17 +00001161 // Find out if the pass still crashes on the cleaned up program...
1162 if (TestFn(BD, M)) {
Justin Bogner8d0a0812016-09-02 01:21:37 +00001163 BD.setNewProgram(M); // Yup, it does, keep the reduced version...
Chris Lattnerbeb01fa2005-08-02 02:16:17 +00001164 } else {
1165 delete M;
1166 }
Chris Lattner514c02e2003-02-28 16:13:20 +00001167 }
1168
Rafael Espindola594994a2010-07-28 18:12:30 +00001169 BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplified");
Chris Lattner514c02e2003-02-28 16:13:20 +00001170
Justin Bogner1c039152016-09-06 17:18:22 +00001171 return Error::success();
Chris Lattner73a6bdd2002-11-20 22:28:10 +00001172}
Brian Gaeke960707c2003-11-11 22:41:34 +00001173
Rafael Espindolad1c7ef42010-08-05 03:00:22 +00001174static bool TestForOptimizerCrash(const BugDriver &BD, Module *M) {
Philip Reamese5b56022016-06-29 03:01:13 +00001175 return BD.runPasses(M, BD.getPassesToRun());
Chris Lattner8bda4c42004-02-18 23:26:28 +00001176}
Chris Lattneread1dff2004-02-18 21:02:04 +00001177
Chris Lattner8bda4c42004-02-18 23:26:28 +00001178/// debugOptimizerCrash - This method is called when some pass crashes on input.
1179/// It attempts to prune down the testcase to something reasonable, and figure
1180/// out exactly which pass is crashing.
1181///
Justin Bogner1c039152016-09-06 17:18:22 +00001182Error BugDriver::debugOptimizerCrash(const std::string &ID) {
Dan Gohmanee051522009-07-16 15:30:09 +00001183 outs() << "\n*** Debugging optimizer crash!\n";
Chris Lattner8bda4c42004-02-18 23:26:28 +00001184
1185 // Reduce the list of passes which causes the optimizer to crash...
Justin Bogner1c039152016-09-06 17:18:22 +00001186 if (!BugpointIsInterrupted && !DontReducePassList) {
1187 Expected<bool> Result = ReducePassList(*this).reduceList(PassesToRun);
1188 if (Error E = Result.takeError())
1189 return E;
1190 }
Chris Lattner8bda4c42004-02-18 23:26:28 +00001191
Dan Gohmanee051522009-07-16 15:30:09 +00001192 outs() << "\n*** Found crashing pass"
1193 << (PassesToRun.size() == 1 ? ": " : "es: ")
1194 << getPassesString(PassesToRun) << '\n';
Chris Lattner8bda4c42004-02-18 23:26:28 +00001195
Rafael Espindola594994a2010-07-28 18:12:30 +00001196 EmitProgressBitcode(Program, ID);
Chris Lattner8bda4c42004-02-18 23:26:28 +00001197
Justin Bogner1c039152016-09-06 17:18:22 +00001198 return DebugACrash(*this, TestForOptimizerCrash);
Chris Lattner8bda4c42004-02-18 23:26:28 +00001199}
1200
Rafael Espindolad1c7ef42010-08-05 03:00:22 +00001201static bool TestForCodeGenCrash(const BugDriver &BD, Module *M) {
Justin Bogner1c039152016-09-06 17:18:22 +00001202 if (Error E = BD.compileProgram(M)) {
Sebastian Pop8f7d0192016-07-15 23:15:06 +00001203 if (VerboseErrors)
Justin Bogner1c039152016-09-06 17:18:22 +00001204 errs() << toString(std::move(E)) << "\n";
1205 else {
1206 consumeError(std::move(E));
Sebastian Pop8f7d0192016-07-15 23:15:06 +00001207 errs() << "<crash>\n";
Justin Bogner1c039152016-09-06 17:18:22 +00001208 }
Justin Bogner8d0a0812016-09-02 01:21:37 +00001209 return true; // Tool is still crashing.
Chris Lattner8bda4c42004-02-18 23:26:28 +00001210 }
Nick Lewycky6ba630b2010-04-12 05:08:25 +00001211 errs() << '\n';
1212 return false;
Chris Lattner8bda4c42004-02-18 23:26:28 +00001213}
Chris Lattneread1dff2004-02-18 21:02:04 +00001214
1215/// debugCodeGeneratorCrash - This method is called when the code generator
1216/// crashes on an input. It attempts to reduce the input as much as possible
1217/// while still causing the code generator to crash.
Justin Bogner1c039152016-09-06 17:18:22 +00001218Error BugDriver::debugCodeGeneratorCrash() {
Dan Gohmand8db3762009-07-15 16:35:29 +00001219 errs() << "*** Debugging code generator crash!\n";
Chris Lattneread1dff2004-02-18 21:02:04 +00001220
Justin Bogner1c039152016-09-06 17:18:22 +00001221 return DebugACrash(*this, TestForCodeGenCrash);
Chris Lattneread1dff2004-02-18 21:02:04 +00001222}