blob: 2555224fde8066fff864352595d0134360683c67 [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"
Chandler Carruth1305dc32014-03-04 11:45:46 +000019#include "llvm/IR/CFG.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000020#include "llvm/IR/Constants.h"
21#include "llvm/IR/DerivedTypes.h"
22#include "llvm/IR/Instructions.h"
Chandler Carruth30d69c22015-02-13 10:01:29 +000023#include "llvm/IR/LegacyPassManager.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000024#include "llvm/IR/Module.h"
25#include "llvm/IR/ValueSymbolTable.h"
Chandler Carruth5ad5f152014-01-13 09:26:24 +000026#include "llvm/IR/Verifier.h"
Misha Brukman0c2305b2003-08-07 21:19:30 +000027#include "llvm/Pass.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000028#include "llvm/Support/CommandLine.h"
29#include "llvm/Support/FileUtilities.h"
Chris Lattnerf32939b2003-04-24 23:51:38 +000030#include "llvm/Transforms/Scalar.h"
Daniel Berlin271ca402016-07-27 16:13:25 +000031#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Chris Lattner1d080f22003-04-24 22:24:58 +000032#include "llvm/Transforms/Utils/Cloning.h"
Daniel Berlin271ca402016-07-27 16:13:25 +000033#include "llvm/Transforms/Utils/Local.h"
Chris Lattner1d080f22003-04-24 22:24:58 +000034#include <set>
Chris Lattner2f1aa112004-01-14 03:38:37 +000035using namespace llvm;
Chris Lattner73a6bdd2002-11-20 22:28:10 +000036
Andrew Lenharthef9aa122006-03-05 22:21:36 +000037namespace {
38 cl::opt<bool>
39 KeepMain("keep-main",
40 cl::desc("Force function reduction to keep main"),
41 cl::init(false));
Torok Edwin5bd3f7b2009-05-24 09:31:04 +000042 cl::opt<bool>
43 NoGlobalRM ("disable-global-remove",
44 cl::desc("Do not remove global variables"),
45 cl::init(false));
JF Bastienf87e20d2015-04-20 23:42:22 +000046
47 cl::opt<bool>
48 ReplaceFuncsWithNull("replace-funcs-with-null",
49 cl::desc("When stubbing functions, replace all uses will null"),
50 cl::init(false));
51 cl::opt<bool>
52 DontReducePassList("disable-pass-list-reduction",
53 cl::desc("Skip pass list reduction steps"),
54 cl::init(false));
Keno Fischer34ca8312015-11-06 00:12:50 +000055
56 cl::opt<bool> NoNamedMDRM("disable-namedmd-remove",
57 cl::desc("Do not remove global named metadata"),
58 cl::init(false));
Sebastian Pop8f7d0192016-07-15 23:15:06 +000059 cl::opt<bool> VerboseErrors("verbose-errors",
60 cl::desc("Print the output of crashing program"),
61 cl::init(false));
Andrew Lenharthef9aa122006-03-05 22:21:36 +000062}
63
Brian Gaeke960707c2003-11-11 22:41:34 +000064namespace llvm {
Rafael Espindola33e81a82010-08-08 03:55:08 +000065 class ReducePassList : public ListReducer<std::string> {
Chris Lattner2f1aa112004-01-14 03:38:37 +000066 BugDriver &BD;
67 public:
Chris Lattner327019b2004-02-18 21:24:48 +000068 ReducePassList(BugDriver &bd) : BD(bd) {}
Misha Brukman650ba8e2005-04-22 00:00:37 +000069
Sylvestre Ledru91ce36c2012-09-27 10:14:43 +000070 // doTest - Return true iff running the "removed" passes succeeds, and
Chris Lattner2f1aa112004-01-14 03:38:37 +000071 // running the "Kept" passes fail when run on the output of the "removed"
72 // passes. If we return true, we update the current module of bugpoint.
73 //
Craig Toppere56917c2014-03-08 08:27:28 +000074 TestResult doTest(std::vector<std::string> &Removed,
75 std::vector<std::string> &Kept,
76 std::string &Error) override;
Chris Lattner2f1aa112004-01-14 03:38:37 +000077 };
78}
Chris Lattner1d080f22003-04-24 22:24:58 +000079
Chris Lattner327019b2004-02-18 21:24:48 +000080ReducePassList::TestResult
Rafael Espindola33e81a82010-08-08 03:55:08 +000081ReducePassList::doTest(std::vector<std::string> &Prefix,
82 std::vector<std::string> &Suffix,
Nick Lewycky6ba630b2010-04-12 05:08:25 +000083 std::string &Error) {
Rafael Espindolabb876652013-06-17 19:33:18 +000084 std::string PrefixOutput;
Craig Toppere6cb63e2014-04-25 04:24:47 +000085 Module *OrigProgram = nullptr;
Chris Lattner1d080f22003-04-24 22:24:58 +000086 if (!Prefix.empty()) {
Dan Gohmanee051522009-07-16 15:30:09 +000087 outs() << "Checking to see if these passes crash: "
88 << getPassesString(Prefix) << ": ";
Rafael Espindolabb876652013-06-17 19:33:18 +000089 if (BD.runPasses(BD.getProgram(), Prefix, PrefixOutput))
Chris Lattner1d080f22003-04-24 22:24:58 +000090 return KeepPrefix;
Chris Lattnera9656312003-06-02 04:54:29 +000091
92 OrigProgram = BD.Program;
93
Rafael Espindola28b351a2014-08-26 17:19:03 +000094 BD.Program = parseInputFile(PrefixOutput, BD.getContext()).release();
Craig Toppere6cb63e2014-04-25 04:24:47 +000095 if (BD.Program == nullptr) {
Dan Gohmand8db3762009-07-15 16:35:29 +000096 errs() << BD.getToolName() << ": Error reading bitcode file '"
Rafael Espindolabb876652013-06-17 19:33:18 +000097 << PrefixOutput << "'!\n";
Chris Lattnera9656312003-06-02 04:54:29 +000098 exit(1);
99 }
Rafael Espindolabb876652013-06-17 19:33:18 +0000100 sys::fs::remove(PrefixOutput);
Chris Lattner1d080f22003-04-24 22:24:58 +0000101 }
102
Dan Gohmanee051522009-07-16 15:30:09 +0000103 outs() << "Checking to see if these passes crash: "
104 << getPassesString(Suffix) << ": ";
Misha Brukman650ba8e2005-04-22 00:00:37 +0000105
Rafael Espindola37302ea2010-08-05 02:16:32 +0000106 if (BD.runPasses(BD.getProgram(), Suffix)) {
Chris Lattner1d080f22003-04-24 22:24:58 +0000107 delete OrigProgram; // The suffix crashes alone...
108 return KeepSuffix;
109 }
110
111 // Nothing failed, restore state...
Chris Lattnera9656312003-06-02 04:54:29 +0000112 if (OrigProgram) {
113 delete BD.Program;
114 BD.Program = OrigProgram;
115 }
Chris Lattner1d080f22003-04-24 22:24:58 +0000116 return NoFailure;
117}
118
Bill Wendling3f833432006-10-25 18:36:14 +0000119namespace {
120 /// ReduceCrashingGlobalVariables - This works by removing the global
121 /// variable's initializer and seeing if the program still crashes. If it
122 /// does, then we keep that program and try again.
123 ///
124 class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable*> {
125 BugDriver &BD;
Rafael Espindolad1c7ef42010-08-05 03:00:22 +0000126 bool (*TestFn)(const BugDriver &, Module *);
Bill Wendling3f833432006-10-25 18:36:14 +0000127 public:
128 ReduceCrashingGlobalVariables(BugDriver &bd,
Rafael Espindolad1c7ef42010-08-05 03:00:22 +0000129 bool (*testFn)(const BugDriver &, Module *))
Bill Wendling3f833432006-10-25 18:36:14 +0000130 : BD(bd), TestFn(testFn) {}
131
Craig Toppere56917c2014-03-08 08:27:28 +0000132 TestResult doTest(std::vector<GlobalVariable*> &Prefix,
133 std::vector<GlobalVariable*> &Kept,
134 std::string &Error) override {
Bill Wendling3f833432006-10-25 18:36:14 +0000135 if (!Kept.empty() && TestGlobalVariables(Kept))
136 return KeepSuffix;
Bill Wendling3f833432006-10-25 18:36:14 +0000137 if (!Prefix.empty() && TestGlobalVariables(Prefix))
138 return KeepPrefix;
Bill Wendling3f833432006-10-25 18:36:14 +0000139 return NoFailure;
140 }
141
Nick Lewycky6ba630b2010-04-12 05:08:25 +0000142 bool TestGlobalVariables(std::vector<GlobalVariable*> &GVs);
Bill Wendling3f833432006-10-25 18:36:14 +0000143 };
144}
145
146bool
147ReduceCrashingGlobalVariables::TestGlobalVariables(
Nick Lewycky6ba630b2010-04-12 05:08:25 +0000148 std::vector<GlobalVariable*> &GVs) {
Bill Wendling3f833432006-10-25 18:36:14 +0000149 // Clone the program to try hacking it apart...
Rafael Espindola229e38f2010-10-13 01:36:30 +0000150 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000151 Module *M = CloneModule(BD.getProgram(), VMap).release();
Bill Wendling3f833432006-10-25 18:36:14 +0000152
153 // Convert list to set for fast lookup...
154 std::set<GlobalVariable*> GVSet;
155
156 for (unsigned i = 0, e = GVs.size(); i != e; ++i) {
Devang Patel0dc3c2d2010-06-24 00:33:28 +0000157 GlobalVariable* CMGV = cast<GlobalVariable>(VMap[GVs[i]]);
Bill Wendling3f833432006-10-25 18:36:14 +0000158 assert(CMGV && "Global Variable not in module?!");
159 GVSet.insert(CMGV);
160 }
161
Dan Gohmanee051522009-07-16 15:30:09 +0000162 outs() << "Checking for crash with only these global variables: ";
Bill Wendling3f833432006-10-25 18:36:14 +0000163 PrintGlobalVariableList(GVs);
Dan Gohmanee051522009-07-16 15:30:09 +0000164 outs() << ": ";
Bill Wendling3f833432006-10-25 18:36:14 +0000165
166 // Loop over and delete any global variables which we aren't supposed to be
167 // playing with...
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000168 for (GlobalVariable &I : M->globals())
169 if (I.hasInitializer() && !GVSet.count(&I)) {
Hal Finkel28ad2b42015-11-26 19:23:49 +0000170 DeleteGlobalInitializer(&I);
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000171 I.setLinkage(GlobalValue::ExternalLinkage);
Justin Lebar2a445cf2016-06-15 23:20:12 +0000172 I.setComdat(nullptr);
Bill Wendling3f833432006-10-25 18:36:14 +0000173 }
174
175 // Try running the hacked up program...
176 if (TestFn(BD, M)) {
177 BD.setNewProgram(M); // It crashed, keep the trimmed version...
178
179 // Make sure to use global variable pointers that point into the now-current
180 // module.
181 GVs.assign(GVSet.begin(), GVSet.end());
182 return true;
183 }
184
185 delete M;
186 return false;
187}
188
David Blaikiea379b1812011-12-20 02:50:00 +0000189namespace {
Bill Wendling3f833432006-10-25 18:36:14 +0000190 /// ReduceCrashingFunctions reducer - This works by removing functions and
191 /// seeing if the program still crashes. If it does, then keep the newer,
192 /// smaller program.
193 ///
Chris Lattnerfd72bed2004-03-14 20:50:42 +0000194 class ReduceCrashingFunctions : public ListReducer<Function*> {
Chris Lattner2f1aa112004-01-14 03:38:37 +0000195 BugDriver &BD;
Rafael Espindolad1c7ef42010-08-05 03:00:22 +0000196 bool (*TestFn)(const BugDriver &, Module *);
Chris Lattner2f1aa112004-01-14 03:38:37 +0000197 public:
Chris Lattner8bda4c42004-02-18 23:26:28 +0000198 ReduceCrashingFunctions(BugDriver &bd,
Rafael Espindolad1c7ef42010-08-05 03:00:22 +0000199 bool (*testFn)(const BugDriver &, Module *))
Chris Lattner8bda4c42004-02-18 23:26:28 +0000200 : BD(bd), TestFn(testFn) {}
Misha Brukman650ba8e2005-04-22 00:00:37 +0000201
Craig Toppere56917c2014-03-08 08:27:28 +0000202 TestResult doTest(std::vector<Function*> &Prefix,
203 std::vector<Function*> &Kept,
204 std::string &Error) override {
Chris Lattner2f1aa112004-01-14 03:38:37 +0000205 if (!Kept.empty() && TestFuncs(Kept))
206 return KeepSuffix;
207 if (!Prefix.empty() && TestFuncs(Prefix))
208 return KeepPrefix;
209 return NoFailure;
210 }
Misha Brukman650ba8e2005-04-22 00:00:37 +0000211
Chris Lattnerfd72bed2004-03-14 20:50:42 +0000212 bool TestFuncs(std::vector<Function*> &Prefix);
Chris Lattner2f1aa112004-01-14 03:38:37 +0000213 };
214}
Chris Lattner1d080f22003-04-24 22:24:58 +0000215
JF Bastienf87e20d2015-04-20 23:42:22 +0000216static void RemoveFunctionReferences(Module *M, const char* Name) {
217 auto *UsedVar = M->getGlobalVariable(Name, true);
218 if (!UsedVar || !UsedVar->hasInitializer()) return;
219 if (isa<ConstantAggregateZero>(UsedVar->getInitializer())) {
220 assert(UsedVar->use_empty());
221 UsedVar->eraseFromParent();
222 return;
223 }
224 auto *OldUsedVal = cast<ConstantArray>(UsedVar->getInitializer());
225 std::vector<Constant*> Used;
226 for(Value *V : OldUsedVal->operand_values()) {
227 Constant *Op = cast<Constant>(V->stripPointerCasts());
228 if(!Op->isNullValue()) {
229 Used.push_back(cast<Constant>(V));
230 }
231 }
232 auto *NewValElemTy = OldUsedVal->getType()->getElementType();
233 auto *NewValTy = ArrayType::get(NewValElemTy, Used.size());
234 auto *NewUsedVal = ConstantArray::get(NewValTy, Used);
235 UsedVar->mutateType(NewUsedVal->getType()->getPointerTo());
236 UsedVar->setInitializer(NewUsedVal);
237}
238
Chris Lattnerfd72bed2004-03-14 20:50:42 +0000239bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
Dmitri Gribenko6e0520e2013-09-02 01:18:56 +0000240 // If main isn't present, claim there is no problem.
241 if (KeepMain && std::find(Funcs.begin(), Funcs.end(),
242 BD.getProgram()->getFunction("main")) ==
243 Funcs.end())
Andrew Lenharthef9aa122006-03-05 22:21:36 +0000244 return false;
245
Misha Brukman8b2bd4e2003-10-10 17:57:28 +0000246 // Clone the program to try hacking it apart...
Rafael Espindola229e38f2010-10-13 01:36:30 +0000247 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000248 Module *M = CloneModule(BD.getProgram(), VMap).release();
Misha Brukman650ba8e2005-04-22 00:00:37 +0000249
Chris Lattner1d080f22003-04-24 22:24:58 +0000250 // Convert list to set for fast lookup...
251 std::set<Function*> Functions;
252 for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
Devang Patel0dc3c2d2010-06-24 00:33:28 +0000253 Function *CMF = cast<Function>(VMap[Funcs[i]]);
Chris Lattner1d080f22003-04-24 22:24:58 +0000254 assert(CMF && "Function not in module?!");
Reid Spencer3aaaa0b2007-02-05 20:47:22 +0000255 assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty");
Dan Gohmanbcad7182009-03-06 02:16:23 +0000256 assert(CMF->getName() == Funcs[i]->getName() && "wrong name");
Chris Lattnerde39f2b2003-04-24 22:54:06 +0000257 Functions.insert(CMF);
Chris Lattner1d080f22003-04-24 22:24:58 +0000258 }
259
Dan Gohmanee051522009-07-16 15:30:09 +0000260 outs() << "Checking for crash with only these functions: ";
Chris Lattnerfd72bed2004-03-14 20:50:42 +0000261 PrintFunctionList(Funcs);
Dan Gohmanee051522009-07-16 15:30:09 +0000262 outs() << ": ";
JF Bastienf87e20d2015-04-20 23:42:22 +0000263 if (!ReplaceFuncsWithNull) {
264 // Loop over and delete any functions which we aren't supposed to be playing
265 // with...
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000266 for (Function &I : *M)
267 if (!I.isDeclaration() && !Functions.count(&I))
268 DeleteFunctionBody(&I);
JF Bastienf87e20d2015-04-20 23:42:22 +0000269 } else {
270 std::vector<GlobalValue*> ToRemove;
271 // First, remove aliases to functions we're about to purge.
272 for (GlobalAlias &Alias : M->aliases()) {
David Majnemer95549492016-05-04 00:20:48 +0000273 GlobalObject *Root = Alias.getBaseObject();
274 Function *F = dyn_cast_or_null<Function>(Root);
JF Bastienf87e20d2015-04-20 23:42:22 +0000275 if (F) {
276 if (Functions.count(F))
277 // We're keeping this function.
278 continue;
279 } else if (Root->isNullValue()) {
280 // This referenced a globalalias that we've already replaced,
281 // so we still need to replace this alias.
282 } else if (!F) {
283 // Not a function, therefore not something we mess with.
284 continue;
285 }
Chris Lattner1d080f22003-04-24 22:24:58 +0000286
JF Bastienf87e20d2015-04-20 23:42:22 +0000287 PointerType *Ty = cast<PointerType>(Alias.getType());
288 Constant *Replacement = ConstantPointerNull::get(Ty);
289 Alias.replaceAllUsesWith(Replacement);
290 ToRemove.push_back(&Alias);
291 }
Chris Lattner1d080f22003-04-24 22:24:58 +0000292
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000293 for (Function &I : *M) {
294 if (!I.isDeclaration() && !Functions.count(&I)) {
295 PointerType *Ty = cast<PointerType>(I.getType());
JF Bastienf87e20d2015-04-20 23:42:22 +0000296 Constant *Replacement = ConstantPointerNull::get(Ty);
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000297 I.replaceAllUsesWith(Replacement);
298 ToRemove.push_back(&I);
JF Bastienf87e20d2015-04-20 23:42:22 +0000299 }
300 }
301
302 for (auto *F : ToRemove) {
303 F->eraseFromParent();
304 }
305
306 // Finally, remove any null members from any global intrinsic.
307 RemoveFunctionReferences(M, "llvm.used");
308 RemoveFunctionReferences(M, "llvm.compiler.used");
309 }
Chris Lattner1d080f22003-04-24 22:24:58 +0000310 // Try running the hacked up program...
Chris Lattner8bda4c42004-02-18 23:26:28 +0000311 if (TestFn(BD, M)) {
Chris Lattner327019b2004-02-18 21:24:48 +0000312 BD.setNewProgram(M); // It crashed, keep the trimmed version...
Chris Lattner1d080f22003-04-24 22:24:58 +0000313
314 // Make sure to use function pointers that point into the now-current
315 // module.
316 Funcs.assign(Functions.begin(), Functions.end());
317 return true;
318 }
Chris Lattner327019b2004-02-18 21:24:48 +0000319 delete M;
Chris Lattner1d080f22003-04-24 22:24:58 +0000320 return false;
321}
322
Chris Lattner16a41312003-04-24 17:02:17 +0000323
Chris Lattner1942f982004-02-18 21:29:46 +0000324namespace {
Chris Lattner2f1aa112004-01-14 03:38:37 +0000325 /// ReduceCrashingBlocks reducer - This works by setting the terminators of
326 /// all terminators except the specified basic blocks to a 'ret' instruction,
327 /// then running the simplify-cfg pass. This has the effect of chopping up
328 /// the CFG really fast which can reduce large functions quickly.
329 ///
Chris Lattner8bda4c42004-02-18 23:26:28 +0000330 class ReduceCrashingBlocks : public ListReducer<const BasicBlock*> {
Chris Lattner2f1aa112004-01-14 03:38:37 +0000331 BugDriver &BD;
Rafael Espindolad1c7ef42010-08-05 03:00:22 +0000332 bool (*TestFn)(const BugDriver &, Module *);
Chris Lattner2f1aa112004-01-14 03:38:37 +0000333 public:
Rafael Espindolad1c7ef42010-08-05 03:00:22 +0000334 ReduceCrashingBlocks(BugDriver &bd,
335 bool (*testFn)(const BugDriver &, Module *))
Chris Lattner8bda4c42004-02-18 23:26:28 +0000336 : BD(bd), TestFn(testFn) {}
Misha Brukman650ba8e2005-04-22 00:00:37 +0000337
Craig Toppere56917c2014-03-08 08:27:28 +0000338 TestResult doTest(std::vector<const BasicBlock*> &Prefix,
339 std::vector<const BasicBlock*> &Kept,
340 std::string &Error) override {
Chris Lattner2f1aa112004-01-14 03:38:37 +0000341 if (!Kept.empty() && TestBlocks(Kept))
342 return KeepSuffix;
343 if (!Prefix.empty() && TestBlocks(Prefix))
344 return KeepPrefix;
345 return NoFailure;
346 }
Misha Brukman650ba8e2005-04-22 00:00:37 +0000347
Chris Lattner8bda4c42004-02-18 23:26:28 +0000348 bool TestBlocks(std::vector<const BasicBlock*> &Prefix);
Chris Lattner2f1aa112004-01-14 03:38:37 +0000349 };
350}
Chris Lattnerf32939b2003-04-24 23:51:38 +0000351
Chris Lattner8bda4c42004-02-18 23:26:28 +0000352bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
Misha Brukman8b2bd4e2003-10-10 17:57:28 +0000353 // Clone the program to try hacking it apart...
Rafael Espindola229e38f2010-10-13 01:36:30 +0000354 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000355 Module *M = CloneModule(BD.getProgram(), VMap).release();
Misha Brukman650ba8e2005-04-22 00:00:37 +0000356
Chris Lattnerf32939b2003-04-24 23:51:38 +0000357 // Convert list to set for fast lookup...
Nick Lewyckyb294e312009-04-04 09:39:23 +0000358 SmallPtrSet<BasicBlock*, 8> Blocks;
359 for (unsigned i = 0, e = BBs.size(); i != e; ++i)
Devang Patel0dc3c2d2010-06-24 00:33:28 +0000360 Blocks.insert(cast<BasicBlock>(VMap[BBs[i]]));
Chris Lattnerf32939b2003-04-24 23:51:38 +0000361
Dan Gohmanee051522009-07-16 15:30:09 +0000362 outs() << "Checking for crash with only these blocks:";
Chris Lattner4f50ebd2003-10-27 04:44:59 +0000363 unsigned NumPrint = Blocks.size();
364 if (NumPrint > 10) NumPrint = 10;
365 for (unsigned i = 0, e = NumPrint; i != e; ++i)
Dan Gohmanee051522009-07-16 15:30:09 +0000366 outs() << " " << BBs[i]->getName();
Chris Lattner4f50ebd2003-10-27 04:44:59 +0000367 if (NumPrint < Blocks.size())
Dan Gohmanee051522009-07-16 15:30:09 +0000368 outs() << "... <" << Blocks.size() << " total>";
369 outs() << ": ";
Chris Lattnerf32939b2003-04-24 23:51:38 +0000370
371 // Loop over and delete any hack up any blocks that are not listed...
372 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
373 for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB)
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000374 if (!Blocks.count(&*BB) && BB->getTerminator()->getNumSuccessors()) {
Chris Lattnerf32939b2003-04-24 23:51:38 +0000375 // Loop over all of the successors of this block, deleting any PHI nodes
376 // that might include it.
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000377 for (succ_iterator SI = succ_begin(&*BB), E = succ_end(&*BB); SI != E;
378 ++SI)
379 (*SI)->removePredecessor(&*BB);
Chris Lattnerf32939b2003-04-24 23:51:38 +0000380
Chris Lattner7855a5c2008-04-28 00:04:58 +0000381 TerminatorInst *BBTerm = BB->getTerminator();
Philip Reames29e641c2016-06-29 00:15:35 +0000382 if (BBTerm->isEHPad() || BBTerm->getType()->isTokenTy())
David Majnemer189d7da2015-11-08 04:16:12 +0000383 continue;
Philip Reames29e641c2016-06-29 00:15:35 +0000384 if (!BBTerm->getType()->isVoidTy())
Owen Anderson5a1acd92009-07-31 20:28:14 +0000385 BBTerm->replaceAllUsesWith(Constant::getNullValue(BBTerm->getType()));
Chris Lattner7b233af2003-11-22 02:10:38 +0000386
Chris Lattner7855a5c2008-04-28 00:04:58 +0000387 // Replace the old terminator instruction.
Chris Lattnerf32939b2003-04-24 23:51:38 +0000388 BB->getInstList().pop_back();
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000389 new UnreachableInst(BB->getContext(), &*BB);
Chris Lattnerf32939b2003-04-24 23:51:38 +0000390 }
391
392 // The CFG Simplifier pass may delete one of the basic blocks we are
393 // interested in. If it does we need to take the block out of the list. Make
394 // a "persistent mapping" by turning basic blocks into <function, name> pairs.
395 // This won't work well if blocks are unnamed, but that is just the risk we
396 // have to take.
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000397 std::vector<std::pair<std::string, std::string> > BlockInfo;
Chris Lattnerf32939b2003-04-24 23:51:38 +0000398
Craig Topper46276792014-08-24 23:23:06 +0000399 for (BasicBlock *BB : Blocks)
Benjamin Kramerf5e2fc42015-05-29 19:43:39 +0000400 BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName());
Chris Lattnerf32939b2003-04-24 23:51:38 +0000401
402 // Now run the CFG simplify pass on the function...
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000403 std::vector<std::string> Passes;
404 Passes.push_back("simplifycfg");
405 Passes.push_back("verify");
Rafael Espindola28b351a2014-08-26 17:19:03 +0000406 std::unique_ptr<Module> New = BD.runPassesOn(M, Passes);
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000407 delete M;
408 if (!New) {
409 errs() << "simplifycfg failed!\n";
410 exit(1);
411 }
Rafael Espindola28b351a2014-08-26 17:19:03 +0000412 M = New.release();
Chris Lattnerf32939b2003-04-24 23:51:38 +0000413
414 // Try running on the hacked up program...
Chris Lattner8bda4c42004-02-18 23:26:28 +0000415 if (TestFn(BD, M)) {
Chris Lattner327019b2004-02-18 21:24:48 +0000416 BD.setNewProgram(M); // It crashed, keep the trimmed version...
Chris Lattnerf32939b2003-04-24 23:51:38 +0000417
418 // Make sure to use basic block pointers that point into the now-current
419 // module, and that they don't include any deleted blocks.
420 BBs.clear();
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000421 const ValueSymbolTable &GST = M->getValueSymbolTable();
Chris Lattnerf32939b2003-04-24 23:51:38 +0000422 for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
Rafael Espindolad1e241a2010-08-10 15:46:11 +0000423 Function *F = cast<Function>(GST.lookup(BlockInfo[i].first));
424 ValueSymbolTable &ST = F->getValueSymbolTable();
Reid Spencer3aaaa0b2007-02-05 20:47:22 +0000425 Value* V = ST.lookup(BlockInfo[i].second);
Owen Anderson55f1c092009-08-13 21:58:54 +0000426 if (V && V->getType() == Type::getLabelTy(V->getContext()))
Reid Spencer3aaaa0b2007-02-05 20:47:22 +0000427 BBs.push_back(cast<BasicBlock>(V));
Chris Lattnerf32939b2003-04-24 23:51:38 +0000428 }
429 return true;
430 }
Chris Lattner327019b2004-02-18 21:24:48 +0000431 delete M; // It didn't crash, try something else.
Chris Lattnerf32939b2003-04-24 23:51:38 +0000432 return false;
433}
434
Nick Lewycky6e090c92009-05-25 05:30:00 +0000435namespace {
Daniel Berlin271ca402016-07-27 16:13:25 +0000436/// Simplify the CFG without completely destroying it.
437/// This is not well defined, but basically comes down to "try to eliminate
438/// unreachable blocks and constant fold terminators without deciding that
439/// certain undefined behavior cuts off the program at the legs".
440void simpleSimplifyCfg(Function &F, SmallVectorImpl<BasicBlock *> &BBs) {
441 if (F.empty())
442 return;
443
444 for (auto *BB : BBs) {
445 ConstantFoldTerminator(BB);
446 MergeBlockIntoPredecessor(BB);
447 }
448
449 // Remove unreachable blocks
450 // removeUnreachableBlocks can't be used here, it will turn various
451 // undefined behavior into unreachables, but bugpoint was the thing that
452 // generated the undefined behavior, and we don't want it to kill the entire
453 // program.
454 SmallPtrSet<BasicBlock *, 16> Visited;
455 for (auto *BB : depth_first(&F.getEntryBlock()))
456 Visited.insert(BB);
457
458 SmallVector<BasicBlock *, 16> Unreachable;
459 for (auto &BB : F)
460 if (!Visited.count(&BB))
461 Unreachable.push_back(&BB);
462
463 // The dead BB's may be in a dead cycle or otherwise have references to each
464 // other. Because of this, we have to drop all references first, then delete
465 // them all at once.
466 for (auto *BB : Unreachable) {
467 for (BasicBlock *Successor : successors(&*BB))
468 if (Visited.count(Successor))
469 Successor->removePredecessor(&*BB);
470 BB->dropAllReferences();
471 }
472 for (auto *BB : Unreachable)
473 BB->eraseFromParent();
474}
475
476/// ReduceCrashingConditionals reducer - This works by changing
477/// conditional branches to unconditional ones, then simplifying the CFG
478/// This has the effect of chopping up the CFG really fast which can reduce
479/// large functions quickly.
480///
481class ReduceCrashingConditionals : public ListReducer<const BasicBlock *> {
482 BugDriver &BD;
483 bool (*TestFn)(const BugDriver &, Module *);
484 bool Direction;
485
486public:
487 ReduceCrashingConditionals(BugDriver &bd,
488 bool (*testFn)(const BugDriver &, Module *),
489 bool Direction)
490 : BD(bd), TestFn(testFn), Direction(Direction) {}
491
492 TestResult doTest(std::vector<const BasicBlock *> &Prefix,
493 std::vector<const BasicBlock *> &Kept,
494 std::string &Error) override {
495 if (!Kept.empty() && TestBlocks(Kept))
496 return KeepSuffix;
497 if (!Prefix.empty() && TestBlocks(Prefix))
498 return KeepPrefix;
499 return NoFailure;
500 }
501
502 bool TestBlocks(std::vector<const BasicBlock *> &Prefix);
503};
504}
505
506bool ReduceCrashingConditionals::TestBlocks(
507 std::vector<const BasicBlock *> &BBs) {
508 // Clone the program to try hacking it apart...
509 ValueToValueMapTy VMap;
510 Module *M = CloneModule(BD.getProgram(), VMap).release();
511
512 // Convert list to set for fast lookup...
513 SmallPtrSet<const BasicBlock *, 8> Blocks;
514 for (const auto *BB: BBs)
515 Blocks.insert(cast<BasicBlock>(VMap[BB]));
516
517 outs() << "Checking for crash with changing conditionals to always jump to "
518 << (Direction ? "true" : "false") << ":";
519 unsigned NumPrint = Blocks.size();
520 if (NumPrint > 10)
521 NumPrint = 10;
522 for (unsigned i = 0, e = NumPrint; i != e; ++i)
523 outs() << " " << BBs[i]->getName();
524 if (NumPrint < Blocks.size())
525 outs() << "... <" << Blocks.size() << " total>";
526 outs() << ": ";
527
528 // Loop over and delete any hack up any blocks that are not listed...
529 for (auto &F: *M)
530 for (auto &BB : F)
531 if (!Blocks.count(&BB)) {
532 auto *BR = dyn_cast<BranchInst>(BB.getTerminator());
533 if (!BR || !BR->isConditional())
534 continue;
535 if (Direction)
536 BR->setCondition(ConstantInt::getTrue(BR->getContext()));
537 else
538 BR->setCondition(ConstantInt::getFalse(BR->getContext()));
539 }
540
541 // The following may destroy some blocks, so we save them first
542 std::vector<std::pair<std::string, std::string>> BlockInfo;
543
544 for (const BasicBlock *BB : Blocks)
545 BlockInfo.emplace_back(BB->getParent()->getName(), BB->getName());
546
547 SmallVector<BasicBlock *, 16> ToProcess;
548 for (auto &F :*M) {
549 for (auto &BB : F)
550 if (!Blocks.count(&BB))
551 ToProcess.push_back(&BB);
552 simpleSimplifyCfg(F, ToProcess);
553 ToProcess.clear();
554 }
555 // Verify we didn't break anything
556 std::vector<std::string> Passes;
557 Passes.push_back("verify");
558 std::unique_ptr<Module> New = BD.runPassesOn(M, Passes);
559 delete M;
560 if (!New) {
561 errs() << "verify failed!\n";
562 exit(1);
563 }
564 M = New.release();
565
566 // Try running on the hacked up program...
567 if (TestFn(BD, M)) {
568 BD.setNewProgram(M); // It crashed, keep the trimmed version...
569
570 // Make sure to use basic block pointers that point into the now-current
571 // module, and that they don't include any deleted blocks.
572 BBs.clear();
573 const ValueSymbolTable &GST = M->getValueSymbolTable();
574 for (auto &BI : BlockInfo) {
575 auto *F = cast<Function>(GST.lookup(BI.first));
576 ValueSymbolTable &ST = F->getValueSymbolTable();
577 Value *V = ST.lookup(BI.second);
578 if (V && V->getType() == Type::getLabelTy(V->getContext()))
579 BBs.push_back(cast<BasicBlock>(V));
580 }
581 return true;
582 }
583 delete M; // It didn't crash, try something else.
584 return false;
585}
586
587namespace {
Nick Lewycky6e090c92009-05-25 05:30:00 +0000588 /// ReduceCrashingInstructions reducer - This works by removing the specified
589 /// non-terminator instructions and replacing them with undef.
590 ///
591 class ReduceCrashingInstructions : public ListReducer<const Instruction*> {
592 BugDriver &BD;
Rafael Espindolad1c7ef42010-08-05 03:00:22 +0000593 bool (*TestFn)(const BugDriver &, Module *);
Nick Lewycky6e090c92009-05-25 05:30:00 +0000594 public:
Rafael Espindolad1c7ef42010-08-05 03:00:22 +0000595 ReduceCrashingInstructions(BugDriver &bd,
596 bool (*testFn)(const BugDriver &, Module *))
Nick Lewycky6e090c92009-05-25 05:30:00 +0000597 : BD(bd), TestFn(testFn) {}
598
Craig Toppere56917c2014-03-08 08:27:28 +0000599 TestResult doTest(std::vector<const Instruction*> &Prefix,
600 std::vector<const Instruction*> &Kept,
601 std::string &Error) override {
Nick Lewycky6e090c92009-05-25 05:30:00 +0000602 if (!Kept.empty() && TestInsts(Kept))
603 return KeepSuffix;
604 if (!Prefix.empty() && TestInsts(Prefix))
605 return KeepPrefix;
606 return NoFailure;
607 }
608
609 bool TestInsts(std::vector<const Instruction*> &Prefix);
610 };
611}
612
613bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*>
614 &Insts) {
615 // Clone the program to try hacking it apart...
Rafael Espindola229e38f2010-10-13 01:36:30 +0000616 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000617 Module *M = CloneModule(BD.getProgram(), VMap).release();
Nick Lewycky6e090c92009-05-25 05:30:00 +0000618
619 // Convert list to set for fast lookup...
Matthias Braunb30f2f512016-01-30 01:24:31 +0000620 SmallPtrSet<Instruction*, 32> Instructions;
Nick Lewycky6e090c92009-05-25 05:30:00 +0000621 for (unsigned i = 0, e = Insts.size(); i != e; ++i) {
622 assert(!isa<TerminatorInst>(Insts[i]));
Devang Patel0dc3c2d2010-06-24 00:33:28 +0000623 Instructions.insert(cast<Instruction>(VMap[Insts[i]]));
Nick Lewycky6e090c92009-05-25 05:30:00 +0000624 }
625
Dan Gohmanee051522009-07-16 15:30:09 +0000626 outs() << "Checking for crash with only " << Instructions.size();
Nick Lewycky6e090c92009-05-25 05:30:00 +0000627 if (Instructions.size() == 1)
Dan Gohmanee051522009-07-16 15:30:09 +0000628 outs() << " instruction: ";
Nick Lewycky6e090c92009-05-25 05:30:00 +0000629 else
Dan Gohmanee051522009-07-16 15:30:09 +0000630 outs() << " instructions: ";
Nick Lewycky6e090c92009-05-25 05:30:00 +0000631
632 for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
633 for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI)
634 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) {
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000635 Instruction *Inst = &*I++;
Eli Friedmand4e02a52011-11-01 04:40:56 +0000636 if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst) &&
Philip Reames29e641c2016-06-29 00:15:35 +0000637 !Inst->isEHPad() && !Inst->getType()->isTokenTy()) {
638 if (!Inst->getType()->isVoidTy())
Nick Lewycky6e090c92009-05-25 05:30:00 +0000639 Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
640 Inst->eraseFromParent();
641 }
642 }
643
644 // Verify that this is still valid.
Chandler Carruth30d69c22015-02-13 10:01:29 +0000645 legacy::PassManager Passes;
Nick Lewycky6e090c92009-05-25 05:30:00 +0000646 Passes.add(createVerifierPass());
647 Passes.run(*M);
648
649 // Try running on the hacked up program...
650 if (TestFn(BD, M)) {
651 BD.setNewProgram(M); // It crashed, keep the trimmed version...
652
653 // Make sure to use instruction pointers that point into the now-current
654 // module, and that they don't include any deleted blocks.
655 Insts.clear();
Craig Topper46276792014-08-24 23:23:06 +0000656 for (Instruction *Inst : Instructions)
657 Insts.push_back(Inst);
Nick Lewycky6e090c92009-05-25 05:30:00 +0000658 return true;
659 }
660 delete M; // It didn't crash, try something else.
661 return false;
662}
663
Keno Fischer34ca8312015-11-06 00:12:50 +0000664namespace {
665// Reduce the list of Named Metadata nodes. We keep this as a list of
666// names to avoid having to convert back and forth every time.
667class ReduceCrashingNamedMD : public ListReducer<std::string> {
668 BugDriver &BD;
669 bool (*TestFn)(const BugDriver &, Module *);
670
671public:
672 ReduceCrashingNamedMD(BugDriver &bd,
673 bool (*testFn)(const BugDriver &, Module *))
674 : BD(bd), TestFn(testFn) {}
675
676 TestResult doTest(std::vector<std::string> &Prefix,
677 std::vector<std::string> &Kept,
678 std::string &Error) override {
679 if (!Kept.empty() && TestNamedMDs(Kept))
680 return KeepSuffix;
681 if (!Prefix.empty() && TestNamedMDs(Prefix))
682 return KeepPrefix;
683 return NoFailure;
684 }
685
686 bool TestNamedMDs(std::vector<std::string> &NamedMDs);
687};
688}
689
690bool ReduceCrashingNamedMD::TestNamedMDs(std::vector<std::string> &NamedMDs) {
691
692 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000693 Module *M = CloneModule(BD.getProgram(), VMap).release();
Keno Fischer34ca8312015-11-06 00:12:50 +0000694
695 outs() << "Checking for crash with only these named metadata nodes:";
696 unsigned NumPrint = std::min<size_t>(NamedMDs.size(), 10);
697 for (unsigned i = 0, e = NumPrint; i != e; ++i)
698 outs() << " " << NamedMDs[i];
699 if (NumPrint < NamedMDs.size())
700 outs() << "... <" << NamedMDs.size() << " total>";
701 outs() << ": ";
702
703 // Make a StringMap for faster lookup
704 StringSet<> Names;
705 for (const std::string &Name : NamedMDs)
706 Names.insert(Name);
707
708 // First collect all the metadata to delete in a vector, then
709 // delete them all at once to avoid invalidating the iterator
710 std::vector<NamedMDNode *> ToDelete;
711 ToDelete.reserve(M->named_metadata_size() - Names.size());
712 for (auto &NamedMD : M->named_metadata())
Adrian Prantlfaebbb02016-03-28 21:06:26 +0000713 // Always keep a nonempty llvm.dbg.cu because the Verifier would complain.
714 if (!Names.count(NamedMD.getName()) &&
715 (!(NamedMD.getName() == "llvm.dbg.cu" && NamedMD.getNumOperands() > 0)))
Keno Fischer34ca8312015-11-06 00:12:50 +0000716 ToDelete.push_back(&NamedMD);
717
718 for (auto *NamedMD : ToDelete)
719 NamedMD->eraseFromParent();
720
721 // Verify that this is still valid.
722 legacy::PassManager Passes;
723 Passes.add(createVerifierPass());
724 Passes.run(*M);
725
726 // Try running on the hacked up program...
727 if (TestFn(BD, M)) {
728 BD.setNewProgram(M); // It crashed, keep the trimmed version...
729 return true;
730 }
731 delete M; // It didn't crash, try something else.
732 return false;
733}
734
735namespace {
736// Reduce the list of operands to named metadata nodes
737class ReduceCrashingNamedMDOps : public ListReducer<const MDNode *> {
738 BugDriver &BD;
739 bool (*TestFn)(const BugDriver &, Module *);
740
741public:
742 ReduceCrashingNamedMDOps(BugDriver &bd,
743 bool (*testFn)(const BugDriver &, Module *))
744 : BD(bd), TestFn(testFn) {}
745
746 TestResult doTest(std::vector<const MDNode *> &Prefix,
747 std::vector<const MDNode *> &Kept,
748 std::string &Error) override {
749 if (!Kept.empty() && TestNamedMDOps(Kept))
750 return KeepSuffix;
751 if (!Prefix.empty() && TestNamedMDOps(Prefix))
752 return KeepPrefix;
753 return NoFailure;
754 }
755
756 bool TestNamedMDOps(std::vector<const MDNode *> &NamedMDOps);
757};
758}
759
760bool ReduceCrashingNamedMDOps::TestNamedMDOps(
761 std::vector<const MDNode *> &NamedMDOps) {
762 // Convert list to set for fast lookup...
Matthias Braunb30f2f512016-01-30 01:24:31 +0000763 SmallPtrSet<const MDNode *, 32> OldMDNodeOps;
Keno Fischer34ca8312015-11-06 00:12:50 +0000764 for (unsigned i = 0, e = NamedMDOps.size(); i != e; ++i) {
765 OldMDNodeOps.insert(NamedMDOps[i]);
766 }
767
768 outs() << "Checking for crash with only " << OldMDNodeOps.size();
769 if (OldMDNodeOps.size() == 1)
770 outs() << " named metadata operand: ";
771 else
772 outs() << " named metadata operands: ";
773
774 ValueToValueMapTy VMap;
Rafael Espindolacab951d2015-12-08 23:57:17 +0000775 Module *M = CloneModule(BD.getProgram(), VMap).release();
Keno Fischer34ca8312015-11-06 00:12:50 +0000776
777 // This is a little wasteful. In the future it might be good if we could have
778 // these dropped during cloning.
779 for (auto &NamedMD : BD.getProgram()->named_metadata()) {
780 // Drop the old one and create a new one
781 M->eraseNamedMetadata(M->getNamedMetadata(NamedMD.getName()));
782 NamedMDNode *NewNamedMDNode =
783 M->getOrInsertNamedMetadata(NamedMD.getName());
784 for (MDNode *op : NamedMD.operands())
785 if (OldMDNodeOps.count(op))
786 NewNamedMDNode->addOperand(cast<MDNode>(MapMetadata(op, VMap)));
787 }
788
789 // Verify that this is still valid.
790 legacy::PassManager Passes;
791 Passes.add(createVerifierPass());
792 Passes.run(*M);
793
794 // Try running on the hacked up program...
795 if (TestFn(BD, M)) {
796 // Make sure to use instruction pointers that point into the now-current
797 // module, and that they don't include any deleted blocks.
798 NamedMDOps.clear();
799 for (const MDNode *Node : OldMDNodeOps)
Duncan P. N. Exon Smithda4a56d2016-04-02 17:04:38 +0000800 NamedMDOps.push_back(cast<MDNode>(*VMap.getMappedMD(Node)));
Keno Fischer34ca8312015-11-06 00:12:50 +0000801
802 BD.setNewProgram(M); // It crashed, keep the trimmed version...
803 return true;
804 }
805 delete M; // It didn't crash, try something else.
806 return false;
807}
808
Philip Reames1c232f92016-06-29 00:43:18 +0000809static void ReduceGlobalInitializers(BugDriver &BD,
810 bool (*TestFn)(const BugDriver &, Module *),
811 std::string &Error) {
812 if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
Bill Wendling3f833432006-10-25 18:36:14 +0000813 // Now try to reduce the number of global variable initializers in the
814 // module to something small.
Rafael Espindolacab951d2015-12-08 23:57:17 +0000815 Module *M = CloneModule(BD.getProgram()).release();
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000816 bool DeletedInit = false;
Misha Brukman650ba8e2005-04-22 00:00:37 +0000817
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000818 for (Module::global_iterator I = M->global_begin(), E = M->global_end();
819 I != E; ++I)
820 if (I->hasInitializer()) {
Hal Finkel28ad2b42015-11-26 19:23:49 +0000821 DeleteGlobalInitializer(&*I);
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000822 I->setLinkage(GlobalValue::ExternalLinkage);
Justin Lebar2a445cf2016-06-15 23:20:12 +0000823 I->setComdat(nullptr);
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000824 DeletedInit = true;
825 }
Bill Wendling3f833432006-10-25 18:36:14 +0000826
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000827 if (!DeletedInit) {
828 delete M; // No change made...
829 } else {
830 // See if the program still causes a crash...
Dan Gohmanee051522009-07-16 15:30:09 +0000831 outs() << "\nChecking to see if we can delete global inits: ";
Bill Wendling3f833432006-10-25 18:36:14 +0000832
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000833 if (TestFn(BD, M)) { // Still crashes?
834 BD.setNewProgram(M);
Dan Gohmanee051522009-07-16 15:30:09 +0000835 outs() << "\n*** Able to remove all global initializers!\n";
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000836 } else { // No longer crashes?
Dan Gohmanee051522009-07-16 15:30:09 +0000837 outs() << " - Removing all global inits hides problem!\n";
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000838 delete M;
Bill Wendling3f833432006-10-25 18:36:14 +0000839
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000840 std::vector<GlobalVariable*> GVs;
841
842 for (Module::global_iterator I = BD.getProgram()->global_begin(),
843 E = BD.getProgram()->global_end(); I != E; ++I)
844 if (I->hasInitializer())
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000845 GVs.push_back(&*I);
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000846
847 if (GVs.size() > 1 && !BugpointIsInterrupted) {
Dan Gohmanee051522009-07-16 15:30:09 +0000848 outs() << "\n*** Attempting to reduce the number of global "
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000849 << "variables in the testcase\n";
850
851 unsigned OldSize = GVs.size();
Nick Lewycky6ba630b2010-04-12 05:08:25 +0000852 ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs, Error);
Philip Reames1c232f92016-06-29 00:43:18 +0000853 assert(!Error.empty());
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000854
855 if (GVs.size() < OldSize)
Rafael Espindola594994a2010-07-28 18:12:30 +0000856 BD.EmitProgressBitcode(BD.getProgram(), "reduced-global-variables");
Bill Wendling74a4a2a2006-10-27 20:18:06 +0000857 }
Bill Wendlingce3afd62006-10-27 20:22:04 +0000858 }
Chris Lattner65e5f652003-04-25 00:53:05 +0000859 }
860 }
Philip Reames1c232f92016-06-29 00:43:18 +0000861}
862
863static void ReduceInsts(BugDriver &BD,
864 bool (*TestFn)(const BugDriver &, Module *),
865 std::string &Error) {
866 // Attempt to delete instructions using bisection. This should help out nasty
867 // cases with large basic blocks where the problem is at one end.
868 if (!BugpointIsInterrupted) {
869 std::vector<const Instruction*> Insts;
870 for (const Function &F : *BD.getProgram())
871 for (const BasicBlock &BB : F)
872 for (const Instruction &I : BB)
873 if (!isa<TerminatorInst>(&I))
874 Insts.push_back(&I);
875
876 ReduceCrashingInstructions(BD, TestFn).reduceList(Insts, Error);
877 }
878
879 unsigned Simplification = 2;
880 do {
881 if (BugpointIsInterrupted)
882 return;
883 --Simplification;
884 outs() << "\n*** Attempting to reduce testcase by deleting instruc"
885 << "tions: Simplification Level #" << Simplification << '\n';
886
887 // Now that we have deleted the functions that are unnecessary for the
888 // program, try to remove instructions that are not necessary to cause the
889 // crash. To do this, we loop through all of the instructions in the
890 // remaining functions, deleting them (replacing any values produced with
891 // nulls), and then running ADCE and SimplifyCFG. If the transformed input
892 // still triggers failure, keep deleting until we cannot trigger failure
893 // anymore.
894 //
895 unsigned InstructionsToSkipBeforeDeleting = 0;
896 TryAgain:
897
898 // Loop over all of the (non-terminator) instructions remaining in the
899 // function, attempting to delete them.
900 unsigned CurInstructionNum = 0;
901 for (Module::const_iterator FI = BD.getProgram()->begin(),
902 E = BD.getProgram()->end(); FI != E; ++FI)
903 if (!FI->isDeclaration())
904 for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E;
905 ++BI)
906 for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end();
907 I != E; ++I, ++CurInstructionNum) {
908 if (InstructionsToSkipBeforeDeleting) {
909 --InstructionsToSkipBeforeDeleting;
910 } else {
911 if (BugpointIsInterrupted)
912 return;
913
914 if (I->isEHPad() || I->getType()->isTokenTy())
915 continue;
916
917 outs() << "Checking instruction: " << *I;
918 std::unique_ptr<Module> M =
919 BD.deleteInstructionFromProgram(&*I, Simplification);
920
921 // Find out if the pass still crashes on this pass...
922 if (TestFn(BD, M.get())) {
923 // Yup, it does, we delete the old module, and continue trying
924 // to reduce the testcase...
925 BD.setNewProgram(M.release());
926 InstructionsToSkipBeforeDeleting = CurInstructionNum;
927 goto TryAgain; // I wish I had a multi-level break here!
928 }
929 }
930 }
931
932 if (InstructionsToSkipBeforeDeleting) {
933 InstructionsToSkipBeforeDeleting = 0;
934 goto TryAgain;
935 }
936
937 } while (Simplification);
938 BD.EmitProgressBitcode(BD.getProgram(), "reduced-instructions");
939}
940
941
942/// DebugACrash - Given a predicate that determines whether a component crashes
943/// on a program, try to destructively reduce the program while still keeping
944/// the predicate true.
945static bool DebugACrash(BugDriver &BD,
946 bool (*TestFn)(const BugDriver &, Module *),
947 std::string &Error) {
948 // See if we can get away with nuking some of the global variable initializers
949 // in the program...
950 if (!NoGlobalRM)
951 ReduceGlobalInitializers(BD, TestFn, Error);
Misha Brukman650ba8e2005-04-22 00:00:37 +0000952
Chris Lattner1d080f22003-04-24 22:24:58 +0000953 // Now try to reduce the number of functions in the module to something small.
Chris Lattnerfd72bed2004-03-14 20:50:42 +0000954 std::vector<Function*> Functions;
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000955 for (Function &F : *BD.getProgram())
956 if (!F.isDeclaration())
957 Functions.push_back(&F);
Chris Lattner73a6bdd2002-11-20 22:28:10 +0000958
Chris Lattnerbeb01fa2005-08-02 02:16:17 +0000959 if (Functions.size() > 1 && !BugpointIsInterrupted) {
Dan Gohmanee051522009-07-16 15:30:09 +0000960 outs() << "\n*** Attempting to reduce the number of functions "
Chris Lattner1d080f22003-04-24 22:24:58 +0000961 "in the testcase\n";
Chris Lattner73a6bdd2002-11-20 22:28:10 +0000962
Chris Lattner8bda4c42004-02-18 23:26:28 +0000963 unsigned OldSize = Functions.size();
Nick Lewycky6ba630b2010-04-12 05:08:25 +0000964 ReduceCrashingFunctions(BD, TestFn).reduceList(Functions, Error);
Chris Lattner73a6bdd2002-11-20 22:28:10 +0000965
Chris Lattnerbeb01fa2005-08-02 02:16:17 +0000966 if (Functions.size() < OldSize)
Rafael Espindola594994a2010-07-28 18:12:30 +0000967 BD.EmitProgressBitcode(BD.getProgram(), "reduced-function");
Chris Lattner73a6bdd2002-11-20 22:28:10 +0000968 }
969
Daniel Berlin271ca402016-07-27 16:13:25 +0000970 // Attempt to change conditional branches into unconditional branches to
971 // eliminate blocks.
972 if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
973 std::vector<const BasicBlock*> Blocks;
974 for (Function &F : *BD.getProgram())
975 for (BasicBlock &BB : F)
976 Blocks.push_back(&BB);
977 unsigned OldSize = Blocks.size();
978 ReduceCrashingConditionals(BD, TestFn, true).reduceList(Blocks, Error);
979 ReduceCrashingConditionals(BD, TestFn, false).reduceList(Blocks, Error);
980 if (Blocks.size() < OldSize)
981 BD.EmitProgressBitcode(BD.getProgram(), "reduced-conditionals");
982 }
983
Chris Lattnerf32939b2003-04-24 23:51:38 +0000984 // Attempt to delete entire basic blocks at a time to speed up
985 // convergence... this actually works by setting the terminator of the blocks
986 // to a return instruction then running simplifycfg, which can potentially
987 // shrinks the code dramatically quickly
988 //
Chris Lattnerbeb01fa2005-08-02 02:16:17 +0000989 if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
Chris Lattner8bda4c42004-02-18 23:26:28 +0000990 std::vector<const BasicBlock*> Blocks;
Duncan P. N. Exon Smith306d16e2015-10-20 19:36:39 +0000991 for (Function &F : *BD.getProgram())
992 for (BasicBlock &BB : F)
993 Blocks.push_back(&BB);
Torok Edwin6ee6f732009-05-24 09:40:47 +0000994 unsigned OldSize = Blocks.size();
Nick Lewycky6ba630b2010-04-12 05:08:25 +0000995 ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks, Error);
Torok Edwin6ee6f732009-05-24 09:40:47 +0000996 if (Blocks.size() < OldSize)
Rafael Espindola594994a2010-07-28 18:12:30 +0000997 BD.EmitProgressBitcode(BD.getProgram(), "reduced-blocks");
Chris Lattnerd1e2aae2003-08-05 15:51:05 +0000998 }
Chris Lattnerd4e04742002-12-23 23:49:59 +0000999
Nick Lewycky6e090c92009-05-25 05:30:00 +00001000 // Attempt to delete instructions using bisection. This should help out nasty
1001 // cases with large basic blocks where the problem is at one end.
Philip Reames1c232f92016-06-29 00:43:18 +00001002 if (!BugpointIsInterrupted)
1003 ReduceInsts(BD, TestFn, Error);
Keno Fischer34ca8312015-11-06 00:12:50 +00001004
1005 if (!NoNamedMDRM) {
Keno Fischer34ca8312015-11-06 00:12:50 +00001006 if (!BugpointIsInterrupted) {
1007 // Try to reduce the amount of global metadata (particularly debug info),
1008 // by dropping global named metadata that anchors them
1009 outs() << "\n*** Attempting to remove named metadata: ";
1010 std::vector<std::string> NamedMDNames;
1011 for (auto &NamedMD : BD.getProgram()->named_metadata())
1012 NamedMDNames.push_back(NamedMD.getName().str());
1013 ReduceCrashingNamedMD(BD, TestFn).reduceList(NamedMDNames, Error);
1014 }
1015
1016 if (!BugpointIsInterrupted) {
1017 // Now that we quickly dropped all the named metadata that doesn't
1018 // contribute to the crash, bisect the operands of the remaining ones
1019 std::vector<const MDNode *> NamedMDOps;
1020 for (auto &NamedMD : BD.getProgram()->named_metadata())
Keno Fischer256df862015-11-06 00:45:47 +00001021 for (auto op : NamedMD.operands())
1022 NamedMDOps.push_back(op);
Keno Fischer34ca8312015-11-06 00:12:50 +00001023 ReduceCrashingNamedMDOps(BD, TestFn).reduceList(NamedMDOps, Error);
1024 }
Philip Reamesac285cc2016-06-29 00:10:39 +00001025 BD.EmitProgressBitcode(BD.getProgram(), "reduced-named-md");
Keno Fischer34ca8312015-11-06 00:12:50 +00001026 }
1027
Chris Lattner514c02e2003-02-28 16:13:20 +00001028 // Try to clean up the testcase by running funcresolve and globaldce...
Chris Lattnerbeb01fa2005-08-02 02:16:17 +00001029 if (!BugpointIsInterrupted) {
Dan Gohmanee051522009-07-16 15:30:09 +00001030 outs() << "\n*** Attempting to perform final cleanups: ";
Rafael Espindolacab951d2015-12-08 23:57:17 +00001031 Module *M = CloneModule(BD.getProgram()).release();
Rafael Espindola28b351a2014-08-26 17:19:03 +00001032 M = BD.performFinalCleanups(M, true).release();
Misha Brukman650ba8e2005-04-22 00:00:37 +00001033
Chris Lattnerbeb01fa2005-08-02 02:16:17 +00001034 // Find out if the pass still crashes on the cleaned up program...
1035 if (TestFn(BD, M)) {
1036 BD.setNewProgram(M); // Yup, it does, keep the reduced version...
1037 } else {
1038 delete M;
1039 }
Chris Lattner514c02e2003-02-28 16:13:20 +00001040 }
1041
Rafael Espindola594994a2010-07-28 18:12:30 +00001042 BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplified");
Chris Lattner514c02e2003-02-28 16:13:20 +00001043
Misha Brukman650ba8e2005-04-22 00:00:37 +00001044 return false;
Chris Lattner73a6bdd2002-11-20 22:28:10 +00001045}
Brian Gaeke960707c2003-11-11 22:41:34 +00001046
Rafael Espindolad1c7ef42010-08-05 03:00:22 +00001047static bool TestForOptimizerCrash(const BugDriver &BD, Module *M) {
Philip Reamese5b56022016-06-29 03:01:13 +00001048 return BD.runPasses(M, BD.getPassesToRun());
Chris Lattner8bda4c42004-02-18 23:26:28 +00001049}
Chris Lattneread1dff2004-02-18 21:02:04 +00001050
Chris Lattner8bda4c42004-02-18 23:26:28 +00001051/// debugOptimizerCrash - This method is called when some pass crashes on input.
1052/// It attempts to prune down the testcase to something reasonable, and figure
1053/// out exactly which pass is crashing.
1054///
Patrick Jenkinsc46c0382006-08-15 16:40:49 +00001055bool BugDriver::debugOptimizerCrash(const std::string &ID) {
Dan Gohmanee051522009-07-16 15:30:09 +00001056 outs() << "\n*** Debugging optimizer crash!\n";
Chris Lattner8bda4c42004-02-18 23:26:28 +00001057
Nick Lewycky6ba630b2010-04-12 05:08:25 +00001058 std::string Error;
Chris Lattner8bda4c42004-02-18 23:26:28 +00001059 // Reduce the list of passes which causes the optimizer to crash...
JF Bastienf87e20d2015-04-20 23:42:22 +00001060 if (!BugpointIsInterrupted && !DontReducePassList)
Nick Lewycky6ba630b2010-04-12 05:08:25 +00001061 ReducePassList(*this).reduceList(PassesToRun, Error);
1062 assert(Error.empty());
Chris Lattner8bda4c42004-02-18 23:26:28 +00001063
Dan Gohmanee051522009-07-16 15:30:09 +00001064 outs() << "\n*** Found crashing pass"
1065 << (PassesToRun.size() == 1 ? ": " : "es: ")
1066 << getPassesString(PassesToRun) << '\n';
Chris Lattner8bda4c42004-02-18 23:26:28 +00001067
Rafael Espindola594994a2010-07-28 18:12:30 +00001068 EmitProgressBitcode(Program, ID);
Chris Lattner8bda4c42004-02-18 23:26:28 +00001069
Nick Lewycky6ba630b2010-04-12 05:08:25 +00001070 bool Success = DebugACrash(*this, TestForOptimizerCrash, Error);
1071 assert(Error.empty());
1072 return Success;
Chris Lattner8bda4c42004-02-18 23:26:28 +00001073}
1074
Rafael Espindolad1c7ef42010-08-05 03:00:22 +00001075static bool TestForCodeGenCrash(const BugDriver &BD, Module *M) {
Nick Lewycky6ba630b2010-04-12 05:08:25 +00001076 std::string Error;
1077 BD.compileProgram(M, &Error);
1078 if (!Error.empty()) {
Sebastian Pop8f7d0192016-07-15 23:15:06 +00001079 if (VerboseErrors)
1080 errs() << Error << "\n";
1081 else
1082 errs() << "<crash>\n";
Chris Lattner8bda4c42004-02-18 23:26:28 +00001083 return true; // Tool is still crashing.
1084 }
Nick Lewycky6ba630b2010-04-12 05:08:25 +00001085 errs() << '\n';
1086 return false;
Chris Lattner8bda4c42004-02-18 23:26:28 +00001087}
Chris Lattneread1dff2004-02-18 21:02:04 +00001088
1089/// debugCodeGeneratorCrash - This method is called when the code generator
1090/// crashes on an input. It attempts to reduce the input as much as possible
1091/// while still causing the code generator to crash.
Nick Lewycky6ba630b2010-04-12 05:08:25 +00001092bool BugDriver::debugCodeGeneratorCrash(std::string &Error) {
Dan Gohmand8db3762009-07-15 16:35:29 +00001093 errs() << "*** Debugging code generator crash!\n";
Chris Lattneread1dff2004-02-18 21:02:04 +00001094
Nick Lewycky6ba630b2010-04-12 05:08:25 +00001095 return DebugACrash(*this, TestForCodeGenCrash, Error);
Chris Lattneread1dff2004-02-18 21:02:04 +00001096}