/// TestFuncs - Extract all blocks for the miscompiled functions except for the /// specified blocks. If the problem still exists, return true. /// bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs, std::string &Error) { // Test to see if the function is misoptimized if we ONLY run it on the // functions listed in Funcs. outs() << "Checking to see if the program is misoptimized when all "; if (!BBs.empty()) { outs() << "but these " << BBs.size() << " blocks are extracted: "; for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i) outs() << BBs[i]->getName() << " "; if (BBs.size() > 10) outs() << "..."; } else { outs() << "blocks are extracted."; } outs() << '\n'; // Split the module into the two halves of the program we want. ValueToValueMapTy VMap; Module *Clone = CloneModule(BD.getProgram(), VMap); Module *Orig = BD.swapProgramIn(Clone); std::vector<Function*> FuncsOnClone; std::vector<BasicBlock*> BBsOnClone; for (unsigned i = 0, e = FunctionsBeingTested.size(); i != e; ++i) { Function *F = cast<Function>(VMap[FunctionsBeingTested[i]]); FuncsOnClone.push_back(F); } for (unsigned i = 0, e = BBs.size(); i != e; ++i) { BasicBlock *BB = cast<BasicBlock>(VMap[BBs[i]]); BBsOnClone.push_back(BB); } VMap.clear(); Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, VMap); // Try the extraction. If it doesn't work, then the block extractor crashed // or something, in which case bugpoint can't chase down this possibility. if (std::unique_ptr<Module> New = BD.extractMappedBlocksFromModule(BBsOnClone, ToOptimize)) { delete ToOptimize; // Run the predicate, // note that the predicate will delete both input modules. bool Ret = TestFn(BD, New.get(), ToNotOptimize, Error); delete BD.swapProgramIn(Orig); return Ret; } delete BD.swapProgramIn(Orig); delete ToOptimize; delete ToNotOptimize; return false; }
/// TestFuncs - split functions in a Module into two groups: those that are /// under consideration for miscompilation vs. those that are not, and test /// accordingly. Each group of functions becomes a separate Module. /// bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs, std::string &Error) { // Test to see if the function is misoptimized if we ONLY run it on the // functions listed in Funcs. outs() << "Checking to see if the program is misoptimized when " << (Funcs.size()==1 ? "this function is" : "these functions are") << " run through the pass" << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":"; PrintFunctionList(Funcs); outs() << '\n'; // Create a clone for two reasons: // * If the optimization passes delete any function, the deleted function // will be in the clone and Funcs will still point to valid memory // * If the optimization passes use interprocedural information to break // a function, we want to continue with the original function. Otherwise // we can conclude that a function triggers the bug when in fact one // needs a larger set of original functions to do so. ValueToValueMapTy VMap; Module *Clone = CloneModule(BD.getProgram(), VMap); Module *Orig = BD.swapProgramIn(Clone); std::vector<Function*> FuncsOnClone; for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { Function *F = cast<Function>(VMap[Funcs[i]]); FuncsOnClone.push_back(F); } // Split the module into the two halves of the program we want. VMap.clear(); Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, VMap); // Run the predicate, note that the predicate will delete both input modules. bool Broken = TestFn(BD, ToOptimize, ToNotOptimize, Error); delete BD.swapProgramIn(Orig); return Broken; }