diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index c45fb132685c2..5b18f45a04ab1 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -322,6 +322,8 @@ CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0) CODEGENOPT(VerifyModule , 1, 1) ///< Control whether the module should be run ///< through the LLVM Verifier. +CODEGENOPT(VerifyEach , 1, 1) ///< Control whether the LLVM verifier + ///< should run after every pass. CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to force stack ///< realignment. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 53c107b0f0fb0..b90d6763d6f3c 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5738,6 +5738,9 @@ def as_secure_log_file : Separate<["-"], "as-secure-log-file">, let Flags = [CC1Option, NoDriverOption] in { +def llvm_verify_each : Flag<["-"], "llvm-verify-each">, + HelpText<"Run the LLVM verifier after every LLVM pass">, + MarshallingInfoFlag>; def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">, HelpText<"Don't run the LLVM IR verifier pass">, MarshallingInfoNegativeFlag>; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 73cd4a62f5d3e..f7a174a5fe462 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -839,7 +839,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline( StandardInstrumentations SI( TheModule->getContext(), (CodeGenOpts.DebugPassManager || DebugPassStructure), - /*VerifyEach*/ false, PrintPassOpts); + CodeGenOpts.VerifyEach, PrintPassOpts); SI.registerCallbacks(PIC, &MAM); PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC); @@ -1192,6 +1192,7 @@ static void runThinLTOBackend( Conf.ProfileRemapping = std::move(ProfileRemapping); Conf.DebugPassManager = CGOpts.DebugPassManager; + Conf.VerifyEach = CGOpts.VerifyEach; Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness; Conf.RemarksFilename = CGOpts.OptRecordFile; Conf.RemarksPasses = CGOpts.OptRecordPasses; diff --git a/clang/test/CodeGen/verify-each.c b/clang/test/CodeGen/verify-each.c new file mode 100644 index 0000000000000..328b846508920 --- /dev/null +++ b/clang/test/CodeGen/verify-each.c @@ -0,0 +1,19 @@ +// Test to ensure -llvm-verify-each works. +// REQUIRES: x86-registered-target + +// RUN: %clang_cc1 -O2 -o /dev/null -triple x86_64-unknown-linux-gnu -emit-llvm-bc %s -fdebug-pass-manager 2>&1 | FileCheck %s --check-prefix=NO +// NO-NOT: Verifying + +// RUN: %clang_cc1 -O2 -o /dev/null -triple x86_64-unknown-linux-gnu -emit-llvm-bc %s -fdebug-pass-manager -llvm-verify-each 2>&1 | FileCheck %s + +// RUN: %clang_cc1 -O2 -o %t.o -flto=thin -triple x86_64-unknown-linux-gnu -emit-llvm-bc %s -fdebug-pass-manager -llvm-verify-each 2>&1 | FileCheck %s +// RUN: llvm-lto -thinlto -o %t %t.o + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O2 -o /dev/null -x ir %t.o -fthinlto-index=%t.thinlto.bc -fdebug-pass-manager -llvm-verify-each 2>&1 | FileCheck %s + +// CHECK: Verifying function foo +// CHECK: Running pass: InstCombinePass +// CHECK: Verifying function foo + +void foo(void) { +} diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index e3c25117a020f..5c23ba4f7ac49 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -57,6 +57,7 @@ struct Config { CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; CodeGenFileType CGFileType = CGFT_ObjectFile; unsigned OptLevel = 2; + bool VerifyEach = false; bool DisableVerify = false; /// Use the standard optimization pipeline. diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 667ebb0c43320..4d9077924c67d 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -259,7 +259,8 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, ModuleAnalysisManager MAM; PassInstrumentationCallbacks PIC; - StandardInstrumentations SI(Mod.getContext(), Conf.DebugPassManager); + StandardInstrumentations SI(Mod.getContext(), Conf.DebugPassManager, + Conf.VerifyEach); SI.registerCallbacks(PIC, &MAM); PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC);