From f0e6ec1547d40da07bcdccb0acc2eb7b2bd4ffd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Bolvansk=C3=BD?= Date: Mon, 14 Feb 2022 18:35:29 +0100 Subject: [PATCH] [Inliner] Respect noinline call site attribute ``` always_inline foo() { } bar () { noinline foo(); } ``` We should prefer call site attribute over attribute on decl. Related to https://reviews.llvm.org/D119061 Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D119579 --- llvm/lib/Analysis/InlineCost.cpp | 3 + .../test/Transforms/Inline/call-site-attrs.ll | 59 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 llvm/test/Transforms/Inline/call-site-attrs.ll diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index 5333626e3cf8..2a1a97622604 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -2864,6 +2864,9 @@ Optional llvm::getAttributeBasedInliningDecision( // Calls to functions with always-inline attributes should be inlined // whenever possible. if (Call.hasFnAttr(Attribute::AlwaysInline)) { + if (Call.getAttributes().hasFnAttr(Attribute::NoInline)) + return InlineResult::failure("noinline call site attribute"); + auto IsViable = isInlineViable(*Callee); if (IsViable.isSuccess()) return InlineResult::success(); diff --git a/llvm/test/Transforms/Inline/call-site-attrs.ll b/llvm/test/Transforms/Inline/call-site-attrs.ll new file mode 100644 index 000000000000..50af344a4c71 --- /dev/null +++ b/llvm/test/Transforms/Inline/call-site-attrs.ll @@ -0,0 +1,59 @@ +; RUN: opt < %s -inline -S | FileCheck %s +; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s + +; Always prefer call site attribute over function attribute + +define internal i32 @inner1() { +; CHECK: @inner1( + ret i32 1 +} + +define i32 @outer1() { +; CHECK-LABEL: @outer1( +; CHECK: call + + %r = call i32 @inner1() noinline + ret i32 %r +} + +define internal i32 @inner2() alwaysinline { +; CHECK: @inner2( + ret i32 1 +} + +define i32 @outer2() { +; CHECK-LABEL: @outer2( +; CHECK: call + + %r = call i32 @inner2() noinline + ret i32 %r +} + +define i32 @inner3() alwaysinline { +; CHECK: @inner3( + ret i32 1 +} + +define i32 @outer3() { +; CHECK-LABEL: @outer3( +; CHECK: call + + %r = call i32 @inner3() noinline + ret i32 %r +} + +define i32 @inner4() noinline { +; CHECK: @inner4( + ret i32 1 +} + +define i32 @outer4() { +; CHECK-LABEL: @outer4( +; CHECK-NOT: call +; CHECK: ret + + %r = call i32 @inner4() alwaysinline + + ret i32 %r +} +