[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
This commit is contained in:
Dávid Bolvanský 2022-02-14 18:35:29 +01:00
parent 3efdfe722d
commit f0e6ec1547
2 changed files with 62 additions and 0 deletions

View File

@ -2864,6 +2864,9 @@ Optional<InlineResult> 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();

View File

@ -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
}