diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -190,6 +190,10 @@ /// The ABI to use for passing floating point arguments. std::string FloatABI; + /// The file to use for dumping bug report by `Debugify` for original + /// debug info. + std::string DIBugsReportFilePath; + /// The floating-point denormal mode to use. llvm::DenormalMode FPDenormalMode = llvm::DenormalMode::getIEEE(); diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -70,6 +70,10 @@ CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled. CODEGENOPT(EmitCallSiteInfo, 1, 0) ///< Emit call site info only in the case of ///< '-g' + 'O>0' level. +CODEGENOPT(EnableDIPreservationVerify, 1, 0) ///< Enable di preservation verify + ///< each (it means check + ///< the original debug info + ///< metadata preservation). CODEGENOPT(IndirectTlsSegRefs, 1, 0) ///< Set when -mno-tls-direct-seg-refs ///< is specified. CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls. diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -342,6 +342,10 @@ def warn_drv_object_size_disabled_O0 : Warning< "the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">, InGroup, DefaultWarnNoWerror; +def warn_ignoring_verify_debuginfo_preserve_export : Warning< + "ignoring -fverify-debuginfo-preserve-export=%0 because " + "-fverify-debuginfo-preserve wasn't enabled">, + InGroup; def err_invalid_branch_protection: Error < "invalid branch protection option '%0' in '%1'">; def err_invalid_sls_hardening : Error< diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4877,6 +4877,18 @@ "fexperimental-debug-variable-locations">, HelpText<"Use experimental new value-tracking variable locations">, MarshallingInfoFlag>; +def fverify_debuginfo_preserve + : Flag<["-"], "fverify-debuginfo-preserve">, + HelpText<"Enable Debug Info Metadata preservation testing in " + "optimizations.">, + MarshallingInfoFlag>; +def fverify_debuginfo_preserve_export + : Joined<["-"], "fverify-debuginfo-preserve-export=">, + MetaVarName<"">, + HelpText<"Export debug info (by testing original Debug Info) failures " + "into specified (JSON) file (should be abs path as we use " + "append mode to insert new JSON objects).">, + MarshallingInfoString>; // The driver option takes the key as a parameter to the -msign-return-address= // and -mbranch-protection= options, but CC1 has a separate option so we // don't have to parse the parameter twice. diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -81,6 +81,7 @@ #include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h" #include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/CanonicalizeAliases.h" +#include "llvm/Transforms/Utils/Debugify.h" #include "llvm/Transforms/Utils/EntryExitInstrumenter.h" #include "llvm/Transforms/Utils/NameAnonGlobals.h" #include "llvm/Transforms/Utils/SymbolRewriter.h" @@ -945,7 +946,16 @@ if (TM) TheModule->setDataLayout(TM->createDataLayout()); - legacy::PassManager PerModulePasses; + DebugifyCustomPassManager PerModulePasses; + DebugInfoPerPassMap DIPreservationMap; + if (CodeGenOpts.EnableDIPreservationVerify) { + PerModulePasses.setDebugifyMode(DebugifyMode::OriginalDebugInfo); + PerModulePasses.setDIPreservationMap(DIPreservationMap); + + if (!CodeGenOpts.DIBugsReportFilePath.empty()) + PerModulePasses.setOrigDIVerifyBugsReportFilePath( + CodeGenOpts.DIBugsReportFilePath); + } PerModulePasses.add( createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1648,6 +1648,12 @@ llvm::is_contained(DebugEntryValueArchs, T.getArch())) Opts.EmitCallSiteInfo = true; + if (!Opts.EnableDIPreservationVerify && Opts.DIBugsReportFilePath.size()) { + Diags.Report(diag::warn_ignoring_verify_debuginfo_preserve_export) + << Opts.DIBugsReportFilePath; + Opts.DIBugsReportFilePath = ""; + } + Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) && Args.hasArg(OPT_new_struct_path_tbaa); Opts.OptimizeSize = getOptimizationLevelSize(Args); diff --git a/clang/test/Driver/verify-debug-info-preservation.c b/clang/test/Driver/verify-debug-info-preservation.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/verify-debug-info-preservation.c @@ -0,0 +1,19 @@ +// We support the CC1 options for testing whether each LLVM pass preserves +// original debug info. + +// RUN: %clang -g -Xclang -fverify-debuginfo-preserve -### %s 2>&1 \ +// RUN: | FileCheck --check-prefix=VERIFYDIPRESERVE %s + +// VERIFYDIPRESERVE: "-fverify-debuginfo-preserve" + +// RUN: %clang -g -Xclang -fverify-debuginfo-preserve \ +// RUN: -Xclang -fverify-debuginfo-preserve-export=%t.json -### %s 2>&1 \ +// RUN: | FileCheck --check-prefix=VERIFYDIPRESERVE-JSON-EXPORT %s + +// VERIFYDIPRESERVE-JSON-EXPORT: "-fverify-debuginfo-preserve" +// VERIFYDIPRESERVE-JSON-EXPORT: "-fverify-debuginfo-preserve-export={{.*}}" + +// RUN: %clang -g -Xclang -fverify-debuginfo-preserve-export=%t.json %s -S 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN %s + +// WARN: warning: ignoring -fverify-debuginfo-preserve-export diff --git a/llvm/docs/HowToUpdateDebugInfo.rst b/llvm/docs/HowToUpdateDebugInfo.rst --- a/llvm/docs/HowToUpdateDebugInfo.rst +++ b/llvm/docs/HowToUpdateDebugInfo.rst @@ -376,6 +376,17 @@ $ llvm-original-di-preservation.py sample.json sample.html +Testing of original debug info preservation can be invoked from front-end level +as follows: + +.. code-block:: bash + + # Test each pass. + $ clang -Xclang -fverify-debuginfo-preserve -g -O2 sample.c + + # Test each pass and export the issues report into the JSON file. + $ clang -Xclang -fverify-debuginfo-preserve -Xclang -fverify-debuginfo-preserve-export=sample.json -g -O2 sample.c + Mutation testing for MIR-level transformations ----------------------------------------------