10b57cec5SDimitry Andric //===- Miscompilation.cpp - Debug program miscompilations -----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements optimizer and code generation miscompilation debugging 100b57cec5SDimitry Andric // support. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "BugDriver.h" 150b57cec5SDimitry Andric #include "ListReducer.h" 160b57cec5SDimitry Andric #include "ToolRunner.h" 170b57cec5SDimitry Andric #include "llvm/Config/config.h" // for HAVE_LINK_R 180b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 190b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 200b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 210b57cec5SDimitry Andric #include "llvm/IR/Module.h" 220b57cec5SDimitry Andric #include "llvm/IR/Verifier.h" 230b57cec5SDimitry Andric #include "llvm/Linker/Linker.h" 240b57cec5SDimitry Andric #include "llvm/Pass.h" 250b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 260b57cec5SDimitry Andric #include "llvm/Support/FileUtilities.h" 270b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric using namespace llvm; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric namespace llvm { 320b57cec5SDimitry Andric extern cl::opt<std::string> OutputPrefix; 330b57cec5SDimitry Andric extern cl::list<std::string> InputArgv; 340b57cec5SDimitry Andric } // end namespace llvm 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric namespace { 370b57cec5SDimitry Andric static llvm::cl::opt<bool> DisableLoopExtraction( 380b57cec5SDimitry Andric "disable-loop-extraction", 390b57cec5SDimitry Andric cl::desc("Don't extract loops when searching for miscompilations"), 400b57cec5SDimitry Andric cl::init(false)); 410b57cec5SDimitry Andric static llvm::cl::opt<bool> DisableBlockExtraction( 420b57cec5SDimitry Andric "disable-block-extraction", 430b57cec5SDimitry Andric cl::desc("Don't extract blocks when searching for miscompilations"), 440b57cec5SDimitry Andric cl::init(false)); 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric class ReduceMiscompilingPasses : public ListReducer<std::string> { 470b57cec5SDimitry Andric BugDriver &BD; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric public: 500b57cec5SDimitry Andric ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {} 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric Expected<TestResult> doTest(std::vector<std::string> &Prefix, 530b57cec5SDimitry Andric std::vector<std::string> &Suffix) override; 540b57cec5SDimitry Andric }; 550b57cec5SDimitry Andric } // end anonymous namespace 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric /// TestResult - After passes have been split into a test group and a control 580b57cec5SDimitry Andric /// group, see if they still break the program. 590b57cec5SDimitry Andric /// 600b57cec5SDimitry Andric Expected<ReduceMiscompilingPasses::TestResult> 610b57cec5SDimitry Andric ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, 620b57cec5SDimitry Andric std::vector<std::string> &Suffix) { 630b57cec5SDimitry Andric // First, run the program with just the Suffix passes. If it is still broken 640b57cec5SDimitry Andric // with JUST the kept passes, discard the prefix passes. 650b57cec5SDimitry Andric outs() << "Checking to see if '" << getPassesString(Suffix) 660b57cec5SDimitry Andric << "' compiles correctly: "; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric std::string BitcodeResult; 690b57cec5SDimitry Andric if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false /*delete*/, 700b57cec5SDimitry Andric true /*quiet*/)) { 710b57cec5SDimitry Andric errs() << " Error running this sequence of passes" 720b57cec5SDimitry Andric << " on the input program!\n"; 730b57cec5SDimitry Andric BD.setPassesToRun(Suffix); 740b57cec5SDimitry Andric BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 750b57cec5SDimitry Andric // TODO: This should propagate the error instead of exiting. 760b57cec5SDimitry Andric if (Error E = BD.debugOptimizerCrash()) 770b57cec5SDimitry Andric exit(1); 780b57cec5SDimitry Andric exit(0); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric // Check to see if the finished program matches the reference output... 820b57cec5SDimitry Andric Expected<bool> Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", 830b57cec5SDimitry Andric true /*delete bitcode*/); 840b57cec5SDimitry Andric if (Error E = Diff.takeError()) 850b57cec5SDimitry Andric return std::move(E); 860b57cec5SDimitry Andric if (*Diff) { 870b57cec5SDimitry Andric outs() << " nope.\n"; 880b57cec5SDimitry Andric if (Suffix.empty()) { 890b57cec5SDimitry Andric errs() << BD.getToolName() << ": I'm confused: the test fails when " 900b57cec5SDimitry Andric << "no passes are run, nondeterministic program?\n"; 910b57cec5SDimitry Andric exit(1); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric return KeepSuffix; // Miscompilation detected! 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric outs() << " yup.\n"; // No miscompilation! 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric if (Prefix.empty()) 980b57cec5SDimitry Andric return NoFailure; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // Next, see if the program is broken if we run the "prefix" passes first, 1010b57cec5SDimitry Andric // then separately run the "kept" passes. 1020b57cec5SDimitry Andric outs() << "Checking to see if '" << getPassesString(Prefix) 1030b57cec5SDimitry Andric << "' compiles correctly: "; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric // If it is not broken with the kept passes, it's possible that the prefix 1060b57cec5SDimitry Andric // passes must be run before the kept passes to break it. If the program 1070b57cec5SDimitry Andric // WORKS after the prefix passes, but then fails if running the prefix AND 1080b57cec5SDimitry Andric // kept passes, we can update our bitcode file to include the result of the 1090b57cec5SDimitry Andric // prefix passes, then discard the prefix passes. 1100b57cec5SDimitry Andric // 1110b57cec5SDimitry Andric if (BD.runPasses(BD.getProgram(), Prefix, BitcodeResult, false /*delete*/, 1120b57cec5SDimitry Andric true /*quiet*/)) { 1130b57cec5SDimitry Andric errs() << " Error running this sequence of passes" 1140b57cec5SDimitry Andric << " on the input program!\n"; 1150b57cec5SDimitry Andric BD.setPassesToRun(Prefix); 1160b57cec5SDimitry Andric BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 1170b57cec5SDimitry Andric // TODO: This should propagate the error instead of exiting. 1180b57cec5SDimitry Andric if (Error E = BD.debugOptimizerCrash()) 1190b57cec5SDimitry Andric exit(1); 1200b57cec5SDimitry Andric exit(0); 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric // If the prefix maintains the predicate by itself, only keep the prefix! 1240b57cec5SDimitry Andric Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", false); 1250b57cec5SDimitry Andric if (Error E = Diff.takeError()) 1260b57cec5SDimitry Andric return std::move(E); 1270b57cec5SDimitry Andric if (*Diff) { 1280b57cec5SDimitry Andric outs() << " nope.\n"; 1290b57cec5SDimitry Andric sys::fs::remove(BitcodeResult); 1300b57cec5SDimitry Andric return KeepPrefix; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric outs() << " yup.\n"; // No miscompilation! 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric // Ok, so now we know that the prefix passes work, try running the suffix 1350b57cec5SDimitry Andric // passes on the result of the prefix passes. 1360b57cec5SDimitry Andric // 1370b57cec5SDimitry Andric std::unique_ptr<Module> PrefixOutput = 1380b57cec5SDimitry Andric parseInputFile(BitcodeResult, BD.getContext()); 1390b57cec5SDimitry Andric if (!PrefixOutput) { 1400b57cec5SDimitry Andric errs() << BD.getToolName() << ": Error reading bitcode file '" 1410b57cec5SDimitry Andric << BitcodeResult << "'!\n"; 1420b57cec5SDimitry Andric exit(1); 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric sys::fs::remove(BitcodeResult); 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric // Don't check if there are no passes in the suffix. 1470b57cec5SDimitry Andric if (Suffix.empty()) 1480b57cec5SDimitry Andric return NoFailure; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric outs() << "Checking to see if '" << getPassesString(Suffix) 1510b57cec5SDimitry Andric << "' passes compile correctly after the '" << getPassesString(Prefix) 1520b57cec5SDimitry Andric << "' passes: "; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric std::unique_ptr<Module> OriginalInput = 1550b57cec5SDimitry Andric BD.swapProgramIn(std::move(PrefixOutput)); 1560b57cec5SDimitry Andric if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false /*delete*/, 1570b57cec5SDimitry Andric true /*quiet*/)) { 1580b57cec5SDimitry Andric errs() << " Error running this sequence of passes" 1590b57cec5SDimitry Andric << " on the input program!\n"; 1600b57cec5SDimitry Andric BD.setPassesToRun(Suffix); 1610b57cec5SDimitry Andric BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); 1620b57cec5SDimitry Andric // TODO: This should propagate the error instead of exiting. 1630b57cec5SDimitry Andric if (Error E = BD.debugOptimizerCrash()) 1640b57cec5SDimitry Andric exit(1); 1650b57cec5SDimitry Andric exit(0); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // Run the result... 1690b57cec5SDimitry Andric Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", 1700b57cec5SDimitry Andric true /*delete bitcode*/); 1710b57cec5SDimitry Andric if (Error E = Diff.takeError()) 1720b57cec5SDimitry Andric return std::move(E); 1730b57cec5SDimitry Andric if (*Diff) { 1740b57cec5SDimitry Andric outs() << " nope.\n"; 1750b57cec5SDimitry Andric return KeepSuffix; 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric // Otherwise, we must not be running the bad pass anymore. 1790b57cec5SDimitry Andric outs() << " yup.\n"; // No miscompilation! 1800b57cec5SDimitry Andric // Restore orig program & free test. 1810b57cec5SDimitry Andric BD.setNewProgram(std::move(OriginalInput)); 1820b57cec5SDimitry Andric return NoFailure; 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric namespace { 1860b57cec5SDimitry Andric class ReduceMiscompilingFunctions : public ListReducer<Function *> { 1870b57cec5SDimitry Andric BugDriver &BD; 1880b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 1890b57cec5SDimitry Andric std::unique_ptr<Module>); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric public: 1920b57cec5SDimitry Andric ReduceMiscompilingFunctions(BugDriver &bd, 1930b57cec5SDimitry Andric Expected<bool> (*F)(BugDriver &, 1940b57cec5SDimitry Andric std::unique_ptr<Module>, 1950b57cec5SDimitry Andric std::unique_ptr<Module>)) 1960b57cec5SDimitry Andric : BD(bd), TestFn(F) {} 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric Expected<TestResult> doTest(std::vector<Function *> &Prefix, 1990b57cec5SDimitry Andric std::vector<Function *> &Suffix) override { 2000b57cec5SDimitry Andric if (!Suffix.empty()) { 2010b57cec5SDimitry Andric Expected<bool> Ret = TestFuncs(Suffix); 2020b57cec5SDimitry Andric if (Error E = Ret.takeError()) 2030b57cec5SDimitry Andric return std::move(E); 2040b57cec5SDimitry Andric if (*Ret) 2050b57cec5SDimitry Andric return KeepSuffix; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric if (!Prefix.empty()) { 2080b57cec5SDimitry Andric Expected<bool> Ret = TestFuncs(Prefix); 2090b57cec5SDimitry Andric if (Error E = Ret.takeError()) 2100b57cec5SDimitry Andric return std::move(E); 2110b57cec5SDimitry Andric if (*Ret) 2120b57cec5SDimitry Andric return KeepPrefix; 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric return NoFailure; 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric Expected<bool> TestFuncs(const std::vector<Function *> &Prefix); 2180b57cec5SDimitry Andric }; 2190b57cec5SDimitry Andric } // end anonymous namespace 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric /// Given two modules, link them together and run the program, checking to see 2220b57cec5SDimitry Andric /// if the program matches the diff. If there is an error, return NULL. If not, 2230b57cec5SDimitry Andric /// return the merged module. The Broken argument will be set to true if the 2240b57cec5SDimitry Andric /// output is different. If the DeleteInputs argument is set to true then this 2250b57cec5SDimitry Andric /// function deletes both input modules before it returns. 2260b57cec5SDimitry Andric /// 2270b57cec5SDimitry Andric static Expected<std::unique_ptr<Module>> testMergedProgram(const BugDriver &BD, 2280b57cec5SDimitry Andric const Module &M1, 2290b57cec5SDimitry Andric const Module &M2, 2300b57cec5SDimitry Andric bool &Broken) { 2310b57cec5SDimitry Andric // Resulting merge of M1 and M2. 2320b57cec5SDimitry Andric auto Merged = CloneModule(M1); 2330b57cec5SDimitry Andric if (Linker::linkModules(*Merged, CloneModule(M2))) 2340b57cec5SDimitry Andric // TODO: Shouldn't we thread the error up instead of exiting? 2350b57cec5SDimitry Andric exit(1); 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric // Execute the program. 2380b57cec5SDimitry Andric Expected<bool> Diff = BD.diffProgram(*Merged, "", "", false); 2390b57cec5SDimitry Andric if (Error E = Diff.takeError()) 2400b57cec5SDimitry Andric return std::move(E); 2410b57cec5SDimitry Andric Broken = *Diff; 2420b57cec5SDimitry Andric return std::move(Merged); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric /// split functions in a Module into two groups: those that are under 2460b57cec5SDimitry Andric /// consideration for miscompilation vs. those that are not, and test 2470b57cec5SDimitry Andric /// accordingly. Each group of functions becomes a separate Module. 2480b57cec5SDimitry Andric Expected<bool> 2490b57cec5SDimitry Andric ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function *> &Funcs) { 2500b57cec5SDimitry Andric // Test to see if the function is misoptimized if we ONLY run it on the 2510b57cec5SDimitry Andric // functions listed in Funcs. 2520b57cec5SDimitry Andric outs() << "Checking to see if the program is misoptimized when " 2530b57cec5SDimitry Andric << (Funcs.size() == 1 ? "this function is" : "these functions are") 2540b57cec5SDimitry Andric << " run through the pass" 2550b57cec5SDimitry Andric << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":"; 2560b57cec5SDimitry Andric PrintFunctionList(Funcs); 2570b57cec5SDimitry Andric outs() << '\n'; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric // Create a clone for two reasons: 2600b57cec5SDimitry Andric // * If the optimization passes delete any function, the deleted function 2610b57cec5SDimitry Andric // will be in the clone and Funcs will still point to valid memory 2620b57cec5SDimitry Andric // * If the optimization passes use interprocedural information to break 2630b57cec5SDimitry Andric // a function, we want to continue with the original function. Otherwise 2640b57cec5SDimitry Andric // we can conclude that a function triggers the bug when in fact one 2650b57cec5SDimitry Andric // needs a larger set of original functions to do so. 2660b57cec5SDimitry Andric ValueToValueMapTy VMap; 2670b57cec5SDimitry Andric std::unique_ptr<Module> Clone = CloneModule(BD.getProgram(), VMap); 2680b57cec5SDimitry Andric std::unique_ptr<Module> Orig = BD.swapProgramIn(std::move(Clone)); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric std::vector<Function *> FuncsOnClone; 2710b57cec5SDimitry Andric for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { 2720b57cec5SDimitry Andric Function *F = cast<Function>(VMap[Funcs[i]]); 2730b57cec5SDimitry Andric FuncsOnClone.push_back(F); 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric // Split the module into the two halves of the program we want. 2770b57cec5SDimitry Andric VMap.clear(); 2780b57cec5SDimitry Andric std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); 2790b57cec5SDimitry Andric std::unique_ptr<Module> ToOptimize = 2800b57cec5SDimitry Andric SplitFunctionsOutOfModule(ToNotOptimize.get(), FuncsOnClone, VMap); 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric Expected<bool> Broken = 2830b57cec5SDimitry Andric TestFn(BD, std::move(ToOptimize), std::move(ToNotOptimize)); 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric BD.setNewProgram(std::move(Orig)); 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric return Broken; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric /// Give anonymous global values names. 2910b57cec5SDimitry Andric static void DisambiguateGlobalSymbols(Module &M) { 2920b57cec5SDimitry Andric for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; 2930b57cec5SDimitry Andric ++I) 2940b57cec5SDimitry Andric if (!I->hasName()) 2950b57cec5SDimitry Andric I->setName("anon_global"); 2960b57cec5SDimitry Andric for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 2970b57cec5SDimitry Andric if (!I->hasName()) 2980b57cec5SDimitry Andric I->setName("anon_fn"); 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric /// Given a reduced list of functions that still exposed the bug, check to see 3020b57cec5SDimitry Andric /// if we can extract the loops in the region without obscuring the bug. If so, 3030b57cec5SDimitry Andric /// it reduces the amount of code identified. 3040b57cec5SDimitry Andric /// 3050b57cec5SDimitry Andric static Expected<bool> 3060b57cec5SDimitry Andric ExtractLoops(BugDriver &BD, 3070b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 3080b57cec5SDimitry Andric std::unique_ptr<Module>), 3090b57cec5SDimitry Andric std::vector<Function *> &MiscompiledFunctions) { 3100b57cec5SDimitry Andric bool MadeChange = false; 31104eeddc0SDimitry Andric while (true) { 3120b57cec5SDimitry Andric if (BugpointIsInterrupted) 3130b57cec5SDimitry Andric return MadeChange; 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric ValueToValueMapTy VMap; 3160b57cec5SDimitry Andric std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); 3170b57cec5SDimitry Andric std::unique_ptr<Module> ToOptimize = SplitFunctionsOutOfModule( 3180b57cec5SDimitry Andric ToNotOptimize.get(), MiscompiledFunctions, VMap); 3190b57cec5SDimitry Andric std::unique_ptr<Module> ToOptimizeLoopExtracted = 3200b57cec5SDimitry Andric BD.extractLoop(ToOptimize.get()); 3210b57cec5SDimitry Andric if (!ToOptimizeLoopExtracted) 3220b57cec5SDimitry Andric // If the loop extractor crashed or if there were no extractible loops, 3230b57cec5SDimitry Andric // then this chapter of our odyssey is over with. 3240b57cec5SDimitry Andric return MadeChange; 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric errs() << "Extracted a loop from the breaking portion of the program.\n"; 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric // Bugpoint is intentionally not very trusting of LLVM transformations. In 3290b57cec5SDimitry Andric // particular, we're not going to assume that the loop extractor works, so 3300b57cec5SDimitry Andric // we're going to test the newly loop extracted program to make sure nothing 3310b57cec5SDimitry Andric // has broken. If something broke, then we'll inform the user and stop 3320b57cec5SDimitry Andric // extraction. 3330b57cec5SDimitry Andric AbstractInterpreter *AI = BD.switchToSafeInterpreter(); 3340b57cec5SDimitry Andric bool Failure; 3350b57cec5SDimitry Andric Expected<std::unique_ptr<Module>> New = testMergedProgram( 3360b57cec5SDimitry Andric BD, *ToOptimizeLoopExtracted, *ToNotOptimize, Failure); 3370b57cec5SDimitry Andric if (Error E = New.takeError()) 3380b57cec5SDimitry Andric return std::move(E); 3390b57cec5SDimitry Andric if (!*New) 3400b57cec5SDimitry Andric return false; 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric // Delete the original and set the new program. 3430b57cec5SDimitry Andric std::unique_ptr<Module> Old = BD.swapProgramIn(std::move(*New)); 3440b57cec5SDimitry Andric for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 3450b57cec5SDimitry Andric MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]); 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric if (Failure) { 3480b57cec5SDimitry Andric BD.switchToInterpreter(AI); 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric // Merged program doesn't work anymore! 3510b57cec5SDimitry Andric errs() << " *** ERROR: Loop extraction broke the program. :(" 3520b57cec5SDimitry Andric << " Please report a bug!\n"; 3530b57cec5SDimitry Andric errs() << " Continuing on with un-loop-extracted version.\n"; 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-tno.bc", 3560b57cec5SDimitry Andric *ToNotOptimize); 3570b57cec5SDimitry Andric BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to.bc", 3580b57cec5SDimitry Andric *ToOptimize); 3590b57cec5SDimitry Andric BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc", 3600b57cec5SDimitry Andric *ToOptimizeLoopExtracted); 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric errs() << "Please submit the " << OutputPrefix 3630b57cec5SDimitry Andric << "-loop-extract-fail-*.bc files.\n"; 3640b57cec5SDimitry Andric return MadeChange; 3650b57cec5SDimitry Andric } 3660b57cec5SDimitry Andric BD.switchToInterpreter(AI); 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric outs() << " Testing after loop extraction:\n"; 3690b57cec5SDimitry Andric // Clone modules, the tester function will free them. 3700b57cec5SDimitry Andric std::unique_ptr<Module> TOLEBackup = 3710b57cec5SDimitry Andric CloneModule(*ToOptimizeLoopExtracted, VMap); 3720b57cec5SDimitry Andric std::unique_ptr<Module> TNOBackup = CloneModule(*ToNotOptimize, VMap); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 3750b57cec5SDimitry Andric MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]); 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric Expected<bool> Result = TestFn(BD, std::move(ToOptimizeLoopExtracted), 3780b57cec5SDimitry Andric std::move(ToNotOptimize)); 3790b57cec5SDimitry Andric if (Error E = Result.takeError()) 3800b57cec5SDimitry Andric return std::move(E); 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric ToOptimizeLoopExtracted = std::move(TOLEBackup); 3830b57cec5SDimitry Andric ToNotOptimize = std::move(TNOBackup); 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric if (!*Result) { 3860b57cec5SDimitry Andric outs() << "*** Loop extraction masked the problem. Undoing.\n"; 3870b57cec5SDimitry Andric // If the program is not still broken, then loop extraction did something 3880b57cec5SDimitry Andric // that masked the error. Stop loop extraction now. 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; 3910b57cec5SDimitry Andric for (Function *F : MiscompiledFunctions) { 3925ffd83dbSDimitry Andric MisCompFunctions.emplace_back(std::string(F->getName()), 3935ffd83dbSDimitry Andric F->getFunctionType()); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric if (Linker::linkModules(*ToNotOptimize, 3970b57cec5SDimitry Andric std::move(ToOptimizeLoopExtracted))) 3980b57cec5SDimitry Andric exit(1); 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric MiscompiledFunctions.clear(); 4010b57cec5SDimitry Andric for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 4020b57cec5SDimitry Andric Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric assert(NewF && "Function not found??"); 4050b57cec5SDimitry Andric MiscompiledFunctions.push_back(NewF); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric BD.setNewProgram(std::move(ToNotOptimize)); 4090b57cec5SDimitry Andric return MadeChange; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric outs() << "*** Loop extraction successful!\n"; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; 4150b57cec5SDimitry Andric for (Module::iterator I = ToOptimizeLoopExtracted->begin(), 4160b57cec5SDimitry Andric E = ToOptimizeLoopExtracted->end(); 4170b57cec5SDimitry Andric I != E; ++I) 4180b57cec5SDimitry Andric if (!I->isDeclaration()) 4195ffd83dbSDimitry Andric MisCompFunctions.emplace_back(std::string(I->getName()), 4205ffd83dbSDimitry Andric I->getFunctionType()); 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric // Okay, great! Now we know that we extracted a loop and that loop 4230b57cec5SDimitry Andric // extraction both didn't break the program, and didn't mask the problem. 4240b57cec5SDimitry Andric // Replace the current program with the loop extracted version, and try to 4250b57cec5SDimitry Andric // extract another loop. 4260b57cec5SDimitry Andric if (Linker::linkModules(*ToNotOptimize, std::move(ToOptimizeLoopExtracted))) 4270b57cec5SDimitry Andric exit(1); 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric // All of the Function*'s in the MiscompiledFunctions list are in the old 4300b57cec5SDimitry Andric // module. Update this list to include all of the functions in the 4310b57cec5SDimitry Andric // optimized and loop extracted module. 4320b57cec5SDimitry Andric MiscompiledFunctions.clear(); 4330b57cec5SDimitry Andric for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 4340b57cec5SDimitry Andric Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric assert(NewF && "Function not found??"); 4370b57cec5SDimitry Andric MiscompiledFunctions.push_back(NewF); 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric BD.setNewProgram(std::move(ToNotOptimize)); 4410b57cec5SDimitry Andric MadeChange = true; 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric namespace { 4460b57cec5SDimitry Andric class ReduceMiscompiledBlocks : public ListReducer<BasicBlock *> { 4470b57cec5SDimitry Andric BugDriver &BD; 4480b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 4490b57cec5SDimitry Andric std::unique_ptr<Module>); 4500b57cec5SDimitry Andric std::vector<Function *> FunctionsBeingTested; 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric public: 4530b57cec5SDimitry Andric ReduceMiscompiledBlocks(BugDriver &bd, 4540b57cec5SDimitry Andric Expected<bool> (*F)(BugDriver &, 4550b57cec5SDimitry Andric std::unique_ptr<Module>, 4560b57cec5SDimitry Andric std::unique_ptr<Module>), 4570b57cec5SDimitry Andric const std::vector<Function *> &Fns) 4580b57cec5SDimitry Andric : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric Expected<TestResult> doTest(std::vector<BasicBlock *> &Prefix, 4610b57cec5SDimitry Andric std::vector<BasicBlock *> &Suffix) override { 4620b57cec5SDimitry Andric if (!Suffix.empty()) { 4630b57cec5SDimitry Andric Expected<bool> Ret = TestFuncs(Suffix); 4640b57cec5SDimitry Andric if (Error E = Ret.takeError()) 4650b57cec5SDimitry Andric return std::move(E); 4660b57cec5SDimitry Andric if (*Ret) 4670b57cec5SDimitry Andric return KeepSuffix; 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric if (!Prefix.empty()) { 4700b57cec5SDimitry Andric Expected<bool> Ret = TestFuncs(Prefix); 4710b57cec5SDimitry Andric if (Error E = Ret.takeError()) 4720b57cec5SDimitry Andric return std::move(E); 4730b57cec5SDimitry Andric if (*Ret) 4740b57cec5SDimitry Andric return KeepPrefix; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric return NoFailure; 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric Expected<bool> TestFuncs(const std::vector<BasicBlock *> &BBs); 4800b57cec5SDimitry Andric }; 4810b57cec5SDimitry Andric } // end anonymous namespace 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric /// TestFuncs - Extract all blocks for the miscompiled functions except for the 4840b57cec5SDimitry Andric /// specified blocks. If the problem still exists, return true. 4850b57cec5SDimitry Andric /// 4860b57cec5SDimitry Andric Expected<bool> 4870b57cec5SDimitry Andric ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock *> &BBs) { 4880b57cec5SDimitry Andric // Test to see if the function is misoptimized if we ONLY run it on the 4890b57cec5SDimitry Andric // functions listed in Funcs. 4900b57cec5SDimitry Andric outs() << "Checking to see if the program is misoptimized when all "; 4910b57cec5SDimitry Andric if (!BBs.empty()) { 4920b57cec5SDimitry Andric outs() << "but these " << BBs.size() << " blocks are extracted: "; 4930b57cec5SDimitry Andric for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i) 4940b57cec5SDimitry Andric outs() << BBs[i]->getName() << " "; 4950b57cec5SDimitry Andric if (BBs.size() > 10) 4960b57cec5SDimitry Andric outs() << "..."; 4970b57cec5SDimitry Andric } else { 4980b57cec5SDimitry Andric outs() << "blocks are extracted."; 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric outs() << '\n'; 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric // Split the module into the two halves of the program we want. 5030b57cec5SDimitry Andric ValueToValueMapTy VMap; 5040b57cec5SDimitry Andric std::unique_ptr<Module> Clone = CloneModule(BD.getProgram(), VMap); 5050b57cec5SDimitry Andric std::unique_ptr<Module> Orig = BD.swapProgramIn(std::move(Clone)); 5060b57cec5SDimitry Andric std::vector<Function *> FuncsOnClone; 5070b57cec5SDimitry Andric std::vector<BasicBlock *> BBsOnClone; 5080b57cec5SDimitry Andric for (unsigned i = 0, e = FunctionsBeingTested.size(); i != e; ++i) { 5090b57cec5SDimitry Andric Function *F = cast<Function>(VMap[FunctionsBeingTested[i]]); 5100b57cec5SDimitry Andric FuncsOnClone.push_back(F); 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric for (unsigned i = 0, e = BBs.size(); i != e; ++i) { 5130b57cec5SDimitry Andric BasicBlock *BB = cast<BasicBlock>(VMap[BBs[i]]); 5140b57cec5SDimitry Andric BBsOnClone.push_back(BB); 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric VMap.clear(); 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); 5190b57cec5SDimitry Andric std::unique_ptr<Module> ToOptimize = 5200b57cec5SDimitry Andric SplitFunctionsOutOfModule(ToNotOptimize.get(), FuncsOnClone, VMap); 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric // Try the extraction. If it doesn't work, then the block extractor crashed 5230b57cec5SDimitry Andric // or something, in which case bugpoint can't chase down this possibility. 5240b57cec5SDimitry Andric if (std::unique_ptr<Module> New = 5250b57cec5SDimitry Andric BD.extractMappedBlocksFromModule(BBsOnClone, ToOptimize.get())) { 5260b57cec5SDimitry Andric Expected<bool> Ret = TestFn(BD, std::move(New), std::move(ToNotOptimize)); 5270b57cec5SDimitry Andric BD.setNewProgram(std::move(Orig)); 5280b57cec5SDimitry Andric return Ret; 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric BD.setNewProgram(std::move(Orig)); 5310b57cec5SDimitry Andric return false; 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric /// Given a reduced list of functions that still expose the bug, extract as many 5350b57cec5SDimitry Andric /// basic blocks from the region as possible without obscuring the bug. 5360b57cec5SDimitry Andric /// 5370b57cec5SDimitry Andric static Expected<bool> 5380b57cec5SDimitry Andric ExtractBlocks(BugDriver &BD, 5390b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 5400b57cec5SDimitry Andric std::unique_ptr<Module>), 5410b57cec5SDimitry Andric std::vector<Function *> &MiscompiledFunctions) { 5420b57cec5SDimitry Andric if (BugpointIsInterrupted) 5430b57cec5SDimitry Andric return false; 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric std::vector<BasicBlock *> Blocks; 5460b57cec5SDimitry Andric for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) 5470b57cec5SDimitry Andric for (BasicBlock &BB : *MiscompiledFunctions[i]) 5480b57cec5SDimitry Andric Blocks.push_back(&BB); 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric // Use the list reducer to identify blocks that can be extracted without 5510b57cec5SDimitry Andric // obscuring the bug. The Blocks list will end up containing blocks that must 5520b57cec5SDimitry Andric // be retained from the original program. 5530b57cec5SDimitry Andric unsigned OldSize = Blocks.size(); 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric // Check to see if all blocks are extractible first. 5560b57cec5SDimitry Andric Expected<bool> Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) 5570b57cec5SDimitry Andric .TestFuncs(std::vector<BasicBlock *>()); 5580b57cec5SDimitry Andric if (Error E = Ret.takeError()) 5590b57cec5SDimitry Andric return std::move(E); 5600b57cec5SDimitry Andric if (*Ret) { 5610b57cec5SDimitry Andric Blocks.clear(); 5620b57cec5SDimitry Andric } else { 5630b57cec5SDimitry Andric Expected<bool> Ret = 5640b57cec5SDimitry Andric ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) 5650b57cec5SDimitry Andric .reduceList(Blocks); 5660b57cec5SDimitry Andric if (Error E = Ret.takeError()) 5670b57cec5SDimitry Andric return std::move(E); 5680b57cec5SDimitry Andric if (Blocks.size() == OldSize) 5690b57cec5SDimitry Andric return false; 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric ValueToValueMapTy VMap; 5730b57cec5SDimitry Andric std::unique_ptr<Module> ProgClone = CloneModule(BD.getProgram(), VMap); 5740b57cec5SDimitry Andric std::unique_ptr<Module> ToExtract = 5750b57cec5SDimitry Andric SplitFunctionsOutOfModule(ProgClone.get(), MiscompiledFunctions, VMap); 5760b57cec5SDimitry Andric std::unique_ptr<Module> Extracted = 5770b57cec5SDimitry Andric BD.extractMappedBlocksFromModule(Blocks, ToExtract.get()); 5780b57cec5SDimitry Andric if (!Extracted) { 5790b57cec5SDimitry Andric // Weird, extraction should have worked. 5800b57cec5SDimitry Andric errs() << "Nondeterministic problem extracting blocks??\n"; 5810b57cec5SDimitry Andric return false; 5820b57cec5SDimitry Andric } 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric // Otherwise, block extraction succeeded. Link the two program fragments back 5850b57cec5SDimitry Andric // together. 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; 5880b57cec5SDimitry Andric for (Module::iterator I = Extracted->begin(), E = Extracted->end(); I != E; 5890b57cec5SDimitry Andric ++I) 5900b57cec5SDimitry Andric if (!I->isDeclaration()) 5915ffd83dbSDimitry Andric MisCompFunctions.emplace_back(std::string(I->getName()), 5925ffd83dbSDimitry Andric I->getFunctionType()); 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric if (Linker::linkModules(*ProgClone, std::move(Extracted))) 5950b57cec5SDimitry Andric exit(1); 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric // Update the list of miscompiled functions. 5980b57cec5SDimitry Andric MiscompiledFunctions.clear(); 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { 6010b57cec5SDimitry Andric Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first); 6020b57cec5SDimitry Andric assert(NewF && "Function not found??"); 6030b57cec5SDimitry Andric MiscompiledFunctions.push_back(NewF); 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric // Set the new program and delete the old one. 6070b57cec5SDimitry Andric BD.setNewProgram(std::move(ProgClone)); 6080b57cec5SDimitry Andric 6090b57cec5SDimitry Andric return true; 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric /// This is a generic driver to narrow down miscompilations, either in an 6130b57cec5SDimitry Andric /// optimization or a code generator. 6140b57cec5SDimitry Andric /// 6150b57cec5SDimitry Andric static Expected<std::vector<Function *>> DebugAMiscompilation( 6160b57cec5SDimitry Andric BugDriver &BD, 6170b57cec5SDimitry Andric Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, 6180b57cec5SDimitry Andric std::unique_ptr<Module>)) { 6190b57cec5SDimitry Andric // Okay, now that we have reduced the list of passes which are causing the 6200b57cec5SDimitry Andric // failure, see if we can pin down which functions are being 6210b57cec5SDimitry Andric // miscompiled... first build a list of all of the non-external functions in 6220b57cec5SDimitry Andric // the program. 6230b57cec5SDimitry Andric std::vector<Function *> MiscompiledFunctions; 6240b57cec5SDimitry Andric Module &Prog = BD.getProgram(); 6250b57cec5SDimitry Andric for (Function &F : Prog) 6260b57cec5SDimitry Andric if (!F.isDeclaration()) 6270b57cec5SDimitry Andric MiscompiledFunctions.push_back(&F); 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric // Do the reduction... 6300b57cec5SDimitry Andric if (!BugpointIsInterrupted) { 6310b57cec5SDimitry Andric Expected<bool> Ret = ReduceMiscompilingFunctions(BD, TestFn) 6320b57cec5SDimitry Andric .reduceList(MiscompiledFunctions); 6330b57cec5SDimitry Andric if (Error E = Ret.takeError()) { 6340b57cec5SDimitry Andric errs() << "\n***Cannot reduce functions: "; 6350b57cec5SDimitry Andric return std::move(E); 6360b57cec5SDimitry Andric } 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric outs() << "\n*** The following function" 6390b57cec5SDimitry Andric << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 6400b57cec5SDimitry Andric << " being miscompiled: "; 6410b57cec5SDimitry Andric PrintFunctionList(MiscompiledFunctions); 6420b57cec5SDimitry Andric outs() << '\n'; 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric // See if we can rip any loops out of the miscompiled functions and still 6450b57cec5SDimitry Andric // trigger the problem. 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric if (!BugpointIsInterrupted && !DisableLoopExtraction) { 6480b57cec5SDimitry Andric Expected<bool> Ret = ExtractLoops(BD, TestFn, MiscompiledFunctions); 6490b57cec5SDimitry Andric if (Error E = Ret.takeError()) 6500b57cec5SDimitry Andric return std::move(E); 6510b57cec5SDimitry Andric if (*Ret) { 6520b57cec5SDimitry Andric // Okay, we extracted some loops and the problem still appears. See if 6530b57cec5SDimitry Andric // we can eliminate some of the created functions from being candidates. 6540b57cec5SDimitry Andric DisambiguateGlobalSymbols(BD.getProgram()); 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric // Do the reduction... 6570b57cec5SDimitry Andric if (!BugpointIsInterrupted) 6580b57cec5SDimitry Andric Ret = ReduceMiscompilingFunctions(BD, TestFn) 6590b57cec5SDimitry Andric .reduceList(MiscompiledFunctions); 6600b57cec5SDimitry Andric if (Error E = Ret.takeError()) 6610b57cec5SDimitry Andric return std::move(E); 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric outs() << "\n*** The following function" 6640b57cec5SDimitry Andric << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 6650b57cec5SDimitry Andric << " being miscompiled: "; 6660b57cec5SDimitry Andric PrintFunctionList(MiscompiledFunctions); 6670b57cec5SDimitry Andric outs() << '\n'; 6680b57cec5SDimitry Andric } 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric if (!BugpointIsInterrupted && !DisableBlockExtraction) { 6720b57cec5SDimitry Andric Expected<bool> Ret = ExtractBlocks(BD, TestFn, MiscompiledFunctions); 6730b57cec5SDimitry Andric if (Error E = Ret.takeError()) 6740b57cec5SDimitry Andric return std::move(E); 6750b57cec5SDimitry Andric if (*Ret) { 6760b57cec5SDimitry Andric // Okay, we extracted some blocks and the problem still appears. See if 6770b57cec5SDimitry Andric // we can eliminate some of the created functions from being candidates. 6780b57cec5SDimitry Andric DisambiguateGlobalSymbols(BD.getProgram()); 6790b57cec5SDimitry Andric 6800b57cec5SDimitry Andric // Do the reduction... 6810b57cec5SDimitry Andric Ret = ReduceMiscompilingFunctions(BD, TestFn) 6820b57cec5SDimitry Andric .reduceList(MiscompiledFunctions); 6830b57cec5SDimitry Andric if (Error E = Ret.takeError()) 6840b57cec5SDimitry Andric return std::move(E); 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric outs() << "\n*** The following function" 6870b57cec5SDimitry Andric << (MiscompiledFunctions.size() == 1 ? " is" : "s are") 6880b57cec5SDimitry Andric << " being miscompiled: "; 6890b57cec5SDimitry Andric PrintFunctionList(MiscompiledFunctions); 6900b57cec5SDimitry Andric outs() << '\n'; 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric } 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric return MiscompiledFunctions; 6950b57cec5SDimitry Andric } 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric /// This is the predicate function used to check to see if the "Test" portion of 6980b57cec5SDimitry Andric /// the program is misoptimized. If so, return true. In any case, both module 6990b57cec5SDimitry Andric /// arguments are deleted. 7000b57cec5SDimitry Andric /// 7010b57cec5SDimitry Andric static Expected<bool> TestOptimizer(BugDriver &BD, std::unique_ptr<Module> Test, 7020b57cec5SDimitry Andric std::unique_ptr<Module> Safe) { 7030b57cec5SDimitry Andric // Run the optimization passes on ToOptimize, producing a transformed version 7040b57cec5SDimitry Andric // of the functions being tested. 7050b57cec5SDimitry Andric outs() << " Optimizing functions being tested: "; 7060b57cec5SDimitry Andric std::unique_ptr<Module> Optimized = 7070b57cec5SDimitry Andric BD.runPassesOn(Test.get(), BD.getPassesToRun()); 7080b57cec5SDimitry Andric if (!Optimized) { 7090b57cec5SDimitry Andric errs() << " Error running this sequence of passes" 7100b57cec5SDimitry Andric << " on the input program!\n"; 7110b57cec5SDimitry Andric BD.EmitProgressBitcode(*Test, "pass-error", false); 7120b57cec5SDimitry Andric BD.setNewProgram(std::move(Test)); 7130b57cec5SDimitry Andric if (Error E = BD.debugOptimizerCrash()) 7140b57cec5SDimitry Andric return std::move(E); 7150b57cec5SDimitry Andric return false; 7160b57cec5SDimitry Andric } 7170b57cec5SDimitry Andric outs() << "done.\n"; 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric outs() << " Checking to see if the merged program executes correctly: "; 7200b57cec5SDimitry Andric bool Broken; 7210b57cec5SDimitry Andric auto Result = testMergedProgram(BD, *Optimized, *Safe, Broken); 7220b57cec5SDimitry Andric if (Error E = Result.takeError()) 7230b57cec5SDimitry Andric return std::move(E); 7240b57cec5SDimitry Andric if (auto New = std::move(*Result)) { 7250b57cec5SDimitry Andric outs() << (Broken ? " nope.\n" : " yup.\n"); 7260b57cec5SDimitry Andric // Delete the original and set the new program. 7270b57cec5SDimitry Andric BD.setNewProgram(std::move(New)); 7280b57cec5SDimitry Andric } 7290b57cec5SDimitry Andric return Broken; 7300b57cec5SDimitry Andric } 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric /// debugMiscompilation - This method is used when the passes selected are not 7330b57cec5SDimitry Andric /// crashing, but the generated output is semantically different from the 7340b57cec5SDimitry Andric /// input. 7350b57cec5SDimitry Andric /// 7360b57cec5SDimitry Andric Error BugDriver::debugMiscompilation() { 7370b57cec5SDimitry Andric // Make sure something was miscompiled... 7380b57cec5SDimitry Andric if (!BugpointIsInterrupted) { 7390b57cec5SDimitry Andric Expected<bool> Result = 7400b57cec5SDimitry Andric ReduceMiscompilingPasses(*this).reduceList(PassesToRun); 7410b57cec5SDimitry Andric if (Error E = Result.takeError()) 7420b57cec5SDimitry Andric return E; 7430b57cec5SDimitry Andric if (!*Result) 7440b57cec5SDimitry Andric return make_error<StringError>( 7450b57cec5SDimitry Andric "*** Optimized program matches reference output! No problem" 7460b57cec5SDimitry Andric " detected...\nbugpoint can't help you with your problem!\n", 7470b57cec5SDimitry Andric inconvertibleErrorCode()); 7480b57cec5SDimitry Andric } 7490b57cec5SDimitry Andric 7500b57cec5SDimitry Andric outs() << "\n*** Found miscompiling pass" 7510b57cec5SDimitry Andric << (getPassesToRun().size() == 1 ? "" : "es") << ": " 7520b57cec5SDimitry Andric << getPassesString(getPassesToRun()) << '\n'; 7530b57cec5SDimitry Andric EmitProgressBitcode(*Program, "passinput"); 7540b57cec5SDimitry Andric 7550b57cec5SDimitry Andric Expected<std::vector<Function *>> MiscompiledFunctions = 7560b57cec5SDimitry Andric DebugAMiscompilation(*this, TestOptimizer); 7570b57cec5SDimitry Andric if (Error E = MiscompiledFunctions.takeError()) 7580b57cec5SDimitry Andric return E; 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric // Output a bunch of bitcode files for the user... 7610b57cec5SDimitry Andric outs() << "Outputting reduced bitcode files which expose the problem:\n"; 7620b57cec5SDimitry Andric ValueToValueMapTy VMap; 7630b57cec5SDimitry Andric Module *ToNotOptimize = CloneModule(getProgram(), VMap).release(); 7640b57cec5SDimitry Andric Module *ToOptimize = 7650b57cec5SDimitry Andric SplitFunctionsOutOfModule(ToNotOptimize, *MiscompiledFunctions, VMap) 7660b57cec5SDimitry Andric .release(); 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andric outs() << " Non-optimized portion: "; 7690b57cec5SDimitry Andric EmitProgressBitcode(*ToNotOptimize, "tonotoptimize", true); 7700b57cec5SDimitry Andric delete ToNotOptimize; // Delete hacked module. 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric outs() << " Portion that is input to optimizer: "; 7730b57cec5SDimitry Andric EmitProgressBitcode(*ToOptimize, "tooptimize"); 7740b57cec5SDimitry Andric delete ToOptimize; // Delete hacked module. 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric return Error::success(); 7770b57cec5SDimitry Andric } 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric /// Get the specified modules ready for code generator testing. 7800b57cec5SDimitry Andric /// 7810b57cec5SDimitry Andric static std::unique_ptr<Module> 7820b57cec5SDimitry Andric CleanupAndPrepareModules(BugDriver &BD, std::unique_ptr<Module> Test, 7830b57cec5SDimitry Andric Module *Safe) { 7840b57cec5SDimitry Andric // Clean up the modules, removing extra cruft that we don't need anymore... 7850b57cec5SDimitry Andric Test = BD.performFinalCleanups(std::move(Test)); 7860b57cec5SDimitry Andric 7870b57cec5SDimitry Andric // If we are executing the JIT, we have several nasty issues to take care of. 7880b57cec5SDimitry Andric if (!BD.isExecutingJIT()) 7890b57cec5SDimitry Andric return Test; 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric // First, if the main function is in the Safe module, we must add a stub to 7920b57cec5SDimitry Andric // the Test module to call into it. Thus, we create a new function `main' 7930b57cec5SDimitry Andric // which just calls the old one. 7940b57cec5SDimitry Andric if (Function *oldMain = Safe->getFunction("main")) 7950b57cec5SDimitry Andric if (!oldMain->isDeclaration()) { 7960b57cec5SDimitry Andric // Rename it 7970b57cec5SDimitry Andric oldMain->setName("llvm_bugpoint_old_main"); 7980b57cec5SDimitry Andric // Create a NEW `main' function with same type in the test module. 7990b57cec5SDimitry Andric Function *newMain = 8000b57cec5SDimitry Andric Function::Create(oldMain->getFunctionType(), 8010b57cec5SDimitry Andric GlobalValue::ExternalLinkage, "main", Test.get()); 8020b57cec5SDimitry Andric // Create an `oldmain' prototype in the test module, which will 8030b57cec5SDimitry Andric // corresponds to the real main function in the same module. 8040b57cec5SDimitry Andric Function *oldMainProto = Function::Create(oldMain->getFunctionType(), 8050b57cec5SDimitry Andric GlobalValue::ExternalLinkage, 8060b57cec5SDimitry Andric oldMain->getName(), Test.get()); 8070b57cec5SDimitry Andric // Set up and remember the argument list for the main function. 8080b57cec5SDimitry Andric std::vector<Value *> args; 8090b57cec5SDimitry Andric for (Function::arg_iterator I = newMain->arg_begin(), 8100b57cec5SDimitry Andric E = newMain->arg_end(), 8110b57cec5SDimitry Andric OI = oldMain->arg_begin(); 8120b57cec5SDimitry Andric I != E; ++I, ++OI) { 8130b57cec5SDimitry Andric I->setName(OI->getName()); // Copy argument names from oldMain 8140b57cec5SDimitry Andric args.push_back(&*I); 8150b57cec5SDimitry Andric } 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric // Call the old main function and return its result 8180b57cec5SDimitry Andric BasicBlock *BB = BasicBlock::Create(Safe->getContext(), "entry", newMain); 8190b57cec5SDimitry Andric CallInst *call = CallInst::Create(oldMainProto, args, "", BB); 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric // If the type of old function wasn't void, return value of call 8220b57cec5SDimitry Andric ReturnInst::Create(Safe->getContext(), call, BB); 8230b57cec5SDimitry Andric } 8240b57cec5SDimitry Andric 8250b57cec5SDimitry Andric // The second nasty issue we must deal with in the JIT is that the Safe 8260b57cec5SDimitry Andric // module cannot directly reference any functions defined in the test 8270b57cec5SDimitry Andric // module. Instead, we use a JIT API call to dynamically resolve the 8280b57cec5SDimitry Andric // symbol. 8290b57cec5SDimitry Andric 8300b57cec5SDimitry Andric // Add the resolver to the Safe module. 8310b57cec5SDimitry Andric // Prototype: void *getPointerToNamedFunction(const char* Name) 8320b57cec5SDimitry Andric FunctionCallee resolverFunc = Safe->getOrInsertFunction( 833*5f757f3fSDimitry Andric "getPointerToNamedFunction", PointerType::getUnqual(Safe->getContext()), 834*5f757f3fSDimitry Andric PointerType::getUnqual(Safe->getContext())); 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric // Use the function we just added to get addresses of functions we need. 8370b57cec5SDimitry Andric for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) { 8380b57cec5SDimitry Andric if (F->isDeclaration() && !F->use_empty() && 8390b57cec5SDimitry Andric &*F != resolverFunc.getCallee() && 8400b57cec5SDimitry Andric !F->isIntrinsic() /* ignore intrinsics */) { 8410b57cec5SDimitry Andric Function *TestFn = Test->getFunction(F->getName()); 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric // Don't forward functions which are external in the test module too. 8440b57cec5SDimitry Andric if (TestFn && !TestFn->isDeclaration()) { 8450b57cec5SDimitry Andric // 1. Add a string constant with its name to the global file 8460b57cec5SDimitry Andric Constant *InitArray = 8470b57cec5SDimitry Andric ConstantDataArray::getString(F->getContext(), F->getName()); 8480b57cec5SDimitry Andric GlobalVariable *funcName = new GlobalVariable( 8490b57cec5SDimitry Andric *Safe, InitArray->getType(), true /*isConstant*/, 8500b57cec5SDimitry Andric GlobalValue::InternalLinkage, InitArray, F->getName() + "_name"); 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andric // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an 8530b57cec5SDimitry Andric // sbyte* so it matches the signature of the resolver function. 8540b57cec5SDimitry Andric 8550b57cec5SDimitry Andric // GetElementPtr *funcName, ulong 0, ulong 0 8560b57cec5SDimitry Andric std::vector<Constant *> GEPargs( 8570b57cec5SDimitry Andric 2, Constant::getNullValue(Type::getInt32Ty(F->getContext()))); 8580b57cec5SDimitry Andric Value *GEP = ConstantExpr::getGetElementPtr(InitArray->getType(), 8590b57cec5SDimitry Andric funcName, GEPargs); 8600b57cec5SDimitry Andric std::vector<Value *> ResolverArgs; 8610b57cec5SDimitry Andric ResolverArgs.push_back(GEP); 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric // Rewrite uses of F in global initializers, etc. to uses of a wrapper 8640b57cec5SDimitry Andric // function that dynamically resolves the calls to F via our JIT API 8650b57cec5SDimitry Andric if (!F->use_empty()) { 8660b57cec5SDimitry Andric // Create a new global to hold the cached function pointer. 8670b57cec5SDimitry Andric Constant *NullPtr = ConstantPointerNull::get(F->getType()); 8680b57cec5SDimitry Andric GlobalVariable *Cache = new GlobalVariable( 8690b57cec5SDimitry Andric *F->getParent(), F->getType(), false, 8700b57cec5SDimitry Andric GlobalValue::InternalLinkage, NullPtr, F->getName() + ".fpcache"); 8710b57cec5SDimitry Andric 8720b57cec5SDimitry Andric // Construct a new stub function that will re-route calls to F 8730b57cec5SDimitry Andric FunctionType *FuncTy = F->getFunctionType(); 8740b57cec5SDimitry Andric Function *FuncWrapper = 8750b57cec5SDimitry Andric Function::Create(FuncTy, GlobalValue::InternalLinkage, 8760b57cec5SDimitry Andric F->getName() + "_wrapper", F->getParent()); 8770b57cec5SDimitry Andric BasicBlock *EntryBB = 8780b57cec5SDimitry Andric BasicBlock::Create(F->getContext(), "entry", FuncWrapper); 8790b57cec5SDimitry Andric BasicBlock *DoCallBB = 8800b57cec5SDimitry Andric BasicBlock::Create(F->getContext(), "usecache", FuncWrapper); 8810b57cec5SDimitry Andric BasicBlock *LookupBB = 8820b57cec5SDimitry Andric BasicBlock::Create(F->getContext(), "lookupfp", FuncWrapper); 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric // Check to see if we already looked up the value. 8850b57cec5SDimitry Andric Value *CachedVal = 8860b57cec5SDimitry Andric new LoadInst(F->getType(), Cache, "fpcache", EntryBB); 8870b57cec5SDimitry Andric Value *IsNull = new ICmpInst(*EntryBB, ICmpInst::ICMP_EQ, CachedVal, 8880b57cec5SDimitry Andric NullPtr, "isNull"); 8890b57cec5SDimitry Andric BranchInst::Create(LookupBB, DoCallBB, IsNull, EntryBB); 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric // Resolve the call to function F via the JIT API: 8920b57cec5SDimitry Andric // 8930b57cec5SDimitry Andric // call resolver(GetElementPtr...) 8940b57cec5SDimitry Andric CallInst *Resolver = CallInst::Create(resolverFunc, ResolverArgs, 8950b57cec5SDimitry Andric "resolver", LookupBB); 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andric // Cast the result from the resolver to correctly-typed function. 8980b57cec5SDimitry Andric CastInst *CastedResolver = new BitCastInst( 8990b57cec5SDimitry Andric Resolver, PointerType::getUnqual(F->getFunctionType()), 9000b57cec5SDimitry Andric "resolverCast", LookupBB); 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric // Save the value in our cache. 9030b57cec5SDimitry Andric new StoreInst(CastedResolver, Cache, LookupBB); 9040b57cec5SDimitry Andric BranchInst::Create(DoCallBB, LookupBB); 9050b57cec5SDimitry Andric 9060b57cec5SDimitry Andric PHINode *FuncPtr = 9070b57cec5SDimitry Andric PHINode::Create(NullPtr->getType(), 2, "fp", DoCallBB); 9080b57cec5SDimitry Andric FuncPtr->addIncoming(CastedResolver, LookupBB); 9090b57cec5SDimitry Andric FuncPtr->addIncoming(CachedVal, EntryBB); 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric // Save the argument list. 9120b57cec5SDimitry Andric std::vector<Value *> Args; 9130b57cec5SDimitry Andric for (Argument &A : FuncWrapper->args()) 9140b57cec5SDimitry Andric Args.push_back(&A); 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric // Pass on the arguments to the real function, return its result 9170b57cec5SDimitry Andric if (F->getReturnType()->isVoidTy()) { 9180b57cec5SDimitry Andric CallInst::Create(FuncTy, FuncPtr, Args, "", DoCallBB); 9190b57cec5SDimitry Andric ReturnInst::Create(F->getContext(), DoCallBB); 9200b57cec5SDimitry Andric } else { 9210b57cec5SDimitry Andric CallInst *Call = 9220b57cec5SDimitry Andric CallInst::Create(FuncTy, FuncPtr, Args, "retval", DoCallBB); 9230b57cec5SDimitry Andric ReturnInst::Create(F->getContext(), Call, DoCallBB); 9240b57cec5SDimitry Andric } 9250b57cec5SDimitry Andric 9260b57cec5SDimitry Andric // Use the wrapper function instead of the old function 9270b57cec5SDimitry Andric F->replaceAllUsesWith(FuncWrapper); 9280b57cec5SDimitry Andric } 9290b57cec5SDimitry Andric } 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric } 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric if (verifyModule(*Test) || verifyModule(*Safe)) { 9340b57cec5SDimitry Andric errs() << "Bugpoint has a bug, which corrupted a module!!\n"; 9350b57cec5SDimitry Andric abort(); 9360b57cec5SDimitry Andric } 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andric return Test; 9390b57cec5SDimitry Andric } 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric /// This is the predicate function used to check to see if the "Test" portion of 9420b57cec5SDimitry Andric /// the program is miscompiled by the code generator under test. If so, return 9430b57cec5SDimitry Andric /// true. In any case, both module arguments are deleted. 9440b57cec5SDimitry Andric /// 9450b57cec5SDimitry Andric static Expected<bool> TestCodeGenerator(BugDriver &BD, 9460b57cec5SDimitry Andric std::unique_ptr<Module> Test, 9470b57cec5SDimitry Andric std::unique_ptr<Module> Safe) { 9480b57cec5SDimitry Andric Test = CleanupAndPrepareModules(BD, std::move(Test), Safe.get()); 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric SmallString<128> TestModuleBC; 9510b57cec5SDimitry Andric int TestModuleFD; 9520b57cec5SDimitry Andric std::error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", 9530b57cec5SDimitry Andric TestModuleFD, TestModuleBC); 9540b57cec5SDimitry Andric if (EC) { 9550b57cec5SDimitry Andric errs() << BD.getToolName() 9560b57cec5SDimitry Andric << "Error making unique filename: " << EC.message() << "\n"; 9570b57cec5SDimitry Andric exit(1); 9580b57cec5SDimitry Andric } 9595ffd83dbSDimitry Andric if (BD.writeProgramToFile(std::string(TestModuleBC.str()), TestModuleFD, 9605ffd83dbSDimitry Andric *Test)) { 9610b57cec5SDimitry Andric errs() << "Error writing bitcode to `" << TestModuleBC.str() 9620b57cec5SDimitry Andric << "'\nExiting."; 9630b57cec5SDimitry Andric exit(1); 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps); 9670b57cec5SDimitry Andric 9680b57cec5SDimitry Andric // Make the shared library 9690b57cec5SDimitry Andric SmallString<128> SafeModuleBC; 9700b57cec5SDimitry Andric int SafeModuleFD; 9710b57cec5SDimitry Andric EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, 9720b57cec5SDimitry Andric SafeModuleBC); 9730b57cec5SDimitry Andric if (EC) { 9740b57cec5SDimitry Andric errs() << BD.getToolName() 9750b57cec5SDimitry Andric << "Error making unique filename: " << EC.message() << "\n"; 9760b57cec5SDimitry Andric exit(1); 9770b57cec5SDimitry Andric } 9780b57cec5SDimitry Andric 9795ffd83dbSDimitry Andric if (BD.writeProgramToFile(std::string(SafeModuleBC.str()), SafeModuleFD, 9805ffd83dbSDimitry Andric *Safe)) { 9810b57cec5SDimitry Andric errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; 9820b57cec5SDimitry Andric exit(1); 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric 9850b57cec5SDimitry Andric FileRemover SafeModuleBCRemover(SafeModuleBC.str(), !SaveTemps); 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric Expected<std::string> SharedObject = 9885ffd83dbSDimitry Andric BD.compileSharedObject(std::string(SafeModuleBC.str())); 9890b57cec5SDimitry Andric if (Error E = SharedObject.takeError()) 9900b57cec5SDimitry Andric return std::move(E); 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric FileRemover SharedObjectRemover(*SharedObject, !SaveTemps); 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andric // Run the code generator on the `Test' code, loading the shared library. 9950b57cec5SDimitry Andric // The function returns whether or not the new output differs from reference. 9965ffd83dbSDimitry Andric Expected<bool> Result = BD.diffProgram( 9975ffd83dbSDimitry Andric BD.getProgram(), std::string(TestModuleBC.str()), *SharedObject, false); 9980b57cec5SDimitry Andric if (Error E = Result.takeError()) 9990b57cec5SDimitry Andric return std::move(E); 10000b57cec5SDimitry Andric 10010b57cec5SDimitry Andric if (*Result) 10020b57cec5SDimitry Andric errs() << ": still failing!\n"; 10030b57cec5SDimitry Andric else 10040b57cec5SDimitry Andric errs() << ": didn't fail.\n"; 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andric return Result; 10070b57cec5SDimitry Andric } 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric /// debugCodeGenerator - debug errors in LLC, LLI, or CBE. 10100b57cec5SDimitry Andric /// 10110b57cec5SDimitry Andric Error BugDriver::debugCodeGenerator() { 10120b57cec5SDimitry Andric if ((void *)SafeInterpreter == (void *)Interpreter) { 10130b57cec5SDimitry Andric Expected<std::string> Result = 10140b57cec5SDimitry Andric executeProgramSafely(*Program, "bugpoint.safe.out"); 10150b57cec5SDimitry Andric if (Result) { 10160b57cec5SDimitry Andric outs() << "\n*** The \"safe\" i.e. 'known good' backend cannot match " 10170b57cec5SDimitry Andric << "the reference diff. This may be due to a\n front-end " 10180b57cec5SDimitry Andric << "bug or a bug in the original program, but this can also " 10190b57cec5SDimitry Andric << "happen if bugpoint isn't running the program with the " 10200b57cec5SDimitry Andric << "right flags or input.\n I left the result of executing " 10210b57cec5SDimitry Andric << "the program with the \"safe\" backend in this file for " 10220b57cec5SDimitry Andric << "you: '" << *Result << "'.\n"; 10230b57cec5SDimitry Andric } 10240b57cec5SDimitry Andric return Error::success(); 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric DisambiguateGlobalSymbols(*Program); 10280b57cec5SDimitry Andric 10290b57cec5SDimitry Andric Expected<std::vector<Function *>> Funcs = 10300b57cec5SDimitry Andric DebugAMiscompilation(*this, TestCodeGenerator); 10310b57cec5SDimitry Andric if (Error E = Funcs.takeError()) 10320b57cec5SDimitry Andric return E; 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric // Split the module into the two halves of the program we want. 10350b57cec5SDimitry Andric ValueToValueMapTy VMap; 10360b57cec5SDimitry Andric std::unique_ptr<Module> ToNotCodeGen = CloneModule(getProgram(), VMap); 10370b57cec5SDimitry Andric std::unique_ptr<Module> ToCodeGen = 10380b57cec5SDimitry Andric SplitFunctionsOutOfModule(ToNotCodeGen.get(), *Funcs, VMap); 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric // Condition the modules 10410b57cec5SDimitry Andric ToCodeGen = 10420b57cec5SDimitry Andric CleanupAndPrepareModules(*this, std::move(ToCodeGen), ToNotCodeGen.get()); 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andric SmallString<128> TestModuleBC; 10450b57cec5SDimitry Andric int TestModuleFD; 10460b57cec5SDimitry Andric std::error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", 10470b57cec5SDimitry Andric TestModuleFD, TestModuleBC); 10480b57cec5SDimitry Andric if (EC) { 10490b57cec5SDimitry Andric errs() << getToolName() << "Error making unique filename: " << EC.message() 10500b57cec5SDimitry Andric << "\n"; 10510b57cec5SDimitry Andric exit(1); 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric 10545ffd83dbSDimitry Andric if (writeProgramToFile(std::string(TestModuleBC.str()), TestModuleFD, 10555ffd83dbSDimitry Andric *ToCodeGen)) { 10560b57cec5SDimitry Andric errs() << "Error writing bitcode to `" << TestModuleBC << "'\nExiting."; 10570b57cec5SDimitry Andric exit(1); 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric // Make the shared library 10610b57cec5SDimitry Andric SmallString<128> SafeModuleBC; 10620b57cec5SDimitry Andric int SafeModuleFD; 10630b57cec5SDimitry Andric EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, 10640b57cec5SDimitry Andric SafeModuleBC); 10650b57cec5SDimitry Andric if (EC) { 10660b57cec5SDimitry Andric errs() << getToolName() << "Error making unique filename: " << EC.message() 10670b57cec5SDimitry Andric << "\n"; 10680b57cec5SDimitry Andric exit(1); 10690b57cec5SDimitry Andric } 10700b57cec5SDimitry Andric 10715ffd83dbSDimitry Andric if (writeProgramToFile(std::string(SafeModuleBC.str()), SafeModuleFD, 10725ffd83dbSDimitry Andric *ToNotCodeGen)) { 10730b57cec5SDimitry Andric errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; 10740b57cec5SDimitry Andric exit(1); 10750b57cec5SDimitry Andric } 10765ffd83dbSDimitry Andric Expected<std::string> SharedObject = 10775ffd83dbSDimitry Andric compileSharedObject(std::string(SafeModuleBC.str())); 10780b57cec5SDimitry Andric if (Error E = SharedObject.takeError()) 10790b57cec5SDimitry Andric return E; 10800b57cec5SDimitry Andric 10810b57cec5SDimitry Andric outs() << "You can reproduce the problem with the command line: \n"; 10820b57cec5SDimitry Andric if (isExecutingJIT()) { 10830b57cec5SDimitry Andric outs() << " lli -load " << *SharedObject << " " << TestModuleBC; 10840b57cec5SDimitry Andric } else { 10850b57cec5SDimitry Andric outs() << " llc " << TestModuleBC << " -o " << TestModuleBC << ".s\n"; 10860b57cec5SDimitry Andric outs() << " cc " << *SharedObject << " " << TestModuleBC.str() << ".s -o " 10870b57cec5SDimitry Andric << TestModuleBC << ".exe\n"; 10880b57cec5SDimitry Andric outs() << " ./" << TestModuleBC << ".exe"; 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric for (unsigned i = 0, e = InputArgv.size(); i != e; ++i) 10910b57cec5SDimitry Andric outs() << " " << InputArgv[i]; 10920b57cec5SDimitry Andric outs() << '\n'; 10930b57cec5SDimitry Andric outs() << "The shared object was created with:\n llc -march=c " 10940b57cec5SDimitry Andric << SafeModuleBC.str() << " -o temporary.c\n" 10950b57cec5SDimitry Andric << " cc -xc temporary.c -O2 -o " << *SharedObject; 10960b57cec5SDimitry Andric if (TargetTriple.getArch() == Triple::sparc) 10970b57cec5SDimitry Andric outs() << " -G"; // Compile a shared library, `-G' for Sparc 10980b57cec5SDimitry Andric else 10990b57cec5SDimitry Andric outs() << " -fPIC -shared"; // `-shared' for Linux/X86, maybe others 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric outs() << " -fno-strict-aliasing\n"; 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric return Error::success(); 11040b57cec5SDimitry Andric } 1105