aboutsummaryrefslogtreecommitdiffstats
path: root/tools/bugpoint
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-07-26 00:07:51 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-07-26 00:07:51 +0000
commit84ae206c976c76761e307e5c45f8170d0b61015f (patch)
treed2bb7a9718246d1607cdca73c2ae7c08237f1f83 /tools/bugpoint
parent82d5baec32054849e760625e2413a27edfd1a9fc (diff)
downloadexternal_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.cpp33
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.