diff --git a/llvm/include/llvm/Analysis/InlineAdvisor.h b/llvm/include/llvm/Analysis/InlineAdvisor.h --- a/llvm/include/llvm/Analysis/InlineAdvisor.h +++ b/llvm/include/llvm/Analysis/InlineAdvisor.h @@ -219,15 +219,16 @@ InlineAdvisorAnalysis() = default; struct Result { Result(Module &M, ModuleAnalysisManager &MAM) : M(M), MAM(MAM) {} - bool invalidate(Module &, const PreservedAnalyses &, + bool invalidate(Module &, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &) { - // InlineAdvisor must be preserved across analysis invalidations. - return false; + // Check whether the analysis has been explicitly invalidated. Otherwise, + // it's stateless and remains preserved. + auto PAC = PA.getChecker(); + return !PAC.preservedWhenStateless(); } bool tryCreate(InlineParams Params, InliningAdvisorMode Mode, StringRef ReplayFile); InlineAdvisor *getAdvisor() const { return Advisor.get(); } - void clear() { Advisor.reset(); } private: Module &M; diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -1048,10 +1048,11 @@ createDevirtSCCRepeatedPass(std::move(PM), MaxDevirtIterations))); MPM.run(M, MAM); - IAA.clear(); - - // The ModulePassManager has already taken care of invalidating analyses. - return PreservedAnalyses::all(); + // Discard the InlineAdvisor, a subsequent inlining session should construct + // its own. + auto PA = PreservedAnalyses::all(); + PA.abandon(); + return PA; } void InlinerPass::printPipeline( diff --git a/llvm/test/Transforms/Inline/pr52118.ll b/llvm/test/Transforms/Inline/pr52118.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/pr52118.ll @@ -0,0 +1,9 @@ +; Test that the InlineAdvisor, upon being cleared, is re-created correctly. +; RUN: opt -S -passes="default,cgscc(inline)" < %s | FileCheck %s + +define double @foo() local_unnamed_addr { +entry: + ret double undef +} + +; CHECK: @foo