diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-07-26 00:07:51 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-07-26 00:07:51 +0000 |
commit | 84ae206c976c76761e307e5c45f8170d0b61015f (patch) | |
tree | d2bb7a9718246d1607cdca73c2ae7c08237f1f83 /tools/bugpoint | |
parent | 82d5baec32054849e760625e2413a27edfd1a9fc (diff) | |
download | external_llvm-84ae206c976c76761e307e5c45f8170d0b61015f.zip external_llvm-84ae206c976c76761e307e5c45f8170d0b61015f.tar.gz external_llvm-84ae206c976c76761e307e5c45f8170d0b61015f.tar.bz2 |
Clone and restore the module being reduced in
ReduceMiscompilingFunctions::TestFuncs. This makes the test functional
(i.e., no side effects).
Before we would end up using dead functions if a pass decided to remove them
(inline for example) and we would also keep broken functions and conclude that
that a single function was enough to reproduce the bug.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109387 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/bugpoint')
-rw-r--r-- | tools/bugpoint/Miscompilation.cpp | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 47ac3c5..3ceb573 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -198,7 +198,7 @@ namespace { return NoFailure; } - int TestFuncs(const std::vector<Function*> &Prefix, std::string &Error); + bool TestFuncs(const std::vector<Function*> &Prefix, std::string &Error); }; } @@ -239,8 +239,8 @@ static bool TestMergedProgram(BugDriver &BD, Module *M1, Module *M2, /// under consideration for miscompilation vs. those that are not, and test /// accordingly. Each group of functions becomes a separate Module. /// -int ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs, - std::string &Error) { +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 " @@ -250,14 +250,35 @@ int ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs, PrintFunctionList(Funcs); outs() << '\n'; - // Split the module into the two halves of the program we want. + // 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. ValueMap<const Value*, Value*> 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, Funcs, + Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, VMap); // Run the predicate, note that the predicate will delete both input modules. - return TestFn(BD, ToOptimize, ToNotOptimize, Error); + bool Broken = TestFn(BD, ToOptimize, ToNotOptimize, Error); + + delete BD.swapProgramIn(Orig); + + return Broken; } /// DisambiguateGlobalSymbols - Give anonymous global values names. |