summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/Verifier.h14
-rw-r--r--llvm/lib/IR/Verifier.cpp10
-rw-r--r--llvm/lib/LTO/LTOCodeGenerator.cpp20
-rw-r--r--llvm/test/LTO/X86/Inputs/strip-debug-info.bcbin0 -> 852 bytes
-rw-r--r--llvm/test/LTO/X86/strip-debug-info.ll20
5 files changed, 57 insertions, 7 deletions
diff --git a/llvm/include/llvm/IR/Verifier.h b/llvm/include/llvm/IR/Verifier.h
index 41a47226caf..70bec787a4c 100644
--- a/llvm/include/llvm/IR/Verifier.h
+++ b/llvm/include/llvm/IR/Verifier.h
@@ -41,10 +41,16 @@ bool verifyFunction(const Function &F, raw_ostream *OS = nullptr);
/// \brief Check a module for errors.
///
-/// If there are no errors, the function returns false. If an error is found,
-/// a message describing the error is written to OS (if non-null) and true is
-/// returned.
-bool verifyModule(const Module &M, raw_ostream *OS = nullptr);
+/// If there are no errors, the function returns false. If an error is
+/// found, a message describing the error is written to OS (if
+/// non-null) and true is returned.
+///
+/// \return true if the module is broken. If BrokenDebugInfo is
+/// supplied, DebugInfo verification failures won't be considered as
+/// error and instead *BrokenDebugInfo will be set to true. Debug
+/// info errors can be "recovered" from by stripping the debug info.
+bool verifyModule(const Module &M, raw_ostream *OS = nullptr,
+ bool *BrokenDebugInfo = nullptr);
/// \brief Create a verifier pass.
///
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 576aefdf29a..e09f763f10b 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4417,18 +4417,22 @@ bool llvm::verifyFunction(const Function &f, raw_ostream *OS) {
return !V.verify(F);
}
-bool llvm::verifyModule(const Module &M, raw_ostream *OS) {
+bool llvm::verifyModule(const Module &M, raw_ostream *OS,
+ bool *BrokenDebugInfo) {
// Don't use a raw_null_ostream. Printing IR is expensive.
- Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/true);
+ Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/!BrokenDebugInfo);
bool Broken = false;
for (const Function &F : M)
if (!F.isDeclaration() && !F.isMaterializable())
Broken |= !V.verify(F);
+ Broken |= !V.verify(M);
+ if (BrokenDebugInfo)
+ *BrokenDebugInfo = V.hasBrokenDebugInfo();
// Note that this function's return value is inverted from what you would
// expect of a function called "verify".
- return !V.verify(M) || Broken;
+ return Broken;
}
namespace {
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 226004a3353..0e1c46cff27 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -26,6 +26,7 @@
#include "llvm/Config/config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
@@ -78,6 +79,16 @@ cl::opt<bool> LTODiscardValueNames(
cl::init(false),
#endif
cl::Hidden);
+
+cl::opt<bool> LTOStripInvalidDebugInfo(
+ "lto-strip-invalid-debug-info",
+ cl::desc("Strip invalid debug info metadata during LTO instead of aborting."),
+#ifdef NDEBUG
+ cl::init(true),
+#else
+ cl::init(false),
+#endif
+ cl::Hidden);
}
LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
@@ -488,6 +499,15 @@ void LTOCodeGenerator::verifyMergedModuleOnce() {
return;
HasVerifiedInput = true;
+ if (LTOStripInvalidDebugInfo) {
+ bool BrokenDebugInfo = false;
+ if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo))
+ report_fatal_error("Broken module found, compilation aborted!");
+ if (BrokenDebugInfo) {
+ emitWarning("Invalid debug info found, debug info will be stripped");
+ StripDebugInfo(*MergedModule);
+ }
+ }
if (verifyModule(*MergedModule, &dbgs()))
report_fatal_error("Broken module found, compilation aborted!");
}
diff --git a/llvm/test/LTO/X86/Inputs/strip-debug-info.bc b/llvm/test/LTO/X86/Inputs/strip-debug-info.bc
new file mode 100644
index 00000000000..c83195ff9ca
--- /dev/null
+++ b/llvm/test/LTO/X86/Inputs/strip-debug-info.bc
Binary files differ
diff --git a/llvm/test/LTO/X86/strip-debug-info.ll b/llvm/test/LTO/X86/strip-debug-info.ll
new file mode 100644
index 00000000000..265a34b9c97
--- /dev/null
+++ b/llvm/test/LTO/X86/strip-debug-info.ll
@@ -0,0 +1,20 @@
+; RUN: not llvm-lto -lto-strip-invalid-debug-info=false \
+; RUN: -o %t.o %S/Inputs/strip-debug-info.bc 2>&1 | \
+; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-ERR
+; RUN: llvm-lto -lto-strip-invalid-debug-info=true -exported-symbol _foo \
+; RUN: -o %t.o %S/Inputs/strip-debug-info.bc 2>&1 | \
+; RUN: FileCheck %s -allow-empty -check-prefix=CHECK-WARN
+; RUN: llvm-nm %t.o | FileCheck %s
+
+; CHECK-ERR: Broken module found, compilation aborted
+; CHECK-WARN: Invalid debug info found, debug info will be stripped
+; CHECK: foo
+define void @foo() {
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{!1}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !DIFile(filename: "broken", directory: "")
OpenPOWER on IntegriCloud