diff --git a/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h b/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h index 1cab52b2cca82..0b93bbd6eaa2d 100644 --- a/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h +++ b/llvm/include/llvm/Transforms/IPO/FunctionAttrs.h @@ -48,8 +48,16 @@ bool thinLTOPropagateFunctionAttrs( /// attribute. It also discovers function arguments that are not captured by /// the function and marks them with the nocapture attribute. struct PostOrderFunctionAttrsPass : PassInfoMixin { + PostOrderFunctionAttrsPass(bool SkipNonRecursive = false) + : SkipNonRecursive(SkipNonRecursive) {} PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR); + + void printPipeline(raw_ostream &OS, + function_ref MapClassName2PassName); + +private: + bool SkipNonRecursive; }; /// A pass to do RPO deduction and propagation of function attributes. diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp index 2de19884014c3..6c2db5bd11e50 100644 --- a/llvm/lib/Analysis/CGSCCPassManager.cpp +++ b/llvm/lib/Analysis/CGSCCPassManager.cpp @@ -545,8 +545,6 @@ PreservedAnalyses CGSCCToFunctionPassAdaptor::run(LazyCallGraph::SCC &C, // function's analyses (that's the contract of a function pass), so // directly handle the function analysis manager's invalidation here. FAM.invalidate(F, EagerlyInvalidate ? PreservedAnalyses::none() : PassPA); - if (NoRerun) - (void)FAM.getResult(F); // Then intersect the preserved set so that invalidation of module // analyses will eventually occur when the module pass completes. diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index e68d94ddbf8eb..38e79eb7fac39 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -657,6 +657,11 @@ Expected parseCoroSplitPassOptions(StringRef Params) { return parseSinglePassOption(Params, "reuse-storage", "CoroSplitPass"); } +Expected parsePostOrderFunctionAttrsPassOptions(StringRef Params) { + return parseSinglePassOption(Params, "skip-non-recursive", + "PostOrderFunctionAttrs"); +} + Expected parseEarlyCSEPassOptions(StringRef Params) { return parseSinglePassOption(Params, "memssa", "EarlyCSE"); } diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index adb555ed21b9d..4021ece4990d7 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -831,8 +831,11 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level, if (AttributorRun & AttributorRunOption::CGSCC) MainCGPipeline.addPass(AttributorCGSCCPass()); - // Now deduce any function attributes based in the current code. - MainCGPipeline.addPass(PostOrderFunctionAttrsPass()); + // Deduce function attributes. We do another run of this after the function + // simplification pipeline, so this only needs to run when it could affect the + // function simplification pipeline, which is only the case with recursive + // functions. + MainCGPipeline.addPass(PostOrderFunctionAttrsPass(/*SkipNonRecursive*/ true)); // When at O3 add argument promotion to the pass pipeline. // FIXME: It isn't at all clear why this should be limited to O3. @@ -847,14 +850,25 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level, for (auto &C : CGSCCOptimizerLateEPCallbacks) C(MainCGPipeline, Level); - // Lastly, add the core function simplification pipeline nested inside the + // Add the core function simplification pipeline nested inside the // CGSCC walk. MainCGPipeline.addPass(createCGSCCToFunctionPassAdaptor( buildFunctionSimplificationPipeline(Level, Phase), PTO.EagerlyInvalidateAnalyses, /*NoRerun=*/true)); + // Finally, deduce any function attributes based on the fully simplified + // function. + MainCGPipeline.addPass(PostOrderFunctionAttrsPass()); + + // Mark that the function is fully simplified and that it shouldn't be + // simplified again if we somehow revisit it due to CGSCC mutations unless + // it's been modified since. + MainCGPipeline.addPass(createCGSCCToFunctionPassAdaptor( + RequireAnalysisPass())); + MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0)); + // Make sure we don't affect potential future NoRerun CGSCC adaptors. MIWP.addLateModulePass(createModuleToFunctionPassAdaptor( InvalidateAnalysisPass())); diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 36700574c1663..04d648580a8c5 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -184,7 +184,6 @@ CGSCC_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC)) #endif CGSCC_PASS("argpromotion", ArgumentPromotionPass()) CGSCC_PASS("invalidate", InvalidateAllAnalysesPass()) -CGSCC_PASS("function-attrs", PostOrderFunctionAttrsPass()) CGSCC_PASS("attributor-cgscc", AttributorCGSCCPass()) CGSCC_PASS("openmp-opt-cgscc", OpenMPOptCGSCCPass()) CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass()) @@ -207,6 +206,13 @@ CGSCC_PASS_WITH_PARAMS("coro-split", }, parseCoroSplitPassOptions, "reuse-storage") +CGSCC_PASS_WITH_PARAMS("function-attrs", + "PostOrderFunctionAttrsPass", + [](bool SkipNonRecursive) { + return PostOrderFunctionAttrsPass(SkipNonRecursive); + }, + parsePostOrderFunctionAttrsPassOptions, + "skip-non-recursive") #undef CGSCC_PASS_WITH_PARAMS #ifndef FUNCTION_ANALYSIS diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 68a4860dc1902..9d87ce5714e52 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -1763,6 +1763,13 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &) { + // Skip non-recursive functions if requested. + if (C.size() == 1 && SkipNonRecursive) { + LazyCallGraph::Node &N = *C.begin(); + if (!N->lookup(N)) + return PreservedAnalyses::all(); + } + FunctionAnalysisManager &FAM = AM.getResult(C, CG).getManager(); @@ -1808,6 +1815,14 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C, return PA; } +void PostOrderFunctionAttrsPass::printPipeline( + raw_ostream &OS, function_ref MapClassName2PassName) { + static_cast *>(this)->printPipeline( + OS, MapClassName2PassName); + if (SkipNonRecursive) + OS << ""; +} + template static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter) { SmallVector Functions; diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll index 8b2bc4c84bcad..cdf136ee20d06 100644 --- a/llvm/test/Other/new-pm-defaults.ll +++ b/llvm/test/Other/new-pm-defaults.ll @@ -139,7 +139,6 @@ ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass -; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass on (foo) ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass on (foo) @@ -147,6 +146,7 @@ ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -214,6 +214,8 @@ ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-EP-PEEPHOLE-NEXT: Running pass: NoOpFunctionPass +; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis diff --git a/llvm/test/Other/new-pm-print-pipeline.ll b/llvm/test/Other/new-pm-print-pipeline.ll index 3ddc3698ea175..c72d52c97e4cc 100644 --- a/llvm/test/Other/new-pm-print-pipeline.ll +++ b/llvm/test/Other/new-pm-print-pipeline.ll @@ -97,3 +97,7 @@ ;; Test InstCombine options - the first pass checks default settings, and the second checks customized options. ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(instcombine,instcombine)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-28 ; CHECK-28: function(instcombine,instcombine) + +;; Test function-attrs +; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='cgscc(function-attrs)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-29 +; CHECK-29: cgscc(function-attrs) diff --git a/llvm/test/Other/new-pm-thinlto-defaults.ll b/llvm/test/Other/new-pm-thinlto-defaults.ll index 6d73544b191c0..6b4c44d011f93 100644 --- a/llvm/test/Other/new-pm-thinlto-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-defaults.ll @@ -116,13 +116,13 @@ ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass -; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass on (foo) ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass on (foo) ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -184,6 +184,8 @@ ; CHECK-O23SZ-NEXT: Running pass: CoroElidePass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll index fddb16e387f60..77220c1d1bece 100644 --- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll @@ -79,13 +79,13 @@ ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass -; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -145,6 +145,8 @@ ; CHECK-O23SZ-NEXT: Running pass: CoroElidePass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll index eb79d471eea97..8b0ea1a1d21af 100644 --- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll @@ -88,13 +88,13 @@ ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass -; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -154,6 +154,8 @@ ; CHECK-O23SZ-NEXT: Running pass: CoroElidePass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis diff --git a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll index 4153502b5180b..2eac9825bcb22 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll @@ -103,20 +103,20 @@ ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass -; CHECK-O-NEXT: Running analysis: AAManager -; CHECK-O-NEXT: Running analysis: BasicAA -; CHECK-O-NEXT: Running analysis: AssumptionAnalysis -; CHECK-O-NEXT: Running analysis: TargetIRAnalysis -; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis -; CHECK-O-NEXT: Running analysis: ScopedNoAliasAA -; CHECK-O-NEXT: Running analysis: TypeBasedAA -; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O-NEXT: Running pass: SROAPass +; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis +; CHECK-O-NEXT: Running analysis: AssumptionAnalysis +; CHECK-O-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running analysis: AAManager +; CHECK-O-NEXT: Running analysis: BasicAA +; CHECK-O-NEXT: Running analysis: ScopedNoAliasAA +; CHECK-O-NEXT: Running analysis: TypeBasedAA +; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -184,6 +184,8 @@ ; CHECK-O23SZ-NEXT: Running pass: CoroElidePass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis diff --git a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll index 663af16ae836f..f1ed2f3086ab4 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll @@ -83,13 +83,13 @@ ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass -; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -148,6 +148,8 @@ ; CHECK-O23SZ-NEXT: Running pass: CoroElidePass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis diff --git a/llvm/test/Transforms/InstCombine/unused-nonnull.ll b/llvm/test/Transforms/InstCombine/unused-nonnull.ll index 32dd65977ea86..169cab455f606 100644 --- a/llvm/test/Transforms/InstCombine/unused-nonnull.ll +++ b/llvm/test/Transforms/InstCombine/unused-nonnull.ll @@ -9,7 +9,7 @@ target triple = "x86_64-unknown-linux-gnu" define i32 @main(i32 %argc, ptr %argv) #0 { ; CHECK-LABEL: define {{[^@]+}}@main -; CHECK-SAME: (i32 [[ARGC:%.*]], ptr nocapture readonly [[ARGV:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +; CHECK-SAME: (i32 [[ARGC:%.*]], ptr nocapture readnone [[ARGV:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[ARGC]], 2 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i32 0, i32 [[ARGC]] diff --git a/llvm/test/Transforms/PhaseOrdering/func-attrs.ll b/llvm/test/Transforms/PhaseOrdering/func-attrs.ll index 64b33e794ed8e..187e32afe00a3 100644 --- a/llvm/test/Transforms/PhaseOrdering/func-attrs.ll +++ b/llvm/test/Transforms/PhaseOrdering/func-attrs.ll @@ -16,7 +16,7 @@ define internal i32 @h2(i32 %a, i32 %b) { } define void @f(i32 %a, i32 %b) noinline { -; CHECK: Function Attrs: noinline +; CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: @f( ; CHECK-NEXT: end: ; CHECK-NEXT: ret void