Index: utils/FileCheck/FileCheck.cpp
===================================================================
--- utils/FileCheck/FileCheck.cpp	(revision 172650)
+++ utils/FileCheck/FileCheck.cpp	(working copy)
@@ -49,6 +49,10 @@
 NoCanonicalizeWhiteSpace("strict-whitespace",
               cl::desc("Do not treat all horizontal whitespace as equivalent"));
 
+static cl::opt<bool>
+DumpInputOnError("dump-input-on-error",
+                 cl::desc("Dump input to stderr in case of errors"));
+
 //===----------------------------------------------------------------------===//
 // Pattern Handling Code.
 //===----------------------------------------------------------------------===//
@@ -587,8 +591,8 @@
     : Pat(P), Loc(L), IsCheckNext(isCheckNext) {}
 };
 
-/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified
-/// memory buffer, free it, and return a new one.
+/// Remove duplicate horizontal space from the specified memory buffer, and
+/// return a new one.  The original memory buffer is not freed.
 static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
   SmallString<128> NewFile;
   NewFile.reserve(MB->getBufferSize());
@@ -613,12 +617,8 @@
       ++Ptr;
   }
 
-  // Free the old buffer and return a new one.
-  MemoryBuffer *MB2 =
-    MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier());
-
-  delete MB;
-  return MB2;
+  return MemoryBuffer::getMemBufferCopy(NewFile.str(),
+                                        MB->getBufferIdentifier());
 }
 
 
@@ -779,6 +779,35 @@
   }
 }
 
+static void SaveInputFile(MemoryBuffer *F) {
+  {
+    SmallString<64> TmpDir;
+    sys::path::system_temp_directory(/*erasedOnReboot*/true, TmpDir);
+    llvm::sys::Path P(TmpDir);
+    P.appendComponent("filecheck");
+    P.appendSuffix("txt");
+    std::string ErrMsg;
+    if (P.makeUnique(/*reuse_current=*/false, &ErrMsg)) {
+      errs() << "Error making unique filename: " << ErrMsg << "\n";
+      return;
+    }
+    std::string SavedInputFileName = P.str();
+
+    errs() << "Saving input file \"" << F->getBufferIdentifier()
+           << "\" to \"" << SavedInputFileName << "\"\n";
+
+    raw_fd_ostream Out(SavedInputFileName.c_str(), ErrMsg,
+                       raw_fd_ostream::F_Binary);
+    Out << F->getBuffer();
+  }
+
+  if (!DumpInputOnError)
+    return;
+
+  errs() << "Input file contains:\n\n"
+         << F->getBuffer();
+}
+
 int main(int argc, char **argv) {
   sys::PrintStackTraceOnErrorSignal();
   PrettyStackTraceProgram X(argc, argv);
@@ -799,16 +828,17 @@
            << ec.message() << '\n';
     return 2;
   }
-  MemoryBuffer *F = File.take();
+  MemoryBuffer *OriginalFile = File.take();
 
-  if (F->getBufferSize() == 0) {
+  if (OriginalFile->getBufferSize() == 0) {
     errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
     return 2;
   }
   
   // Remove duplicate spaces in the input file if requested.
+  MemoryBuffer *F = OriginalFile;
   if (!NoCanonicalizeWhiteSpace)
-    F = CanonicalizeInputFile(F);
+    F = CanonicalizeInputFile(OriginalFile);
 
   SM.AddNewSourceBuffer(F, SMLoc());
 
@@ -834,6 +864,7 @@
     // If we didn't find a match, reject the input.
     if (MatchPos == StringRef::npos) {
       PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
+      SaveInputFile(OriginalFile);
       return 1;
     }
 
@@ -854,6 +885,7 @@
                         SourceMgr::DK_Note, "'next' match was here");
         SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
                         "previous match was here");
+        SaveInputFile(OriginalFile);
         return 1;
       }
 
@@ -864,6 +896,7 @@
                         SourceMgr::DK_Note, "'next' match was here");
         SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
                         "previous match was here");
+        SaveInputFile(OriginalFile);
         return 1;
       }
     }
@@ -882,6 +915,7 @@
                       CheckPrefix+"-NOT: string occurred!");
       SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first, SourceMgr::DK_Note,
                       CheckPrefix+"-NOT: pattern specified here");
+      SaveInputFile(OriginalFile);
       return 1;
     }
 
Index: test/lit.cfg
===================================================================
--- test/lit.cfg	(revision 172650)
+++ test/lit.cfg	(working copy)
@@ -177,6 +177,11 @@
 else:
   config.substitutions.append( ('%lli', 'lli') )
 
+if 'FILECHECK_DUMP_INPUT_ON_ERROR' in os.environ:
+  config.substitutions.append( ('%FileCheck', 'FileCheck --dump-input-on-error') )
+else:
+  config.substitutions.append( ('%FileCheck', 'FileCheck') )
+
 # Add site-specific substitutions.
 config.substitutions.append( ('%ocamlopt', config.ocamlopt_executable) )
 config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) )
