diff --git a/llvm/tools/llvm-reduce/deltas/Delta.cpp b/llvm/tools/llvm-reduce/deltas/Delta.cpp --- a/llvm/tools/llvm-reduce/deltas/Delta.cpp +++ b/llvm/tools/llvm-reduce/deltas/Delta.cpp @@ -21,6 +21,8 @@ using namespace llvm; +extern Module *volatile LastIntersting; + bool IsReduced(Module &M, TestRunner &Test, SmallString<128> &CurrentFilepath) { // Write Module to tmp file int FD; @@ -148,6 +150,7 @@ FoundAtLeastOneNewUninterestingChunkWithCurrentGranularity = true; UninterestingChunks.insert(ChunkToCheckForUninterestingness); ReducedProgram = std::move(Clone); + LastIntersting = ReducedProgram.get(); errs() << " **** SUCCESS | lines: " << getLines(CurrentFilepath) << "\n"; } // Delete uninteresting chunks diff --git a/llvm/tools/llvm-reduce/llvm-reduce.cpp b/llvm/tools/llvm-reduce/llvm-reduce.cpp --- a/llvm/tools/llvm-reduce/llvm-reduce.cpp +++ b/llvm/tools/llvm-reduce/llvm-reduce.cpp @@ -21,6 +21,7 @@ #include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/InitLLVM.h" +#include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include @@ -80,6 +81,22 @@ return Result; } +/// This variable is mark volatile because it is accessed by a signal handler. +Module *volatile LastIntersting = nullptr; + +static void onCrashHandler(void *) { + StringRef Path = "last-interssting.ll"; + + std::error_code EC; + raw_fd_ostream Out(Path, EC); + if (EC) { + errs() << "Error opening output file: " << EC.message() << "!\n"; + exit(1); + } + LastIntersting->print(Out, /*AnnotationWriter=*/nullptr); + errs() << "\n Saved last intersting Module to " << Path << "\n"; +} + int main(int argc, char **argv) { InitLLVM X(argc, argv); @@ -88,6 +105,8 @@ LLVMContext Context; std::unique_ptr OriginalProgram = parseInputFile(InputFilename, Context); + LastIntersting = OriginalProgram.get(); + sys::AddSignalHandler(onCrashHandler, nullptr); // Initialize test environment TestRunner Tester(TestFilename, TestArguments);