1*0b57cec5SDimitry Andric //===- Miscompilation.cpp - Debug program miscompilations -----------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file implements optimizer and code generation miscompilation debugging 10*0b57cec5SDimitry Andric // support. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "BugDriver.h" 15*0b57cec5SDimitry Andric #include "ListReducer.h" 16*0b57cec5SDimitry Andric #include "ToolRunner.h" 17*0b57cec5SDimitry Andric #include "llvm/Config/config.h" // for HAVE_LINK_R 18*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 19*0b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 20*0b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 21*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 22*0b57cec5SDimitry Andric #include "llvm/IR/Verifier.h" 23*0b57cec5SDimitry Andric #include "llvm/Linker/Linker.h" 24*0b57cec5SDimitry Andric #include "llvm/Pass.h" 25*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 26*0b57cec5SDimitry Andric #include "llvm/Support/FileUtilities.h" 27*0b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric using namespace llvm; 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric namespace llvm { 32*0b57cec5SDimitry Andric extern cl::opt<std::string> OutputPrefix; 33*0b57cec5SDimitry Andric extern cl::list<std::string> InputArgv; 34*0b57cec5SDimitry Andric } // end namespace llvm 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric namespace { 37*0b57cec5SDimitry Andric static llvm::cl::opt<bool> DisableLoopExtraction( 38*0b57cec5SDimitry Andric "disable-loop-extraction", 39*0b57cec5SDimitry Andric cl::desc("Don't extract loops when searching for miscompilations"), 40*0b57cec5SDimitry Andric cl::init(false)); 41*0b57cec5SDimitry Andric static llvm::cl::opt<bool> DisableBlockExtraction( 42*0b57cec5SDimitry Andric "disable-block-extraction", 43*0b57cec5SDimitry Andric cl::desc("Don't extract blocks when searching for miscompilations"), 44*0b57cec5SDimitry Andric cl::init(false)); 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric class ReduceMiscompilingPasses : public ListReducer<std::string> { 47*0b57cec5SDimitry Andric BugDriver &BD; 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric public: 50*0b57cec5SDimitry Andric ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {} 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric Expected<TestResult> doTest(std::vector<std::string> &Prefix, 53*0b57cec5SDimitry Andric std::vector<std::string> &Suffix) override; 54*0b57cec5SDimitry Andric }; 55*0b57cec5SDimitry Andric } // end anonymous namespace 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric /// TestResult - After passes have been split into a test group and a control 58*0b57cec5SDimitry Andric /// group, see if they still break the program. 59*0b57cec5SDimitry Andric /// 60*0b57cec5SDimitry Andric Expected<ReduceMiscompilingPasses::TestResult> 61*0b57cec5SDimitry Andric ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, 62*0b57cec5SDimitry Andric std::vector<std::string> &Suffix) { 63*0b57cec5SDimitry Andric // First, run the program with just the Suffix passes. If it is still broken 64*0b57cec5SDimitry Andric // with JUST the kept passes, discard the prefix passes. 65*0b57cec5SDimitry Andric outs() << "Checking to see if '" << getPassesString(Suffix) 66*0b57cec5SDimitry Andric << "' compiles correctly: "; 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric std::string BitcodeResult; 69*0b57cec5SDimitry Andric if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false /*delete*/, 70*0b57cec5SDimitry Andric true /*quiet*/)) { 71*0b57cec5SDimitry Andric errs() << " Error running this sequence of passes" 72*0b57cec5SDimitry Andric << " on the input program!\n"; 73*0b57cec5SDimitry Andric BD.setPassesToRun(Suffix); 74*0b57cec5SDimitry Andric BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 75*0b57cec5SDimitry Andric // TODO: This should propagate the error instead of exiting. 76*0b57cec5SDimitry Andric if (Error E = BD.debugOptimizerCrash()) 77*0b57cec5SDimitry Andric exit(1); 78*0b57cec5SDimitry Andric exit(0); 79*0b57cec5SDimitry Andric } 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric // Check to see if the finished program matches the reference output... 82*0b57cec5SDimitry Andric Expected<bool> Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", 83*0b57cec5SDimitry Andric true /*delete bitcode*/); 84*0b57cec5SDimitry Andric if (Error E = Diff.takeError()) 85*0b57cec5SDimitry Andric return std::move(E); 86*0b57cec5SDimitry Andric if (*Diff) { 87*0b57cec5SDimitry Andric outs() << " nope.\n"; 88*0b57cec5SDimitry Andric if (Suffix.empty()) { 89*0b57cec5SDimitry Andric errs() << BD.getToolName() << ": I'm confused: the test fails when " 90*0b57cec5SDimitry Andric << "no passes are run, nondeterministic program?\n"; 91*0b57cec5SDimitry Andric exit(1); 92*0b57cec5SDimitry Andric } 93*0b57cec5SDimitry Andric return KeepSuffix; // Miscompilation detected! 94*0b57cec5SDimitry Andric } 95*0b57cec5SDimitry Andric outs() << " yup.\n"; // No miscompilation! 96*0b57cec5SDimitry Andric 97*0b57cec5SDimitry Andric if (Prefix.empty()) 98*0b57cec5SDimitry Andric return NoFailure; 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric // Next, see if the program is broken if we run the "prefix" passes first, 101*0b57cec5SDimitry Andric // then separately run the "kept" passes. 102*0b57cec5SDimitry Andric outs() << "Checking to see if '" << getPassesString(Prefix) 103*0b57cec5SDimitry Andric << "' compiles correctly: "; 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric // If it is not broken with the kept passes, it's possible that the prefix 106*0b57cec5SDimitry Andric // passes must be run before the kept passes to break it. If the program 107*0b57cec5SDimitry Andric // WORKS after the prefix passes, but then fails if running the prefix AND 108*0b57cec5SDimitry Andric // kept passes, we can update our bitcode file to include the result of the 109*0b57cec5SDimitry Andric // prefix passes, then discard the prefix passes. 110*0b57cec5SDimitry Andric // 111*0b57cec5SDimitry Andric if (BD.runPasses(BD.getProgram(), Prefix, BitcodeResult, false /*delete*/, 112*0b57cec5SDimitry Andric true /*quiet*/)) { 113*0b57cec5SDimitry Andric errs() << " Error running this sequence of passes" 114*0b57cec5SDimitry Andric << " on the input program!\n"; 115*0b57cec5SDimitry Andric BD.setPassesToRun(Prefix); 116*0b57cec5SDimitry Andric BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 117*0b57cec5SDimitry Andric // TODO: This should propagate the error instead of exiting. 118*0b57cec5SDimitry Andric if (Error E = BD.debugOptimizerCrash()) 119*0b57cec5SDimitry Andric exit(1); 120*0b57cec5SDimitry Andric exit(0); 121*0b57cec5SDimitry Andric } 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric // If the prefix maintains the predicate by itself, only keep the prefix! 124*0b57cec5SDimitry Andric Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", false); 125*0b57cec5SDimitry Andric if (Error E = Diff.takeError()) 126*0b57cec5SDimitry Andric return std::move(E); 127*0b57cec5SDimitry Andric if (*Diff) { 128*0b57cec5SDimitry Andric outs() << " nope.\n"; 129*0b57cec5SDimitry Andric sys::fs::remove(BitcodeResult); 130*0b57cec5SDimitry Andric return KeepPrefix; 131*0b57cec5SDimitry Andric } 132*0b57cec5SDimitry Andric outs() << " yup.\n"; // No miscompilation! 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric // Ok, so now we know that the prefix passes work, try running the suffix 135*0b57cec5SDimitry Andric // passes on the result of the prefix passes. 136*0b57cec5SDimitry Andric // 137*0b57cec5SDimitry Andric std::unique_ptr<Module> PrefixOutput = 138*0b57cec5SDimitry Andric parseInputFile(BitcodeResult, BD.getContext()); 139*0b57cec5SDimitry Andric if (!PrefixOutput) { 140*0b57cec5SDimitry Andric errs() << BD.getToolName() << ": Error reading bitcode file '" 141*0b57cec5SDimitry Andric << BitcodeResult << "'!\n"; 142*0b57cec5SDimitry Andric exit(1); 143*0b57cec5SDimitry Andric } 144*0b57cec5SDimitry Andric sys::fs::remove(BitcodeResult); 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric // Don't check if there are no passes in the suffix. 147*0b57cec5SDimitry Andric if (Suffix.empty()) 148*0b57cec5SDimitry Andric return NoFailure; 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric outs() << "Checking to see if '" << getPassesString(Suffix) 151*0b57cec5SDimitry Andric << "' passes compile correctly after the '" << getPassesString(Prefix) 152*0b57cec5SDimitry Andric << "' passes: "; 153*0b57cec5SDimitry Andric 154*0b57cec5SDimitry Andric std::unique_ptr<Module> OriginalInput = 155*0b57cec5SDimitry Andric BD.swapProgramIn(std::move(PrefixOutput)); 156*0b57cec5SDimitry Andric if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false /*delete*/, 157*0b57cec5SDimitry Andric true /*quiet*/)) { 158*0b57cec5SDimitry Andric errs() << " Error running this sequence of passes" 159*0b57cec5SDimitry Andric << " on the input program!\n"; 160*0b57cec5SDimitry Andric BD.setPassesToRun(Suffix); 161*0b57cec5SDimitry Andric BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 162*0b57cec5SDimitry Andric // TODO: This should propagate the error instead of exiting. 163*0b57cec5SDimitry Andric if (Error E = BD.debugOptimizerCrash()) 164*0b57cec5SDimitry Andric exit(1); 165*0b57cec5SDimitry Andric exit(0); 166*0b57cec5SDimitry Andric } 167*0b57cec5SDimitry Andric 168*0b57cec5SDimitry Andric // Run the result... 169*0b57cec5SDimitry Andric Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", 170*0b57cec5SDimitry Andric true /*delete bitcode*/); 171*0b57cec5SDimitry Andric if (Error E = Diff.takeError()) 172*0b57cec5SDimitry Andric return std::move(E); 173*0b57cec5SDimitry Andric if (*Diff) { 174*0b57cec5SDimitry Andric outs() << " nope.\n"; 175*0b57cec5SDimitry Andric return KeepSuffix; 176*0b57cec5SDimitry Andric } 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric // Otherwise, we must not be running the bad pass anymore. 179*0b57cec5SDimitry Andric outs() << " yup.\n"; // No miscompilation! 180*0b57cec5SDimitry Andric // Restore orig program & free test. 181*0b57cec5SDimitry Andric BD.setNewProgram(std::move(OriginalInput)); 182*0b57cec5SDimitry Andric return NoFailure; 183*0b57cec5SDimitry Andric } 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric namespace { 186*0b57cec5SDimitry Andric class ReduceMiscompilingFunctions : public ListReducer<Function *> { 187*0b57cec5SDimitry Andric BugDriver &BD; 188*0b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 189*0b57cec5SDimitry Andric std::unique_ptr<Module>); 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andric public: 192*0b57cec5SDimitry Andric ReduceMiscompilingFunctions(BugDriver &bd, 193*0b57cec5SDimitry Andric Expected<bool> (*F)(BugDriver &, 194*0b57cec5SDimitry Andric std::unique_ptr<Module>, 195*0b57cec5SDimitry Andric std::unique_ptr<Module>)) 196*0b57cec5SDimitry Andric : BD(bd), TestFn(F) {} 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric Expected<TestResult> doTest(std::vector<Function *> &Prefix, 199*0b57cec5SDimitry Andric std::vector<Function *> &Suffix) override { 200*0b57cec5SDimitry Andric if (!Suffix.empty()) { 201*0b57cec5SDimitry Andric Expected<bool> Ret = TestFuncs(Suffix); 202*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 203*0b57cec5SDimitry Andric return std::move(E); 204*0b57cec5SDimitry Andric if (*Ret) 205*0b57cec5SDimitry Andric return KeepSuffix; 206*0b57cec5SDimitry Andric } 207*0b57cec5SDimitry Andric if (!Prefix.empty()) { 208*0b57cec5SDimitry Andric Expected<bool> Ret = TestFuncs(Prefix); 209*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 210*0b57cec5SDimitry Andric return std::move(E); 211*0b57cec5SDimitry Andric if (*Ret) 212*0b57cec5SDimitry Andric return KeepPrefix; 213*0b57cec5SDimitry Andric } 214*0b57cec5SDimitry Andric return NoFailure; 215*0b57cec5SDimitry Andric } 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric Expected<bool> TestFuncs(const std::vector<Function *> &Prefix); 218*0b57cec5SDimitry Andric }; 219*0b57cec5SDimitry Andric } // end anonymous namespace 220*0b57cec5SDimitry Andric 221*0b57cec5SDimitry Andric /// Given two modules, link them together and run the program, checking to see 222*0b57cec5SDimitry Andric /// if the program matches the diff. If there is an error, return NULL. If not, 223*0b57cec5SDimitry Andric /// return the merged module. The Broken argument will be set to true if the 224*0b57cec5SDimitry Andric /// output is different. If the DeleteInputs argument is set to true then this 225*0b57cec5SDimitry Andric /// function deletes both input modules before it returns. 226*0b57cec5SDimitry Andric /// 227*0b57cec5SDimitry Andric static Expected<std::unique_ptr<Module>> testMergedProgram(const BugDriver &BD, 228*0b57cec5SDimitry Andric const Module &M1, 229*0b57cec5SDimitry Andric const Module &M2, 230*0b57cec5SDimitry Andric bool &Broken) { 231*0b57cec5SDimitry Andric // Resulting merge of M1 and M2. 232*0b57cec5SDimitry Andric auto Merged = CloneModule(M1); 233*0b57cec5SDimitry Andric if (Linker::linkModules(*Merged, CloneModule(M2))) 234*0b57cec5SDimitry Andric // TODO: Shouldn't we thread the error up instead of exiting? 235*0b57cec5SDimitry Andric exit(1); 236*0b57cec5SDimitry Andric 237*0b57cec5SDimitry Andric // Execute the program. 238*0b57cec5SDimitry Andric Expected<bool> Diff = BD.diffProgram(*Merged, "", "", false); 239*0b57cec5SDimitry Andric if (Error E = Diff.takeError()) 240*0b57cec5SDimitry Andric return std::move(E); 241*0b57cec5SDimitry Andric Broken = *Diff; 242*0b57cec5SDimitry Andric return std::move(Merged); 243*0b57cec5SDimitry Andric } 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric /// split functions in a Module into two groups: those that are under 246*0b57cec5SDimitry Andric /// consideration for miscompilation vs. those that are not, and test 247*0b57cec5SDimitry Andric /// accordingly. Each group of functions becomes a separate Module. 248*0b57cec5SDimitry Andric Expected<bool> 249*0b57cec5SDimitry Andric ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function *> &Funcs) { 250*0b57cec5SDimitry Andric // Test to see if the function is misoptimized if we ONLY run it on the 251*0b57cec5SDimitry Andric // functions listed in Funcs. 252*0b57cec5SDimitry Andric outs() << "Checking to see if the program is misoptimized when " 253*0b57cec5SDimitry Andric << (Funcs.size() == 1 ? "this function is" : "these functions are") 254*0b57cec5SDimitry Andric << " run through the pass" 255*0b57cec5SDimitry Andric << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":"; 256*0b57cec5SDimitry Andric PrintFunctionList(Funcs); 257*0b57cec5SDimitry Andric outs() << '\n'; 258*0b57cec5SDimitry Andric 259*0b57cec5SDimitry Andric // Create a clone for two reasons: 260*0b57cec5SDimitry Andric // * If the optimization passes delete any function, the deleted function 261*0b57cec5SDimitry Andric // will be in the clone and Funcs will still point to valid memory 262*0b57cec5SDimitry Andric // * If the optimization passes use interprocedural information to break 263*0b57cec5SDimitry Andric // a function, we want to continue with the original function. Otherwise 264*0b57cec5SDimitry Andric // we can conclude that a function triggers the bug when in fact one 265*0b57cec5SDimitry Andric // needs a larger set of original functions to do so. 266*0b57cec5SDimitry Andric ValueToValueMapTy VMap; 267*0b57cec5SDimitry Andric std::unique_ptr<Module> Clone = CloneModule(BD.getProgram(), VMap); 268*0b57cec5SDimitry Andric std::unique_ptr<Module> Orig = BD.swapProgramIn(std::move(Clone)); 269*0b57cec5SDimitry Andric 270*0b57cec5SDimitry Andric std::vector<Function *> FuncsOnClone; 271*0b57cec5SDimitry Andric for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { 272*0b57cec5SDimitry Andric Function *F = cast<Function>(VMap[Funcs[i]]); 273*0b57cec5SDimitry Andric FuncsOnClone.push_back(F); 274*0b57cec5SDimitry Andric } 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric // Split the module into the two halves of the program we want. 277*0b57cec5SDimitry Andric VMap.clear(); 278*0b57cec5SDimitry Andric std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); 279*0b57cec5SDimitry Andric std::unique_ptr<Module> ToOptimize = 280*0b57cec5SDimitry Andric SplitFunctionsOutOfModule(ToNotOptimize.get(), FuncsOnClone, VMap); 281*0b57cec5SDimitry Andric 282*0b57cec5SDimitry Andric Expected<bool> Broken = 283*0b57cec5SDimitry Andric TestFn(BD, std::move(ToOptimize), std::move(ToNotOptimize)); 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andric BD.setNewProgram(std::move(Orig)); 286*0b57cec5SDimitry Andric 287*0b57cec5SDimitry Andric return Broken; 288*0b57cec5SDimitry Andric } 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric /// Give anonymous global values names. 291*0b57cec5SDimitry Andric static void DisambiguateGlobalSymbols(Module &M) { 292*0b57cec5SDimitry Andric for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; 293*0b57cec5SDimitry Andric ++I) 294*0b57cec5SDimitry Andric if (!I->hasName()) 295*0b57cec5SDimitry Andric I->setName("anon_global"); 296*0b57cec5SDimitry Andric for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 297*0b57cec5SDimitry Andric if (!I->hasName()) 298*0b57cec5SDimitry Andric I->setName("anon_fn"); 299*0b57cec5SDimitry Andric } 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric /// Given a reduced list of functions that still exposed the bug, check to see 302*0b57cec5SDimitry Andric /// if we can extract the loops in the region without obscuring the bug. If so, 303*0b57cec5SDimitry Andric /// it reduces the amount of code identified. 304*0b57cec5SDimitry Andric /// 305*0b57cec5SDimitry Andric static Expected<bool> 306*0b57cec5SDimitry Andric ExtractLoops(BugDriver &BD, 307*0b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 308*0b57cec5SDimitry Andric std::unique_ptr<Module>), 309*0b57cec5SDimitry Andric std::vector<Function *> &MiscompiledFunctions) { 310*0b57cec5SDimitry Andric bool MadeChange = false; 311*0b57cec5SDimitry Andric while (1) { 312*0b57cec5SDimitry Andric if (BugpointIsInterrupted) 313*0b57cec5SDimitry Andric return MadeChange; 314*0b57cec5SDimitry Andric 315*0b57cec5SDimitry Andric ValueToValueMapTy VMap; 316*0b57cec5SDimitry Andric std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); 317*0b57cec5SDimitry Andric std::unique_ptr<Module> ToOptimize = SplitFunctionsOutOfModule( 318*0b57cec5SDimitry Andric ToNotOptimize.get(), MiscompiledFunctions, VMap); 319*0b57cec5SDimitry Andric std::unique_ptr<Module> ToOptimizeLoopExtracted = 320*0b57cec5SDimitry Andric BD.extractLoop(ToOptimize.get()); 321*0b57cec5SDimitry Andric if (!ToOptimizeLoopExtracted) 322*0b57cec5SDimitry Andric // If the loop extractor crashed or if there were no extractible loops, 323*0b57cec5SDimitry Andric // then this chapter of our odyssey is over with. 324*0b57cec5SDimitry Andric return MadeChange; 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric errs() << "Extracted a loop from the breaking portion of the program.\n"; 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andric // Bugpoint is intentionally not very trusting of LLVM transformations. In 329*0b57cec5SDimitry Andric // particular, we're not going to assume that the loop extractor works, so 330*0b57cec5SDimitry Andric // we're going to test the newly loop extracted program to make sure nothing 331*0b57cec5SDimitry Andric // has broken. If something broke, then we'll inform the user and stop 332*0b57cec5SDimitry Andric // extraction. 333*0b57cec5SDimitry Andric AbstractInterpreter *AI = BD.switchToSafeInterpreter(); 334*0b57cec5SDimitry Andric bool Failure; 335*0b57cec5SDimitry Andric Expected<std::unique_ptr<Module>> New = testMergedProgram( 336*0b57cec5SDimitry Andric BD, *ToOptimizeLoopExtracted, *ToNotOptimize, Failure); 337*0b57cec5SDimitry Andric if (Error E = New.takeError()) 338*0b57cec5SDimitry Andric return std::move(E); 339*0b57cec5SDimitry Andric if (!*New) 340*0b57cec5SDimitry Andric return false; 341*0b57cec5SDimitry Andric 342*0b57cec5SDimitry Andric // Delete the original and set the new program. 343*0b57cec5SDimitry Andric std::unique_ptr<Module> Old = BD.swapProgramIn(std::move(*New)); 344*0b57cec5SDimitry Andric for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 345*0b57cec5SDimitry Andric MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]); 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric if (Failure) { 348*0b57cec5SDimitry Andric BD.switchToInterpreter(AI); 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric // Merged program doesn't work anymore! 351*0b57cec5SDimitry Andric errs() << " *** ERROR: Loop extraction broke the program. :(" 352*0b57cec5SDimitry Andric << " Please report a bug!\n"; 353*0b57cec5SDimitry Andric errs() << " Continuing on with un-loop-extracted version.\n"; 354*0b57cec5SDimitry Andric 355*0b57cec5SDimitry Andric BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-tno.bc", 356*0b57cec5SDimitry Andric *ToNotOptimize); 357*0b57cec5SDimitry Andric BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to.bc", 358*0b57cec5SDimitry Andric *ToOptimize); 359*0b57cec5SDimitry Andric BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc", 360*0b57cec5SDimitry Andric *ToOptimizeLoopExtracted); 361*0b57cec5SDimitry Andric 362*0b57cec5SDimitry Andric errs() << "Please submit the " << OutputPrefix 363*0b57cec5SDimitry Andric << "-loop-extract-fail-*.bc files.\n"; 364*0b57cec5SDimitry Andric return MadeChange; 365*0b57cec5SDimitry Andric } 366*0b57cec5SDimitry Andric BD.switchToInterpreter(AI); 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric outs() << " Testing after loop extraction:\n"; 369*0b57cec5SDimitry Andric // Clone modules, the tester function will free them. 370*0b57cec5SDimitry Andric std::unique_ptr<Module> TOLEBackup = 371*0b57cec5SDimitry Andric CloneModule(*ToOptimizeLoopExtracted, VMap); 372*0b57cec5SDimitry Andric std::unique_ptr<Module> TNOBackup = CloneModule(*ToNotOptimize, VMap); 373*0b57cec5SDimitry Andric 374*0b57cec5SDimitry Andric for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 375*0b57cec5SDimitry Andric MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]); 376*0b57cec5SDimitry Andric 377*0b57cec5SDimitry Andric Expected<bool> Result = TestFn(BD, std::move(ToOptimizeLoopExtracted), 378*0b57cec5SDimitry Andric std::move(ToNotOptimize)); 379*0b57cec5SDimitry Andric if (Error E = Result.takeError()) 380*0b57cec5SDimitry Andric return std::move(E); 381*0b57cec5SDimitry Andric 382*0b57cec5SDimitry Andric ToOptimizeLoopExtracted = std::move(TOLEBackup); 383*0b57cec5SDimitry Andric ToNotOptimize = std::move(TNOBackup); 384*0b57cec5SDimitry Andric 385*0b57cec5SDimitry Andric if (!*Result) { 386*0b57cec5SDimitry Andric outs() << "*** Loop extraction masked the problem. Undoing.\n"; 387*0b57cec5SDimitry Andric // If the program is not still broken, then loop extraction did something 388*0b57cec5SDimitry Andric // that masked the error. Stop loop extraction now. 389*0b57cec5SDimitry Andric 390*0b57cec5SDimitry Andric std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; 391*0b57cec5SDimitry Andric for (Function *F : MiscompiledFunctions) { 392*0b57cec5SDimitry Andric MisCompFunctions.emplace_back(F->getName(), F->getFunctionType()); 393*0b57cec5SDimitry Andric } 394*0b57cec5SDimitry Andric 395*0b57cec5SDimitry Andric if (Linker::linkModules(*ToNotOptimize, 396*0b57cec5SDimitry Andric std::move(ToOptimizeLoopExtracted))) 397*0b57cec5SDimitry Andric exit(1); 398*0b57cec5SDimitry Andric 399*0b57cec5SDimitry Andric MiscompiledFunctions.clear(); 400*0b57cec5SDimitry Andric for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 401*0b57cec5SDimitry Andric Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); 402*0b57cec5SDimitry Andric 403*0b57cec5SDimitry Andric assert(NewF && "Function not found??"); 404*0b57cec5SDimitry Andric MiscompiledFunctions.push_back(NewF); 405*0b57cec5SDimitry Andric } 406*0b57cec5SDimitry Andric 407*0b57cec5SDimitry Andric BD.setNewProgram(std::move(ToNotOptimize)); 408*0b57cec5SDimitry Andric return MadeChange; 409*0b57cec5SDimitry Andric } 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andric outs() << "*** Loop extraction successful!\n"; 412*0b57cec5SDimitry Andric 413*0b57cec5SDimitry Andric std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; 414*0b57cec5SDimitry Andric for (Module::iterator I = ToOptimizeLoopExtracted->begin(), 415*0b57cec5SDimitry Andric E = ToOptimizeLoopExtracted->end(); 416*0b57cec5SDimitry Andric I != E; ++I) 417*0b57cec5SDimitry Andric if (!I->isDeclaration()) 418*0b57cec5SDimitry Andric MisCompFunctions.emplace_back(I->getName(), I->getFunctionType()); 419*0b57cec5SDimitry Andric 420*0b57cec5SDimitry Andric // Okay, great! Now we know that we extracted a loop and that loop 421*0b57cec5SDimitry Andric // extraction both didn't break the program, and didn't mask the problem. 422*0b57cec5SDimitry Andric // Replace the current program with the loop extracted version, and try to 423*0b57cec5SDimitry Andric // extract another loop. 424*0b57cec5SDimitry Andric if (Linker::linkModules(*ToNotOptimize, std::move(ToOptimizeLoopExtracted))) 425*0b57cec5SDimitry Andric exit(1); 426*0b57cec5SDimitry Andric 427*0b57cec5SDimitry Andric // All of the Function*'s in the MiscompiledFunctions list are in the old 428*0b57cec5SDimitry Andric // module. Update this list to include all of the functions in the 429*0b57cec5SDimitry Andric // optimized and loop extracted module. 430*0b57cec5SDimitry Andric MiscompiledFunctions.clear(); 431*0b57cec5SDimitry Andric for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 432*0b57cec5SDimitry Andric Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); 433*0b57cec5SDimitry Andric 434*0b57cec5SDimitry Andric assert(NewF && "Function not found??"); 435*0b57cec5SDimitry Andric MiscompiledFunctions.push_back(NewF); 436*0b57cec5SDimitry Andric } 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andric BD.setNewProgram(std::move(ToNotOptimize)); 439*0b57cec5SDimitry Andric MadeChange = true; 440*0b57cec5SDimitry Andric } 441*0b57cec5SDimitry Andric } 442*0b57cec5SDimitry Andric 443*0b57cec5SDimitry Andric namespace { 444*0b57cec5SDimitry Andric class ReduceMiscompiledBlocks : public ListReducer<BasicBlock *> { 445*0b57cec5SDimitry Andric BugDriver &BD; 446*0b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 447*0b57cec5SDimitry Andric std::unique_ptr<Module>); 448*0b57cec5SDimitry Andric std::vector<Function *> FunctionsBeingTested; 449*0b57cec5SDimitry Andric 450*0b57cec5SDimitry Andric public: 451*0b57cec5SDimitry Andric ReduceMiscompiledBlocks(BugDriver &bd, 452*0b57cec5SDimitry Andric Expected<bool> (*F)(BugDriver &, 453*0b57cec5SDimitry Andric std::unique_ptr<Module>, 454*0b57cec5SDimitry Andric std::unique_ptr<Module>), 455*0b57cec5SDimitry Andric const std::vector<Function *> &Fns) 456*0b57cec5SDimitry Andric : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} 457*0b57cec5SDimitry Andric 458*0b57cec5SDimitry Andric Expected<TestResult> doTest(std::vector<BasicBlock *> &Prefix, 459*0b57cec5SDimitry Andric std::vector<BasicBlock *> &Suffix) override { 460*0b57cec5SDimitry Andric if (!Suffix.empty()) { 461*0b57cec5SDimitry Andric Expected<bool> Ret = TestFuncs(Suffix); 462*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 463*0b57cec5SDimitry Andric return std::move(E); 464*0b57cec5SDimitry Andric if (*Ret) 465*0b57cec5SDimitry Andric return KeepSuffix; 466*0b57cec5SDimitry Andric } 467*0b57cec5SDimitry Andric if (!Prefix.empty()) { 468*0b57cec5SDimitry Andric Expected<bool> Ret = TestFuncs(Prefix); 469*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 470*0b57cec5SDimitry Andric return std::move(E); 471*0b57cec5SDimitry Andric if (*Ret) 472*0b57cec5SDimitry Andric return KeepPrefix; 473*0b57cec5SDimitry Andric } 474*0b57cec5SDimitry Andric return NoFailure; 475*0b57cec5SDimitry Andric } 476*0b57cec5SDimitry Andric 477*0b57cec5SDimitry Andric Expected<bool> TestFuncs(const std::vector<BasicBlock *> &BBs); 478*0b57cec5SDimitry Andric }; 479*0b57cec5SDimitry Andric } // end anonymous namespace 480*0b57cec5SDimitry Andric 481*0b57cec5SDimitry Andric /// TestFuncs - Extract all blocks for the miscompiled functions except for the 482*0b57cec5SDimitry Andric /// specified blocks. If the problem still exists, return true. 483*0b57cec5SDimitry Andric /// 484*0b57cec5SDimitry Andric Expected<bool> 485*0b57cec5SDimitry Andric ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock *> &BBs) { 486*0b57cec5SDimitry Andric // Test to see if the function is misoptimized if we ONLY run it on the 487*0b57cec5SDimitry Andric // functions listed in Funcs. 488*0b57cec5SDimitry Andric outs() << "Checking to see if the program is misoptimized when all "; 489*0b57cec5SDimitry Andric if (!BBs.empty()) { 490*0b57cec5SDimitry Andric outs() << "but these " << BBs.size() << " blocks are extracted: "; 491*0b57cec5SDimitry Andric for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i) 492*0b57cec5SDimitry Andric outs() << BBs[i]->getName() << " "; 493*0b57cec5SDimitry Andric if (BBs.size() > 10) 494*0b57cec5SDimitry Andric outs() << "..."; 495*0b57cec5SDimitry Andric } else { 496*0b57cec5SDimitry Andric outs() << "blocks are extracted."; 497*0b57cec5SDimitry Andric } 498*0b57cec5SDimitry Andric outs() << '\n'; 499*0b57cec5SDimitry Andric 500*0b57cec5SDimitry Andric // Split the module into the two halves of the program we want. 501*0b57cec5SDimitry Andric ValueToValueMapTy VMap; 502*0b57cec5SDimitry Andric std::unique_ptr<Module> Clone = CloneModule(BD.getProgram(), VMap); 503*0b57cec5SDimitry Andric std::unique_ptr<Module> Orig = BD.swapProgramIn(std::move(Clone)); 504*0b57cec5SDimitry Andric std::vector<Function *> FuncsOnClone; 505*0b57cec5SDimitry Andric std::vector<BasicBlock *> BBsOnClone; 506*0b57cec5SDimitry Andric for (unsigned i = 0, e = FunctionsBeingTested.size(); i != e; ++i) { 507*0b57cec5SDimitry Andric Function *F = cast<Function>(VMap[FunctionsBeingTested[i]]); 508*0b57cec5SDimitry Andric FuncsOnClone.push_back(F); 509*0b57cec5SDimitry Andric } 510*0b57cec5SDimitry Andric for (unsigned i = 0, e = BBs.size(); i != e; ++i) { 511*0b57cec5SDimitry Andric BasicBlock *BB = cast<BasicBlock>(VMap[BBs[i]]); 512*0b57cec5SDimitry Andric BBsOnClone.push_back(BB); 513*0b57cec5SDimitry Andric } 514*0b57cec5SDimitry Andric VMap.clear(); 515*0b57cec5SDimitry Andric 516*0b57cec5SDimitry Andric std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); 517*0b57cec5SDimitry Andric std::unique_ptr<Module> ToOptimize = 518*0b57cec5SDimitry Andric SplitFunctionsOutOfModule(ToNotOptimize.get(), FuncsOnClone, VMap); 519*0b57cec5SDimitry Andric 520*0b57cec5SDimitry Andric // Try the extraction. If it doesn't work, then the block extractor crashed 521*0b57cec5SDimitry Andric // or something, in which case bugpoint can't chase down this possibility. 522*0b57cec5SDimitry Andric if (std::unique_ptr<Module> New = 523*0b57cec5SDimitry Andric BD.extractMappedBlocksFromModule(BBsOnClone, ToOptimize.get())) { 524*0b57cec5SDimitry Andric Expected<bool> Ret = TestFn(BD, std::move(New), std::move(ToNotOptimize)); 525*0b57cec5SDimitry Andric BD.setNewProgram(std::move(Orig)); 526*0b57cec5SDimitry Andric return Ret; 527*0b57cec5SDimitry Andric } 528*0b57cec5SDimitry Andric BD.setNewProgram(std::move(Orig)); 529*0b57cec5SDimitry Andric return false; 530*0b57cec5SDimitry Andric } 531*0b57cec5SDimitry Andric 532*0b57cec5SDimitry Andric /// Given a reduced list of functions that still expose the bug, extract as many 533*0b57cec5SDimitry Andric /// basic blocks from the region as possible without obscuring the bug. 534*0b57cec5SDimitry Andric /// 535*0b57cec5SDimitry Andric static Expected<bool> 536*0b57cec5SDimitry Andric ExtractBlocks(BugDriver &BD, 537*0b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 538*0b57cec5SDimitry Andric std::unique_ptr<Module>), 539*0b57cec5SDimitry Andric std::vector<Function *> &MiscompiledFunctions) { 540*0b57cec5SDimitry Andric if (BugpointIsInterrupted) 541*0b57cec5SDimitry Andric return false; 542*0b57cec5SDimitry Andric 543*0b57cec5SDimitry Andric std::vector<BasicBlock *> Blocks; 544*0b57cec5SDimitry Andric for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 545*0b57cec5SDimitry Andric for (BasicBlock &BB : *MiscompiledFunctions[i]) 546*0b57cec5SDimitry Andric Blocks.push_back(&BB); 547*0b57cec5SDimitry Andric 548*0b57cec5SDimitry Andric // Use the list reducer to identify blocks that can be extracted without 549*0b57cec5SDimitry Andric // obscuring the bug. The Blocks list will end up containing blocks that must 550*0b57cec5SDimitry Andric // be retained from the original program. 551*0b57cec5SDimitry Andric unsigned OldSize = Blocks.size(); 552*0b57cec5SDimitry Andric 553*0b57cec5SDimitry Andric // Check to see if all blocks are extractible first. 554*0b57cec5SDimitry Andric Expected<bool> Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) 555*0b57cec5SDimitry Andric .TestFuncs(std::vector<BasicBlock *>()); 556*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 557*0b57cec5SDimitry Andric return std::move(E); 558*0b57cec5SDimitry Andric if (*Ret) { 559*0b57cec5SDimitry Andric Blocks.clear(); 560*0b57cec5SDimitry Andric } else { 561*0b57cec5SDimitry Andric Expected<bool> Ret = 562*0b57cec5SDimitry Andric ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) 563*0b57cec5SDimitry Andric .reduceList(Blocks); 564*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 565*0b57cec5SDimitry Andric return std::move(E); 566*0b57cec5SDimitry Andric if (Blocks.size() == OldSize) 567*0b57cec5SDimitry Andric return false; 568*0b57cec5SDimitry Andric } 569*0b57cec5SDimitry Andric 570*0b57cec5SDimitry Andric ValueToValueMapTy VMap; 571*0b57cec5SDimitry Andric std::unique_ptr<Module> ProgClone = CloneModule(BD.getProgram(), VMap); 572*0b57cec5SDimitry Andric std::unique_ptr<Module> ToExtract = 573*0b57cec5SDimitry Andric SplitFunctionsOutOfModule(ProgClone.get(), MiscompiledFunctions, VMap); 574*0b57cec5SDimitry Andric std::unique_ptr<Module> Extracted = 575*0b57cec5SDimitry Andric BD.extractMappedBlocksFromModule(Blocks, ToExtract.get()); 576*0b57cec5SDimitry Andric if (!Extracted) { 577*0b57cec5SDimitry Andric // Weird, extraction should have worked. 578*0b57cec5SDimitry Andric errs() << "Nondeterministic problem extracting blocks??\n"; 579*0b57cec5SDimitry Andric return false; 580*0b57cec5SDimitry Andric } 581*0b57cec5SDimitry Andric 582*0b57cec5SDimitry Andric // Otherwise, block extraction succeeded. Link the two program fragments back 583*0b57cec5SDimitry Andric // together. 584*0b57cec5SDimitry Andric 585*0b57cec5SDimitry Andric std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; 586*0b57cec5SDimitry Andric for (Module::iterator I = Extracted->begin(), E = Extracted->end(); I != E; 587*0b57cec5SDimitry Andric ++I) 588*0b57cec5SDimitry Andric if (!I->isDeclaration()) 589*0b57cec5SDimitry Andric MisCompFunctions.emplace_back(I->getName(), I->getFunctionType()); 590*0b57cec5SDimitry Andric 591*0b57cec5SDimitry Andric if (Linker::linkModules(*ProgClone, std::move(Extracted))) 592*0b57cec5SDimitry Andric exit(1); 593*0b57cec5SDimitry Andric 594*0b57cec5SDimitry Andric // Update the list of miscompiled functions. 595*0b57cec5SDimitry Andric MiscompiledFunctions.clear(); 596*0b57cec5SDimitry Andric 597*0b57cec5SDimitry Andric for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 598*0b57cec5SDimitry Andric Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first); 599*0b57cec5SDimitry Andric assert(NewF && "Function not found??"); 600*0b57cec5SDimitry Andric MiscompiledFunctions.push_back(NewF); 601*0b57cec5SDimitry Andric } 602*0b57cec5SDimitry Andric 603*0b57cec5SDimitry Andric // Set the new program and delete the old one. 604*0b57cec5SDimitry Andric BD.setNewProgram(std::move(ProgClone)); 605*0b57cec5SDimitry Andric 606*0b57cec5SDimitry Andric return true; 607*0b57cec5SDimitry Andric } 608*0b57cec5SDimitry Andric 609*0b57cec5SDimitry Andric /// This is a generic driver to narrow down miscompilations, either in an 610*0b57cec5SDimitry Andric /// optimization or a code generator. 611*0b57cec5SDimitry Andric /// 612*0b57cec5SDimitry Andric static Expected<std::vector<Function *>> DebugAMiscompilation( 613*0b57cec5SDimitry Andric BugDriver &BD, 614*0b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 615*0b57cec5SDimitry Andric std::unique_ptr<Module>)) { 616*0b57cec5SDimitry Andric // Okay, now that we have reduced the list of passes which are causing the 617*0b57cec5SDimitry Andric // failure, see if we can pin down which functions are being 618*0b57cec5SDimitry Andric // miscompiled... first build a list of all of the non-external functions in 619*0b57cec5SDimitry Andric // the program. 620*0b57cec5SDimitry Andric std::vector<Function *> MiscompiledFunctions; 621*0b57cec5SDimitry Andric Module &Prog = BD.getProgram(); 622*0b57cec5SDimitry Andric for (Function &F : Prog) 623*0b57cec5SDimitry Andric if (!F.isDeclaration()) 624*0b57cec5SDimitry Andric MiscompiledFunctions.push_back(&F); 625*0b57cec5SDimitry Andric 626*0b57cec5SDimitry Andric // Do the reduction... 627*0b57cec5SDimitry Andric if (!BugpointIsInterrupted) { 628*0b57cec5SDimitry Andric Expected<bool> Ret = ReduceMiscompilingFunctions(BD, TestFn) 629*0b57cec5SDimitry Andric .reduceList(MiscompiledFunctions); 630*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) { 631*0b57cec5SDimitry Andric errs() << "\n***Cannot reduce functions: "; 632*0b57cec5SDimitry Andric return std::move(E); 633*0b57cec5SDimitry Andric } 634*0b57cec5SDimitry Andric } 635*0b57cec5SDimitry Andric outs() << "\n*** The following function" 636*0b57cec5SDimitry Andric << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 637*0b57cec5SDimitry Andric << " being miscompiled: "; 638*0b57cec5SDimitry Andric PrintFunctionList(MiscompiledFunctions); 639*0b57cec5SDimitry Andric outs() << '\n'; 640*0b57cec5SDimitry Andric 641*0b57cec5SDimitry Andric // See if we can rip any loops out of the miscompiled functions and still 642*0b57cec5SDimitry Andric // trigger the problem. 643*0b57cec5SDimitry Andric 644*0b57cec5SDimitry Andric if (!BugpointIsInterrupted && !DisableLoopExtraction) { 645*0b57cec5SDimitry Andric Expected<bool> Ret = ExtractLoops(BD, TestFn, MiscompiledFunctions); 646*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 647*0b57cec5SDimitry Andric return std::move(E); 648*0b57cec5SDimitry Andric if (*Ret) { 649*0b57cec5SDimitry Andric // Okay, we extracted some loops and the problem still appears. See if 650*0b57cec5SDimitry Andric // we can eliminate some of the created functions from being candidates. 651*0b57cec5SDimitry Andric DisambiguateGlobalSymbols(BD.getProgram()); 652*0b57cec5SDimitry Andric 653*0b57cec5SDimitry Andric // Do the reduction... 654*0b57cec5SDimitry Andric if (!BugpointIsInterrupted) 655*0b57cec5SDimitry Andric Ret = ReduceMiscompilingFunctions(BD, TestFn) 656*0b57cec5SDimitry Andric .reduceList(MiscompiledFunctions); 657*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 658*0b57cec5SDimitry Andric return std::move(E); 659*0b57cec5SDimitry Andric 660*0b57cec5SDimitry Andric outs() << "\n*** The following function" 661*0b57cec5SDimitry Andric << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 662*0b57cec5SDimitry Andric << " being miscompiled: "; 663*0b57cec5SDimitry Andric PrintFunctionList(MiscompiledFunctions); 664*0b57cec5SDimitry Andric outs() << '\n'; 665*0b57cec5SDimitry Andric } 666*0b57cec5SDimitry Andric } 667*0b57cec5SDimitry Andric 668*0b57cec5SDimitry Andric if (!BugpointIsInterrupted && !DisableBlockExtraction) { 669*0b57cec5SDimitry Andric Expected<bool> Ret = ExtractBlocks(BD, TestFn, MiscompiledFunctions); 670*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 671*0b57cec5SDimitry Andric return std::move(E); 672*0b57cec5SDimitry Andric if (*Ret) { 673*0b57cec5SDimitry Andric // Okay, we extracted some blocks and the problem still appears. See if 674*0b57cec5SDimitry Andric // we can eliminate some of the created functions from being candidates. 675*0b57cec5SDimitry Andric DisambiguateGlobalSymbols(BD.getProgram()); 676*0b57cec5SDimitry Andric 677*0b57cec5SDimitry Andric // Do the reduction... 678*0b57cec5SDimitry Andric Ret = ReduceMiscompilingFunctions(BD, TestFn) 679*0b57cec5SDimitry Andric .reduceList(MiscompiledFunctions); 680*0b57cec5SDimitry Andric if (Error E = Ret.takeError()) 681*0b57cec5SDimitry Andric return std::move(E); 682*0b57cec5SDimitry Andric 683*0b57cec5SDimitry Andric outs() << "\n*** The following function" 684*0b57cec5SDimitry Andric << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 685*0b57cec5SDimitry Andric << " being miscompiled: "; 686*0b57cec5SDimitry Andric PrintFunctionList(MiscompiledFunctions); 687*0b57cec5SDimitry Andric outs() << '\n'; 688*0b57cec5SDimitry Andric } 689*0b57cec5SDimitry Andric } 690*0b57cec5SDimitry Andric 691*0b57cec5SDimitry Andric return MiscompiledFunctions; 692*0b57cec5SDimitry Andric } 693*0b57cec5SDimitry Andric 694*0b57cec5SDimitry Andric /// This is the predicate function used to check to see if the "Test" portion of 695*0b57cec5SDimitry Andric /// the program is misoptimized. If so, return true. In any case, both module 696*0b57cec5SDimitry Andric /// arguments are deleted. 697*0b57cec5SDimitry Andric /// 698*0b57cec5SDimitry Andric static Expected<bool> TestOptimizer(BugDriver &BD, std::unique_ptr<Module> Test, 699*0b57cec5SDimitry Andric std::unique_ptr<Module> Safe) { 700*0b57cec5SDimitry Andric // Run the optimization passes on ToOptimize, producing a transformed version 701*0b57cec5SDimitry Andric // of the functions being tested. 702*0b57cec5SDimitry Andric outs() << " Optimizing functions being tested: "; 703*0b57cec5SDimitry Andric std::unique_ptr<Module> Optimized = 704*0b57cec5SDimitry Andric BD.runPassesOn(Test.get(), BD.getPassesToRun()); 705*0b57cec5SDimitry Andric if (!Optimized) { 706*0b57cec5SDimitry Andric errs() << " Error running this sequence of passes" 707*0b57cec5SDimitry Andric << " on the input program!\n"; 708*0b57cec5SDimitry Andric BD.EmitProgressBitcode(*Test, "pass-error", false); 709*0b57cec5SDimitry Andric BD.setNewProgram(std::move(Test)); 710*0b57cec5SDimitry Andric if (Error E = BD.debugOptimizerCrash()) 711*0b57cec5SDimitry Andric return std::move(E); 712*0b57cec5SDimitry Andric return false; 713*0b57cec5SDimitry Andric } 714*0b57cec5SDimitry Andric outs() << "done.\n"; 715*0b57cec5SDimitry Andric 716*0b57cec5SDimitry Andric outs() << " Checking to see if the merged program executes correctly: "; 717*0b57cec5SDimitry Andric bool Broken; 718*0b57cec5SDimitry Andric auto Result = testMergedProgram(BD, *Optimized, *Safe, Broken); 719*0b57cec5SDimitry Andric if (Error E = Result.takeError()) 720*0b57cec5SDimitry Andric return std::move(E); 721*0b57cec5SDimitry Andric if (auto New = std::move(*Result)) { 722*0b57cec5SDimitry Andric outs() << (Broken ? " nope.\n" : " yup.\n"); 723*0b57cec5SDimitry Andric // Delete the original and set the new program. 724*0b57cec5SDimitry Andric BD.setNewProgram(std::move(New)); 725*0b57cec5SDimitry Andric } 726*0b57cec5SDimitry Andric return Broken; 727*0b57cec5SDimitry Andric } 728*0b57cec5SDimitry Andric 729*0b57cec5SDimitry Andric /// debugMiscompilation - This method is used when the passes selected are not 730*0b57cec5SDimitry Andric /// crashing, but the generated output is semantically different from the 731*0b57cec5SDimitry Andric /// input. 732*0b57cec5SDimitry Andric /// 733*0b57cec5SDimitry Andric Error BugDriver::debugMiscompilation() { 734*0b57cec5SDimitry Andric // Make sure something was miscompiled... 735*0b57cec5SDimitry Andric if (!BugpointIsInterrupted) { 736*0b57cec5SDimitry Andric Expected<bool> Result = 737*0b57cec5SDimitry Andric ReduceMiscompilingPasses(*this).reduceList(PassesToRun); 738*0b57cec5SDimitry Andric if (Error E = Result.takeError()) 739*0b57cec5SDimitry Andric return E; 740*0b57cec5SDimitry Andric if (!*Result) 741*0b57cec5SDimitry Andric return make_error<StringError>( 742*0b57cec5SDimitry Andric "*** Optimized program matches reference output! No problem" 743*0b57cec5SDimitry Andric " detected...\nbugpoint can't help you with your problem!\n", 744*0b57cec5SDimitry Andric inconvertibleErrorCode()); 745*0b57cec5SDimitry Andric } 746*0b57cec5SDimitry Andric 747*0b57cec5SDimitry Andric outs() << "\n*** Found miscompiling pass" 748*0b57cec5SDimitry Andric << (getPassesToRun().size() == 1 ? "" : "es") << ": " 749*0b57cec5SDimitry Andric << getPassesString(getPassesToRun()) << '\n'; 750*0b57cec5SDimitry Andric EmitProgressBitcode(*Program, "passinput"); 751*0b57cec5SDimitry Andric 752*0b57cec5SDimitry Andric Expected<std::vector<Function *>> MiscompiledFunctions = 753*0b57cec5SDimitry Andric DebugAMiscompilation(*this, TestOptimizer); 754*0b57cec5SDimitry Andric if (Error E = MiscompiledFunctions.takeError()) 755*0b57cec5SDimitry Andric return E; 756*0b57cec5SDimitry Andric 757*0b57cec5SDimitry Andric // Output a bunch of bitcode files for the user... 758*0b57cec5SDimitry Andric outs() << "Outputting reduced bitcode files which expose the problem:\n"; 759*0b57cec5SDimitry Andric ValueToValueMapTy VMap; 760*0b57cec5SDimitry Andric Module *ToNotOptimize = CloneModule(getProgram(), VMap).release(); 761*0b57cec5SDimitry Andric Module *ToOptimize = 762*0b57cec5SDimitry Andric SplitFunctionsOutOfModule(ToNotOptimize, *MiscompiledFunctions, VMap) 763*0b57cec5SDimitry Andric .release(); 764*0b57cec5SDimitry Andric 765*0b57cec5SDimitry Andric outs() << " Non-optimized portion: "; 766*0b57cec5SDimitry Andric EmitProgressBitcode(*ToNotOptimize, "tonotoptimize", true); 767*0b57cec5SDimitry Andric delete ToNotOptimize; // Delete hacked module. 768*0b57cec5SDimitry Andric 769*0b57cec5SDimitry Andric outs() << " Portion that is input to optimizer: "; 770*0b57cec5SDimitry Andric EmitProgressBitcode(*ToOptimize, "tooptimize"); 771*0b57cec5SDimitry Andric delete ToOptimize; // Delete hacked module. 772*0b57cec5SDimitry Andric 773*0b57cec5SDimitry Andric return Error::success(); 774*0b57cec5SDimitry Andric } 775*0b57cec5SDimitry Andric 776*0b57cec5SDimitry Andric /// Get the specified modules ready for code generator testing. 777*0b57cec5SDimitry Andric /// 778*0b57cec5SDimitry Andric static std::unique_ptr<Module> 779*0b57cec5SDimitry Andric CleanupAndPrepareModules(BugDriver &BD, std::unique_ptr<Module> Test, 780*0b57cec5SDimitry Andric Module *Safe) { 781*0b57cec5SDimitry Andric // Clean up the modules, removing extra cruft that we don't need anymore... 782*0b57cec5SDimitry Andric Test = BD.performFinalCleanups(std::move(Test)); 783*0b57cec5SDimitry Andric 784*0b57cec5SDimitry Andric // If we are executing the JIT, we have several nasty issues to take care of. 785*0b57cec5SDimitry Andric if (!BD.isExecutingJIT()) 786*0b57cec5SDimitry Andric return Test; 787*0b57cec5SDimitry Andric 788*0b57cec5SDimitry Andric // First, if the main function is in the Safe module, we must add a stub to 789*0b57cec5SDimitry Andric // the Test module to call into it. Thus, we create a new function `main' 790*0b57cec5SDimitry Andric // which just calls the old one. 791*0b57cec5SDimitry Andric if (Function *oldMain = Safe->getFunction("main")) 792*0b57cec5SDimitry Andric if (!oldMain->isDeclaration()) { 793*0b57cec5SDimitry Andric // Rename it 794*0b57cec5SDimitry Andric oldMain->setName("llvm_bugpoint_old_main"); 795*0b57cec5SDimitry Andric // Create a NEW `main' function with same type in the test module. 796*0b57cec5SDimitry Andric Function *newMain = 797*0b57cec5SDimitry Andric Function::Create(oldMain->getFunctionType(), 798*0b57cec5SDimitry Andric GlobalValue::ExternalLinkage, "main", Test.get()); 799*0b57cec5SDimitry Andric // Create an `oldmain' prototype in the test module, which will 800*0b57cec5SDimitry Andric // corresponds to the real main function in the same module. 801*0b57cec5SDimitry Andric Function *oldMainProto = Function::Create(oldMain->getFunctionType(), 802*0b57cec5SDimitry Andric GlobalValue::ExternalLinkage, 803*0b57cec5SDimitry Andric oldMain->getName(), Test.get()); 804*0b57cec5SDimitry Andric // Set up and remember the argument list for the main function. 805*0b57cec5SDimitry Andric std::vector<Value *> args; 806*0b57cec5SDimitry Andric for (Function::arg_iterator I = newMain->arg_begin(), 807*0b57cec5SDimitry Andric E = newMain->arg_end(), 808*0b57cec5SDimitry Andric OI = oldMain->arg_begin(); 809*0b57cec5SDimitry Andric I != E; ++I, ++OI) { 810*0b57cec5SDimitry Andric I->setName(OI->getName()); // Copy argument names from oldMain 811*0b57cec5SDimitry Andric args.push_back(&*I); 812*0b57cec5SDimitry Andric } 813*0b57cec5SDimitry Andric 814*0b57cec5SDimitry Andric // Call the old main function and return its result 815*0b57cec5SDimitry Andric BasicBlock *BB = BasicBlock::Create(Safe->getContext(), "entry", newMain); 816*0b57cec5SDimitry Andric CallInst *call = CallInst::Create(oldMainProto, args, "", BB); 817*0b57cec5SDimitry Andric 818*0b57cec5SDimitry Andric // If the type of old function wasn't void, return value of call 819*0b57cec5SDimitry Andric ReturnInst::Create(Safe->getContext(), call, BB); 820*0b57cec5SDimitry Andric } 821*0b57cec5SDimitry Andric 822*0b57cec5SDimitry Andric // The second nasty issue we must deal with in the JIT is that the Safe 823*0b57cec5SDimitry Andric // module cannot directly reference any functions defined in the test 824*0b57cec5SDimitry Andric // module. Instead, we use a JIT API call to dynamically resolve the 825*0b57cec5SDimitry Andric // symbol. 826*0b57cec5SDimitry Andric 827*0b57cec5SDimitry Andric // Add the resolver to the Safe module. 828*0b57cec5SDimitry Andric // Prototype: void *getPointerToNamedFunction(const char* Name) 829*0b57cec5SDimitry Andric FunctionCallee resolverFunc = Safe->getOrInsertFunction( 830*0b57cec5SDimitry Andric "getPointerToNamedFunction", Type::getInt8PtrTy(Safe->getContext()), 831*0b57cec5SDimitry Andric Type::getInt8PtrTy(Safe->getContext())); 832*0b57cec5SDimitry Andric 833*0b57cec5SDimitry Andric // Use the function we just added to get addresses of functions we need. 834*0b57cec5SDimitry Andric for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) { 835*0b57cec5SDimitry Andric if (F->isDeclaration() && !F->use_empty() && 836*0b57cec5SDimitry Andric &*F != resolverFunc.getCallee() && 837*0b57cec5SDimitry Andric !F->isIntrinsic() /* ignore intrinsics */) { 838*0b57cec5SDimitry Andric Function *TestFn = Test->getFunction(F->getName()); 839*0b57cec5SDimitry Andric 840*0b57cec5SDimitry Andric // Don't forward functions which are external in the test module too. 841*0b57cec5SDimitry Andric if (TestFn && !TestFn->isDeclaration()) { 842*0b57cec5SDimitry Andric // 1. Add a string constant with its name to the global file 843*0b57cec5SDimitry Andric Constant *InitArray = 844*0b57cec5SDimitry Andric ConstantDataArray::getString(F->getContext(), F->getName()); 845*0b57cec5SDimitry Andric GlobalVariable *funcName = new GlobalVariable( 846*0b57cec5SDimitry Andric *Safe, InitArray->getType(), true /*isConstant*/, 847*0b57cec5SDimitry Andric GlobalValue::InternalLinkage, InitArray, F->getName() + "_name"); 848*0b57cec5SDimitry Andric 849*0b57cec5SDimitry Andric // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an 850*0b57cec5SDimitry Andric // sbyte* so it matches the signature of the resolver function. 851*0b57cec5SDimitry Andric 852*0b57cec5SDimitry Andric // GetElementPtr *funcName, ulong 0, ulong 0 853*0b57cec5SDimitry Andric std::vector<Constant *> GEPargs( 854*0b57cec5SDimitry Andric 2, Constant::getNullValue(Type::getInt32Ty(F->getContext()))); 855*0b57cec5SDimitry Andric Value *GEP = ConstantExpr::getGetElementPtr(InitArray->getType(), 856*0b57cec5SDimitry Andric funcName, GEPargs); 857*0b57cec5SDimitry Andric std::vector<Value *> ResolverArgs; 858*0b57cec5SDimitry Andric ResolverArgs.push_back(GEP); 859*0b57cec5SDimitry Andric 860*0b57cec5SDimitry Andric // Rewrite uses of F in global initializers, etc. to uses of a wrapper 861*0b57cec5SDimitry Andric // function that dynamically resolves the calls to F via our JIT API 862*0b57cec5SDimitry Andric if (!F->use_empty()) { 863*0b57cec5SDimitry Andric // Create a new global to hold the cached function pointer. 864*0b57cec5SDimitry Andric Constant *NullPtr = ConstantPointerNull::get(F->getType()); 865*0b57cec5SDimitry Andric GlobalVariable *Cache = new GlobalVariable( 866*0b57cec5SDimitry Andric *F->getParent(), F->getType(), false, 867*0b57cec5SDimitry Andric GlobalValue::InternalLinkage, NullPtr, F->getName() + ".fpcache"); 868*0b57cec5SDimitry Andric 869*0b57cec5SDimitry Andric // Construct a new stub function that will re-route calls to F 870*0b57cec5SDimitry Andric FunctionType *FuncTy = F->getFunctionType(); 871*0b57cec5SDimitry Andric Function *FuncWrapper = 872*0b57cec5SDimitry Andric Function::Create(FuncTy, GlobalValue::InternalLinkage, 873*0b57cec5SDimitry Andric F->getName() + "_wrapper", F->getParent()); 874*0b57cec5SDimitry Andric BasicBlock *EntryBB = 875*0b57cec5SDimitry Andric BasicBlock::Create(F->getContext(), "entry", FuncWrapper); 876*0b57cec5SDimitry Andric BasicBlock *DoCallBB = 877*0b57cec5SDimitry Andric BasicBlock::Create(F->getContext(), "usecache", FuncWrapper); 878*0b57cec5SDimitry Andric BasicBlock *LookupBB = 879*0b57cec5SDimitry Andric BasicBlock::Create(F->getContext(), "lookupfp", FuncWrapper); 880*0b57cec5SDimitry Andric 881*0b57cec5SDimitry Andric // Check to see if we already looked up the value. 882*0b57cec5SDimitry Andric Value *CachedVal = 883*0b57cec5SDimitry Andric new LoadInst(F->getType(), Cache, "fpcache", EntryBB); 884*0b57cec5SDimitry Andric Value *IsNull = new ICmpInst(*EntryBB, ICmpInst::ICMP_EQ, CachedVal, 885*0b57cec5SDimitry Andric NullPtr, "isNull"); 886*0b57cec5SDimitry Andric BranchInst::Create(LookupBB, DoCallBB, IsNull, EntryBB); 887*0b57cec5SDimitry Andric 888*0b57cec5SDimitry Andric // Resolve the call to function F via the JIT API: 889*0b57cec5SDimitry Andric // 890*0b57cec5SDimitry Andric // call resolver(GetElementPtr...) 891*0b57cec5SDimitry Andric CallInst *Resolver = CallInst::Create(resolverFunc, ResolverArgs, 892*0b57cec5SDimitry Andric "resolver", LookupBB); 893*0b57cec5SDimitry Andric 894*0b57cec5SDimitry Andric // Cast the result from the resolver to correctly-typed function. 895*0b57cec5SDimitry Andric CastInst *CastedResolver = new BitCastInst( 896*0b57cec5SDimitry Andric Resolver, PointerType::getUnqual(F->getFunctionType()), 897*0b57cec5SDimitry Andric "resolverCast", LookupBB); 898*0b57cec5SDimitry Andric 899*0b57cec5SDimitry Andric // Save the value in our cache. 900*0b57cec5SDimitry Andric new StoreInst(CastedResolver, Cache, LookupBB); 901*0b57cec5SDimitry Andric BranchInst::Create(DoCallBB, LookupBB); 902*0b57cec5SDimitry Andric 903*0b57cec5SDimitry Andric PHINode *FuncPtr = 904*0b57cec5SDimitry Andric PHINode::Create(NullPtr->getType(), 2, "fp", DoCallBB); 905*0b57cec5SDimitry Andric FuncPtr->addIncoming(CastedResolver, LookupBB); 906*0b57cec5SDimitry Andric FuncPtr->addIncoming(CachedVal, EntryBB); 907*0b57cec5SDimitry Andric 908*0b57cec5SDimitry Andric // Save the argument list. 909*0b57cec5SDimitry Andric std::vector<Value *> Args; 910*0b57cec5SDimitry Andric for (Argument &A : FuncWrapper->args()) 911*0b57cec5SDimitry Andric Args.push_back(&A); 912*0b57cec5SDimitry Andric 913*0b57cec5SDimitry Andric // Pass on the arguments to the real function, return its result 914*0b57cec5SDimitry Andric if (F->getReturnType()->isVoidTy()) { 915*0b57cec5SDimitry Andric CallInst::Create(FuncTy, FuncPtr, Args, "", DoCallBB); 916*0b57cec5SDimitry Andric ReturnInst::Create(F->getContext(), DoCallBB); 917*0b57cec5SDimitry Andric } else { 918*0b57cec5SDimitry Andric CallInst *Call = 919*0b57cec5SDimitry Andric CallInst::Create(FuncTy, FuncPtr, Args, "retval", DoCallBB); 920*0b57cec5SDimitry Andric ReturnInst::Create(F->getContext(), Call, DoCallBB); 921*0b57cec5SDimitry Andric } 922*0b57cec5SDimitry Andric 923*0b57cec5SDimitry Andric // Use the wrapper function instead of the old function 924*0b57cec5SDimitry Andric F->replaceAllUsesWith(FuncWrapper); 925*0b57cec5SDimitry Andric } 926*0b57cec5SDimitry Andric } 927*0b57cec5SDimitry Andric } 928*0b57cec5SDimitry Andric } 929*0b57cec5SDimitry Andric 930*0b57cec5SDimitry Andric if (verifyModule(*Test) || verifyModule(*Safe)) { 931*0b57cec5SDimitry Andric errs() << "Bugpoint has a bug, which corrupted a module!!\n"; 932*0b57cec5SDimitry Andric abort(); 933*0b57cec5SDimitry Andric } 934*0b57cec5SDimitry Andric 935*0b57cec5SDimitry Andric return Test; 936*0b57cec5SDimitry Andric } 937*0b57cec5SDimitry Andric 938*0b57cec5SDimitry Andric /// This is the predicate function used to check to see if the "Test" portion of 939*0b57cec5SDimitry Andric /// the program is miscompiled by the code generator under test. If so, return 940*0b57cec5SDimitry Andric /// true. In any case, both module arguments are deleted. 941*0b57cec5SDimitry Andric /// 942*0b57cec5SDimitry Andric static Expected<bool> TestCodeGenerator(BugDriver &BD, 943*0b57cec5SDimitry Andric std::unique_ptr<Module> Test, 944*0b57cec5SDimitry Andric std::unique_ptr<Module> Safe) { 945*0b57cec5SDimitry Andric Test = CleanupAndPrepareModules(BD, std::move(Test), Safe.get()); 946*0b57cec5SDimitry Andric 947*0b57cec5SDimitry Andric SmallString<128> TestModuleBC; 948*0b57cec5SDimitry Andric int TestModuleFD; 949*0b57cec5SDimitry Andric std::error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", 950*0b57cec5SDimitry Andric TestModuleFD, TestModuleBC); 951*0b57cec5SDimitry Andric if (EC) { 952*0b57cec5SDimitry Andric errs() << BD.getToolName() 953*0b57cec5SDimitry Andric << "Error making unique filename: " << EC.message() << "\n"; 954*0b57cec5SDimitry Andric exit(1); 955*0b57cec5SDimitry Andric } 956*0b57cec5SDimitry Andric if (BD.writeProgramToFile(TestModuleBC.str(), TestModuleFD, *Test)) { 957*0b57cec5SDimitry Andric errs() << "Error writing bitcode to `" << TestModuleBC.str() 958*0b57cec5SDimitry Andric << "'\nExiting."; 959*0b57cec5SDimitry Andric exit(1); 960*0b57cec5SDimitry Andric } 961*0b57cec5SDimitry Andric 962*0b57cec5SDimitry Andric FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps); 963*0b57cec5SDimitry Andric 964*0b57cec5SDimitry Andric // Make the shared library 965*0b57cec5SDimitry Andric SmallString<128> SafeModuleBC; 966*0b57cec5SDimitry Andric int SafeModuleFD; 967*0b57cec5SDimitry Andric EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, 968*0b57cec5SDimitry Andric SafeModuleBC); 969*0b57cec5SDimitry Andric if (EC) { 970*0b57cec5SDimitry Andric errs() << BD.getToolName() 971*0b57cec5SDimitry Andric << "Error making unique filename: " << EC.message() << "\n"; 972*0b57cec5SDimitry Andric exit(1); 973*0b57cec5SDimitry Andric } 974*0b57cec5SDimitry Andric 975*0b57cec5SDimitry Andric if (BD.writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, *Safe)) { 976*0b57cec5SDimitry Andric errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; 977*0b57cec5SDimitry Andric exit(1); 978*0b57cec5SDimitry Andric } 979*0b57cec5SDimitry Andric 980*0b57cec5SDimitry Andric FileRemover SafeModuleBCRemover(SafeModuleBC.str(), !SaveTemps); 981*0b57cec5SDimitry Andric 982*0b57cec5SDimitry Andric Expected<std::string> SharedObject = 983*0b57cec5SDimitry Andric BD.compileSharedObject(SafeModuleBC.str()); 984*0b57cec5SDimitry Andric if (Error E = SharedObject.takeError()) 985*0b57cec5SDimitry Andric return std::move(E); 986*0b57cec5SDimitry Andric 987*0b57cec5SDimitry Andric FileRemover SharedObjectRemover(*SharedObject, !SaveTemps); 988*0b57cec5SDimitry Andric 989*0b57cec5SDimitry Andric // Run the code generator on the `Test' code, loading the shared library. 990*0b57cec5SDimitry Andric // The function returns whether or not the new output differs from reference. 991*0b57cec5SDimitry Andric Expected<bool> Result = 992*0b57cec5SDimitry Andric BD.diffProgram(BD.getProgram(), TestModuleBC.str(), *SharedObject, false); 993*0b57cec5SDimitry Andric if (Error E = Result.takeError()) 994*0b57cec5SDimitry Andric return std::move(E); 995*0b57cec5SDimitry Andric 996*0b57cec5SDimitry Andric if (*Result) 997*0b57cec5SDimitry Andric errs() << ": still failing!\n"; 998*0b57cec5SDimitry Andric else 999*0b57cec5SDimitry Andric errs() << ": didn't fail.\n"; 1000*0b57cec5SDimitry Andric 1001*0b57cec5SDimitry Andric return Result; 1002*0b57cec5SDimitry Andric } 1003*0b57cec5SDimitry Andric 1004*0b57cec5SDimitry Andric /// debugCodeGenerator - debug errors in LLC, LLI, or CBE. 1005*0b57cec5SDimitry Andric /// 1006*0b57cec5SDimitry Andric Error BugDriver::debugCodeGenerator() { 1007*0b57cec5SDimitry Andric if ((void *)SafeInterpreter == (void *)Interpreter) { 1008*0b57cec5SDimitry Andric Expected<std::string> Result = 1009*0b57cec5SDimitry Andric executeProgramSafely(*Program, "bugpoint.safe.out"); 1010*0b57cec5SDimitry Andric if (Result) { 1011*0b57cec5SDimitry Andric outs() << "\n*** The \"safe\" i.e. 'known good' backend cannot match " 1012*0b57cec5SDimitry Andric << "the reference diff. This may be due to a\n front-end " 1013*0b57cec5SDimitry Andric << "bug or a bug in the original program, but this can also " 1014*0b57cec5SDimitry Andric << "happen if bugpoint isn't running the program with the " 1015*0b57cec5SDimitry Andric << "right flags or input.\n I left the result of executing " 1016*0b57cec5SDimitry Andric << "the program with the \"safe\" backend in this file for " 1017*0b57cec5SDimitry Andric << "you: '" << *Result << "'.\n"; 1018*0b57cec5SDimitry Andric } 1019*0b57cec5SDimitry Andric return Error::success(); 1020*0b57cec5SDimitry Andric } 1021*0b57cec5SDimitry Andric 1022*0b57cec5SDimitry Andric DisambiguateGlobalSymbols(*Program); 1023*0b57cec5SDimitry Andric 1024*0b57cec5SDimitry Andric Expected<std::vector<Function *>> Funcs = 1025*0b57cec5SDimitry Andric DebugAMiscompilation(*this, TestCodeGenerator); 1026*0b57cec5SDimitry Andric if (Error E = Funcs.takeError()) 1027*0b57cec5SDimitry Andric return E; 1028*0b57cec5SDimitry Andric 1029*0b57cec5SDimitry Andric // Split the module into the two halves of the program we want. 1030*0b57cec5SDimitry Andric ValueToValueMapTy VMap; 1031*0b57cec5SDimitry Andric std::unique_ptr<Module> ToNotCodeGen = CloneModule(getProgram(), VMap); 1032*0b57cec5SDimitry Andric std::unique_ptr<Module> ToCodeGen = 1033*0b57cec5SDimitry Andric SplitFunctionsOutOfModule(ToNotCodeGen.get(), *Funcs, VMap); 1034*0b57cec5SDimitry Andric 1035*0b57cec5SDimitry Andric // Condition the modules 1036*0b57cec5SDimitry Andric ToCodeGen = 1037*0b57cec5SDimitry Andric CleanupAndPrepareModules(*this, std::move(ToCodeGen), ToNotCodeGen.get()); 1038*0b57cec5SDimitry Andric 1039*0b57cec5SDimitry Andric SmallString<128> TestModuleBC; 1040*0b57cec5SDimitry Andric int TestModuleFD; 1041*0b57cec5SDimitry Andric std::error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", 1042*0b57cec5SDimitry Andric TestModuleFD, TestModuleBC); 1043*0b57cec5SDimitry Andric if (EC) { 1044*0b57cec5SDimitry Andric errs() << getToolName() << "Error making unique filename: " << EC.message() 1045*0b57cec5SDimitry Andric << "\n"; 1046*0b57cec5SDimitry Andric exit(1); 1047*0b57cec5SDimitry Andric } 1048*0b57cec5SDimitry Andric 1049*0b57cec5SDimitry Andric if (writeProgramToFile(TestModuleBC.str(), TestModuleFD, *ToCodeGen)) { 1050*0b57cec5SDimitry Andric errs() << "Error writing bitcode to `" << TestModuleBC << "'\nExiting."; 1051*0b57cec5SDimitry Andric exit(1); 1052*0b57cec5SDimitry Andric } 1053*0b57cec5SDimitry Andric 1054*0b57cec5SDimitry Andric // Make the shared library 1055*0b57cec5SDimitry Andric SmallString<128> SafeModuleBC; 1056*0b57cec5SDimitry Andric int SafeModuleFD; 1057*0b57cec5SDimitry Andric EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, 1058*0b57cec5SDimitry Andric SafeModuleBC); 1059*0b57cec5SDimitry Andric if (EC) { 1060*0b57cec5SDimitry Andric errs() << getToolName() << "Error making unique filename: " << EC.message() 1061*0b57cec5SDimitry Andric << "\n"; 1062*0b57cec5SDimitry Andric exit(1); 1063*0b57cec5SDimitry Andric } 1064*0b57cec5SDimitry Andric 1065*0b57cec5SDimitry Andric if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, *ToNotCodeGen)) { 1066*0b57cec5SDimitry Andric errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; 1067*0b57cec5SDimitry Andric exit(1); 1068*0b57cec5SDimitry Andric } 1069*0b57cec5SDimitry Andric Expected<std::string> SharedObject = compileSharedObject(SafeModuleBC.str()); 1070*0b57cec5SDimitry Andric if (Error E = SharedObject.takeError()) 1071*0b57cec5SDimitry Andric return E; 1072*0b57cec5SDimitry Andric 1073*0b57cec5SDimitry Andric outs() << "You can reproduce the problem with the command line: \n"; 1074*0b57cec5SDimitry Andric if (isExecutingJIT()) { 1075*0b57cec5SDimitry Andric outs() << " lli -load " << *SharedObject << " " << TestModuleBC; 1076*0b57cec5SDimitry Andric } else { 1077*0b57cec5SDimitry Andric outs() << " llc " << TestModuleBC << " -o " << TestModuleBC << ".s\n"; 1078*0b57cec5SDimitry Andric outs() << " cc " << *SharedObject << " " << TestModuleBC.str() << ".s -o " 1079*0b57cec5SDimitry Andric << TestModuleBC << ".exe\n"; 1080*0b57cec5SDimitry Andric outs() << " ./" << TestModuleBC << ".exe"; 1081*0b57cec5SDimitry Andric } 1082*0b57cec5SDimitry Andric for (unsigned i = 0, e = InputArgv.size(); i != e; ++i) 1083*0b57cec5SDimitry Andric outs() << " " << InputArgv[i]; 1084*0b57cec5SDimitry Andric outs() << '\n'; 1085*0b57cec5SDimitry Andric outs() << "The shared object was created with:\n llc -march=c " 1086*0b57cec5SDimitry Andric << SafeModuleBC.str() << " -o temporary.c\n" 1087*0b57cec5SDimitry Andric << " cc -xc temporary.c -O2 -o " << *SharedObject; 1088*0b57cec5SDimitry Andric if (TargetTriple.getArch() == Triple::sparc) 1089*0b57cec5SDimitry Andric outs() << " -G"; // Compile a shared library, `-G' for Sparc 1090*0b57cec5SDimitry Andric else 1091*0b57cec5SDimitry Andric outs() << " -fPIC -shared"; // `-shared' for Linux/X86, maybe others 1092*0b57cec5SDimitry Andric 1093*0b57cec5SDimitry Andric outs() << " -fno-strict-aliasing\n"; 1094*0b57cec5SDimitry Andric 1095*0b57cec5SDimitry Andric return Error::success(); 1096*0b57cec5SDimitry Andric } 1097