Skip to content

Commit d828281

Browse files
[AlwaysInliner] Respect noinline call site attribute
``` always_inline foo() { } bar () { noinline foo(); } ``` We should prefer call site attribute over attribute on decl. This is fix for AlwaysInliner, similar fix is needed for normal Inliner (follow up). Related to https://reviews.llvm.org/D119061 Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D119553
1 parent 8224114 commit d828281

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

llvm/lib/Transforms/IPO/AlwaysInliner.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===- InlineAlways.cpp - Code to inline always_inline functions ----------===//
1+
//===- AlwaysInliner.cpp - Code to inline always_inline functions ----------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -59,9 +59,16 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
5959

6060
for (User *U : F.users())
6161
if (auto *CB = dyn_cast<CallBase>(U))
62-
if (CB->getCalledFunction() == &F &&
63-
CB->hasFnAttr(Attribute::AlwaysInline))
64-
Calls.insert(CB);
62+
if (CB->getCalledFunction() == &F) {
63+
if (F.hasFnAttribute(Attribute::AlwaysInline)) {
64+
// Avoid inlining if noinline call site attribute.
65+
if (!CB->isNoInline())
66+
Calls.insert(CB);
67+
} else if (CB->hasFnAttr(Attribute::AlwaysInline)) {
68+
// Ok, alwaysinline call site attribute.
69+
Calls.insert(CB);
70+
}
71+
}
6572

6673
for (CallBase *CB : Calls) {
6774
Function *Caller = CB->getCaller();
@@ -210,6 +217,9 @@ InlineCost AlwaysInlinerLegacyPass::getInlineCost(CallBase &CB) {
210217
if (!CB.hasFnAttr(Attribute::AlwaysInline))
211218
return InlineCost::getNever("no alwaysinline attribute");
212219

220+
if (Callee->hasFnAttribute(Attribute::AlwaysInline) && CB.isNoInline())
221+
return InlineCost::getNever("noinline call site attribute");
222+
213223
auto IsViable = isInlineViable(*Callee);
214224
if (!IsViable.isSuccess())
215225
return InlineCost::getNever(IsViable.getFailureReason());

llvm/test/Transforms/Inline/always-inline.ll

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,57 @@ define void @outer14() {
314314
call void @inner14()
315315
ret void
316316
}
317+
318+
define internal i32 @inner15() {
319+
; CHECK: @inner15(
320+
ret i32 1
321+
}
322+
323+
define i32 @outer15() {
324+
; CHECK-LABEL: @outer15(
325+
; CHECK: call
326+
327+
%r = call i32 @inner15() noinline
328+
ret i32 %r
329+
}
330+
331+
define internal i32 @inner16() alwaysinline {
332+
; CHECK: @inner16(
333+
ret i32 1
334+
}
335+
336+
define i32 @outer16() {
337+
; CHECK-LABEL: @outer16(
338+
; CHECK: call
339+
340+
%r = call i32 @inner16() noinline
341+
ret i32 %r
342+
}
343+
344+
define i32 @inner17() alwaysinline {
345+
; CHECK: @inner17(
346+
ret i32 1
347+
}
348+
349+
define i32 @outer17() {
350+
; CHECK-LABEL: @outer17(
351+
; CHECK: call
352+
353+
%r = call i32 @inner17() noinline
354+
ret i32 %r
355+
}
356+
357+
define i32 @inner18() noinline {
358+
; CHECK: @inner18(
359+
ret i32 1
360+
}
361+
362+
define i32 @outer18() {
363+
; CHECK-LABEL: @outer18(
364+
; CHECK-NOT: call
365+
; CHECK: ret
366+
367+
%r = call i32 @inner18() alwaysinline
368+
369+
ret i32 %r
370+
}

0 commit comments

Comments
 (0)