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 @@ -1063,63 +1063,80 @@ const LangOptions &LangOpts, PassBuilder &PB) { PB.registerOptimizerLastEPCallback([&](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) { - if (CodeGenOpts.SanitizeCoverageType || - CodeGenOpts.SanitizeCoverageIndirectCalls || - CodeGenOpts.SanitizeCoverageTraceCmp) { - auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts); - MPM.addPass(ModuleSanitizerCoveragePass( - SancovOpts, CodeGenOpts.SanitizeCoverageAllowlistFiles, - CodeGenOpts.SanitizeCoverageBlocklistFiles)); - } - - auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) { - if (LangOpts.Sanitize.has(Mask)) { - int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins; - bool Recover = CodeGenOpts.SanitizeRecover.has(Mask); - - MPM.addPass( - MemorySanitizerPass({TrackOrigins, Recover, CompileKernel})); - MPM.addPass(createModuleToFunctionPassAdaptor( - MemorySanitizerPass({TrackOrigins, Recover, CompileKernel}))); - } - }; - MSanPass(SanitizerKind::Memory, false); - MSanPass(SanitizerKind::KernelMemory, true); - - if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { - MPM.addPass(ThreadSanitizerPass()); - MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); - } - - auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) { - if (LangOpts.Sanitize.has(Mask)) { - bool Recover = CodeGenOpts.SanitizeRecover.has(Mask); - bool UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope; - bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts); - bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator; - MPM.addPass(RequireAnalysisPass()); - MPM.addPass(ModuleAddressSanitizerPass( - CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator)); - MPM.addPass(createModuleToFunctionPassAdaptor( - AddressSanitizerPass(CompileKernel, Recover, UseAfterScope))); - } - }; - ASanPass(SanitizerKind::Address, false); - ASanPass(SanitizerKind::KernelAddress, true); + PB.registerOptimizerLastEPCallback( + [&](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) { + if (CodeGenOpts.OptimizationLevel == 0) { + if (!CodeGenOpts.ThinLTOIndexFile.empty()) + llvm::report_fatal_error( + "Unexpected optimizer in non-optimized ThinLTO PostLink"); + } else { + if (CodeGenOpts.PrepareForThinLTO) + llvm::report_fatal_error( + "Unexpected optimizer in optimized ThinLTO PreLink"); + } + + if (CodeGenOpts.SanitizeCoverageType || + CodeGenOpts.SanitizeCoverageIndirectCalls || + CodeGenOpts.SanitizeCoverageTraceCmp) { + auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts); + MPM.addPass(ModuleSanitizerCoveragePass( + SancovOpts, CodeGenOpts.SanitizeCoverageAllowlistFiles, + CodeGenOpts.SanitizeCoverageBlocklistFiles)); + } + + auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) { + if (LangOpts.Sanitize.has(Mask)) { + int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins; + bool Recover = CodeGenOpts.SanitizeRecover.has(Mask); - auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) { - if (LangOpts.Sanitize.has(Mask)) { - bool Recover = CodeGenOpts.SanitizeRecover.has(Mask); - MPM.addPass(HWAddressSanitizerPass(CompileKernel, Recover)); - } - }; - HWASanPass(SanitizerKind::HWAddress, false); - HWASanPass(SanitizerKind::KernelHWAddress, true); - - if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) { - MPM.addPass(DataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles)); - } - }); + MPM.addPass( + MemorySanitizerPass({TrackOrigins, Recover, CompileKernel})); + MPM.addPass(createModuleToFunctionPassAdaptor( + MemorySanitizerPass({TrackOrigins, Recover, CompileKernel}))); + } + }; + MSanPass(SanitizerKind::Memory, false); + MSanPass(SanitizerKind::KernelMemory, true); + + if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { + MPM.addPass(ThreadSanitizerPass()); + MPM.addPass( + createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); + } + + auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) { + if (LangOpts.Sanitize.has(Mask)) { + bool Recover = CodeGenOpts.SanitizeRecover.has(Mask); + bool UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope; + bool ModuleUseAfterScope = + asanUseGlobalsGC(TargetTriple, CodeGenOpts); + bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator; + MPM.addPass( + RequireAnalysisPass()); + MPM.addPass(ModuleAddressSanitizerPass(CompileKernel, Recover, + ModuleUseAfterScope, + UseOdrIndicator)); + MPM.addPass(createModuleToFunctionPassAdaptor( + AddressSanitizerPass(CompileKernel, Recover, UseAfterScope))); + } + }; + ASanPass(SanitizerKind::Address, false); + ASanPass(SanitizerKind::KernelAddress, true); + + auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) { + if (LangOpts.Sanitize.has(Mask)) { + bool Recover = CodeGenOpts.SanitizeRecover.has(Mask); + MPM.addPass(HWAddressSanitizerPass(CompileKernel, Recover)); + } + }; + HWASanPass(SanitizerKind::HWAddress, false); + HWASanPass(SanitizerKind::KernelHWAddress, true); + + if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) { + MPM.addPass( + DataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles)); + } + }); } /// A clean version of `EmitAssembly` that uses the new pass manager. @@ -1313,7 +1330,12 @@ FPM.addPass(BoundsCheckingPass()); }); - addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB); + if (CodeGenOpts.OptimizationLevel != 0 || + CodeGenOpts.ThinLTOIndexFile.empty()) { + // This is testing distributed ThinLTO PostLink. O0 called optimized in + // PreLink. + addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB); + } if (Optional Options = getGCOVOptions(CodeGenOpts, LangOpts)) PB.registerPipelineStartEPCallback( @@ -1522,6 +1544,10 @@ Conf.CGFileType = getCodeGenFileType(Action); break; } + Triple TargetTriple(M->getTargetTriple()); + Conf.OptimizerLastPassBuilderHook = [&](PassBuilder &PB) { + addSanitizers(TargetTriple, CGOpts, LOpts, PB); + }; if (Error E = thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList, ModuleToDefinedGVSummaries[M->getModuleIdentifier()], diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -48,7 +48,9 @@ TargetOptions Options; std::vector MAttrs; std::vector PassPlugins; - /// For adding passes that run right before codegen. + /// For adding passes that run by optimizer. + std::function OptimizerLastPassBuilderHook; + /// For adding passes that run right before codegen (NewPM only). std::function PreCodeGenPassesHook; Optional RelocModel = Reloc::PIC_; Optional CodeModel = None; diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -253,6 +253,9 @@ PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + if (Conf.OptimizerLastPassBuilderHook) + Conf.OptimizerLastPassBuilderHook(PB); + ModulePassManager MPM(Conf.DebugPassManager); if (!Conf.DisableVerify)