[llvm] r266894 - LTO: Verify the input even if optimize() isn't called

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 20 10:48:22 PDT 2016


Author: dexonsmith
Date: Wed Apr 20 12:48:22 2016
New Revision: 266894

URL: http://llvm.org/viewvc/llvm-project?rev=266894&view=rev
Log:
LTO: Verify the input even if optimize() isn't called

Clients may call writeMergedModules before calling optimize, or call
compileOptimized without calling optimize.  Make sure they don't sneak
past the verifier.  This adds LTOCodeGenerator::verifyMergedModuleOnce,
and calls it from writeMergedModule, optimize, and codegenOptimized.

I couldn't find a good way to test this.  I tried writing broken IR to
send into llvm-lto, but LTOCodeGenerator doesn't understand textual IR,
and assembler runs the verifier itself anyway.  Checking in
valid-but-doesn't-verify bitcode here doesn't seem valuable.

Modified:
    llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp

Modified: llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h?rev=266894&r1=266893&r2=266894&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h (original)
+++ llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h Wed Apr 20 12:48:22 2016
@@ -68,9 +68,13 @@ struct LTOCodeGenerator {
   ~LTOCodeGenerator();
 
   /// Merge given module.  Return true on success.
+  ///
+  /// Resets \a HasVerifiedInput.
   bool addModule(struct LTOModule *);
 
   /// Set the destination module.
+  ///
+  /// Resets \a HasVerifiedInput.
   void setModule(std::unique_ptr<LTOModule> M);
 
   void setTargetOptions(TargetOptions Options);
@@ -123,6 +127,8 @@ struct LTOCodeGenerator {
 
   /// Write the merged module to the file specified by the given path.  Return
   /// true on success.
+  ///
+  /// Calls \a verifyMergedModuleOnce().
   bool writeMergedModules(const char *Path);
 
   /// Compile the merged module into a *single* output file; the path to output
@@ -147,6 +153,8 @@ struct LTOCodeGenerator {
                                         bool DisableVectorization);
 
   /// Optimizes the merged module.  Returns true on success.
+  ///
+  /// Calls \a verifyMergedModuleOnce().
   bool optimize(bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE,
                 bool DisableVectorization);
 
@@ -160,6 +168,8 @@ struct LTOCodeGenerator {
   /// than one element, code generation is done in parallel with out.size()
   /// threads.  Output files will be written to members of out. Returns true on
   /// success.
+  ///
+  /// Calls \a verifyMergedModuleOnce().
   bool compileOptimized(ArrayRef<raw_pwrite_stream *> Out);
 
   void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
@@ -171,6 +181,12 @@ struct LTOCodeGenerator {
 private:
   void initializeLTOPasses();
 
+  /// Verify the merged module on first call.
+  ///
+  /// Sets \a HasVerifiedInput on first call and doesn't run again on the same
+  /// input.
+  void verifyMergedModuleOnce();
+
   bool compileOptimizedToFile(const char **Name);
   void restoreLinkageForExternals();
   void applyScopeRestrictions();
@@ -189,6 +205,7 @@ private:
   std::unique_ptr<TargetMachine> TargetMach;
   bool EmitDwarfDebugInfo = false;
   bool ScopeRestrictionsDone = false;
+  bool HasVerifiedInput = false;
   Reloc::Model RelocModel = Reloc::Default;
   StringSet<> MustPreserveSymbols;
   StringSet<> AsmUndefinedRefs;

Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=266894&r1=266893&r2=266894&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Wed Apr 20 12:48:22 2016
@@ -131,6 +131,9 @@ bool LTOCodeGenerator::addModule(LTOModu
   for (int i = 0, e = undefs.size(); i != e; ++i)
     AsmUndefinedRefs[undefs[i]] = 1;
 
+  // We've just changed the input, so let's make sure we verify it.
+  HasVerifiedInput = false;
+
   return !ret;
 }
 
@@ -146,6 +149,9 @@ void LTOCodeGenerator::setModule(std::un
   const std::vector<const char*> &Undefs = Mod->getAsmUndefinedRefs();
   for (int I = 0, E = Undefs.size(); I != E; ++I)
     AsmUndefinedRefs[Undefs[I]] = 1;
+
+  // We've just changed the input, so let's make sure we verify it.
+  HasVerifiedInput = false;
 }
 
 void LTOCodeGenerator::setTargetOptions(TargetOptions Options) {
@@ -187,6 +193,9 @@ bool LTOCodeGenerator::writeMergedModule
   if (!determineTarget())
     return false;
 
+  // We always run the verifier once on the merged module.
+  verifyMergedModuleOnce();
+
   // mark which symbols can not be internalized
   applyScopeRestrictions();
 
@@ -413,6 +422,16 @@ void LTOCodeGenerator::restoreLinkageFor
                 externalize);
 }
 
+void LTOCodeGenerator::verifyMergedModuleOnce() {
+  // Only run on the first call.
+  if (HasVerifiedInput)
+    return;
+  HasVerifiedInput = true;
+
+  if (verifyModule(*MergedModule, &dbgs()))
+    report_fatal_error("Broken module found, compilation aborted!");
+}
+
 /// Optimize merged modules using various IPO passes
 bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
                                 bool DisableGVNLoadPRE,
@@ -422,8 +441,7 @@ bool LTOCodeGenerator::optimize(bool Dis
 
   // We always run the verifier once on the merged module, the `DisableVerify`
   // parameter only applies to subsequent verify.
-  if (verifyModule(*MergedModule, &dbgs()))
-    report_fatal_error("Broken module found, compilation aborted!");
+  verifyMergedModuleOnce();
 
   // Mark which symbols can not be internalized
   this->applyScopeRestrictions();
@@ -461,6 +479,10 @@ bool LTOCodeGenerator::compileOptimized(
   if (!this->determineTarget())
     return false;
 
+  // We always run the verifier once on the merged module.  If it has already
+  // been called in optimize(), this call will return early.
+  verifyMergedModuleOnce();
+
   legacy::PassManager preCodeGenPasses;
 
   // If the bitcode files contain ARC code and were compiled with optimization,




More information about the llvm-commits mailing list