Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 754fc78

Browse files
[ForceFunctionAttrs] Fix handling of alwaysinline and noinline attributes. (#180026)
Address #152365 (comment)
1 parent 61c2432 commit 754fc78

2 files changed

Lines changed: 48 additions & 11 deletions

File tree

llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ static cl::opt<std::string> CSVFilePath(
4444
"Path to CSV file containing lines of function names and attributes to "
4545
"add to them in the form of `f1,attr1` or `f2,attr2=str`."));
4646

47+
static bool hasConflictingFnAttr(Attribute::AttrKind Kind, Function &F) {
48+
if (Kind == Attribute::AlwaysInline)
49+
return F.hasFnAttribute(Attribute::NoInline);
50+
if (Kind == Attribute::NoInline)
51+
return F.hasFnAttribute(Attribute::AlwaysInline);
52+
return false;
53+
}
54+
4755
/// If F has any forced attributes given on the command line, add them.
4856
/// If F has any forced remove attributes given on the command line, remove
4957
/// them. When both force and force-remove are given to a function, the latter
@@ -69,7 +77,8 @@ static void forceAttributes(Function &F) {
6977

7078
for (const auto &S : ForceAttributes) {
7179
auto Kind = ParseFunctionAndAttr(S);
72-
if (Kind == Attribute::None || F.hasFnAttribute(Kind))
80+
if (Kind == Attribute::None || F.hasFnAttribute(Kind) ||
81+
hasConflictingFnAttr(Kind, F))
7382
continue;
7483
F.addFnAttr(Kind);
7584
}
@@ -115,7 +124,8 @@ PreservedAnalyses ForceFunctionAttrsPass::run(Module &M,
115124
} else {
116125
auto AttrKind = Attribute::getAttrKindFromName(SplitPair.second);
117126
if (AttrKind != Attribute::None &&
118-
Attribute::canUseAsFnAttr(AttrKind)) {
127+
Attribute::canUseAsFnAttr(AttrKind) &&
128+
!hasConflictingFnAttr(AttrKind, *Func)) {
119129
// TODO: There could be string attributes without a value, we should
120130
// support those, too.
121131
Func->addFnAttr(AttrKind);

llvm/test/Transforms/ForcedFunctionAttrs/forced.ll

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
; RUN: opt < %s -S -passes=forceattrs | FileCheck %s --check-prefix=CHECK-CONTROL
2-
; RUN: opt < %s -S -passes=forceattrs -force-attribute foo:noinline | FileCheck %s --check-prefix=CHECK-FOO
3-
; RUN: opt < %s -S -passes=forceattrs -force-remove-attribute goo:cold | FileCheck %s --check-prefix=REMOVE-COLD
4-
; RUN: opt < %s -S -passes=forceattrs -force-remove-attribute goo:noinline | FileCheck %s --check-prefix=REMOVE-NOINLINE
5-
; RUN: opt < %s -S -passes=forceattrs -force-attribute goo:cold -force-remove-attribute goo:noinline | FileCheck %s --check-prefix=ADD-COLD-REMOVE-NOINLINE
6-
; RUN: opt < %s -S -passes=forceattrs -force-attribute goo:noinline -force-remove-attribute goo:noinline | FileCheck %s --check-prefix=ADD-NOINLINE-REMOVE-NOINLINE
7-
; RUN: opt < %s -S -passes=forceattrs -force-attribute optsize | FileCheck %s --check-prefix=CHECK-ADD-ALL
8-
; RUN: opt < %s -S -passes=forceattrs -force-remove-attribute noinline | FileCheck %s --check-prefix=CHECK-REMOVE-ALL
1+
; RUN: opt < %s -S -passes=verify,forceattrs,verify | FileCheck %s --check-prefix=CHECK-CONTROL
2+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-attribute foo:noinline | FileCheck %s --check-prefix=CHECK-FOO
3+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-remove-attribute goo:cold | FileCheck %s --check-prefix=REMOVE-COLD
4+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-remove-attribute goo:noinline | FileCheck %s --check-prefix=REMOVE-NOINLINE
5+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-attribute goo:cold -force-remove-attribute goo:noinline | FileCheck %s --check-prefix=ADD-COLD-REMOVE-NOINLINE
6+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-attribute goo:noinline -force-remove-attribute goo:noinline | FileCheck %s --check-prefix=ADD-NOINLINE-REMOVE-NOINLINE
7+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-attribute optsize | FileCheck %s --check-prefix=CHECK-ADD-ALL
8+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-remove-attribute noinline | FileCheck %s --check-prefix=CHECK-REMOVE-ALL
9+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-attribute alwaysinline | FileCheck %s --check-prefix=CHECK-ALWAYSINLINE-ALL
10+
; RUN: opt < %s -S -passes=verify,forceattrs,verify -force-attribute noinline | FileCheck %s --check-prefix=CHECK-NOINLINE-ALL
911

1012
; CHECK-CONTROL: define void @foo() {
1113
; CHECK-FOO: define void @foo() #0 {
@@ -29,7 +31,13 @@ define void @foo() {
2931
define void @goo() #0 {
3032
ret void
3133
}
34+
35+
define void @hoo() #1 {
36+
ret void
37+
}
38+
3239
attributes #0 = { noinline }
40+
attributes #1 = { alwaysinline }
3341

3442
; CHECK-FOO: attributes #0 = { noinline }
3543
; REMOVE-COLD: attributes #0 = { noinline }
@@ -39,13 +47,32 @@ attributes #0 = { noinline }
3947
; should be added to all functions in the module.
4048
; CHECK-ADD-ALL: define void @foo() #0 {
4149
; CHECK-ADD-ALL: define void @goo() #1 {
50+
; CHECK-ADD-ALL: define void @hoo() #2 {
4251
; CHECK-ADD-ALL: attributes #0 = { optsize }
4352
; CHECK-ADD-ALL: attributes #1 = { noinline optsize }
53+
; CHECK-ADD-ALL: attributes #2 = { alwaysinline optsize }
4454

4555
; When passing an attribute to be removed without specifying a function,
4656
; the attribute should be removed from all functions in the module that
4757
; have it.
4858
; CHECK-REMOVE-ALL: define void @foo() {
4959
; CHECK-REMOVE-ALL: define void @goo() {
50-
; CHECK-REMOVE-ALL-NOT: attributes #0
60+
; CHECK-REMOVE-ALL: define void @hoo() #0 {
61+
; CHECK-REMOVE-ALL: attributes #0 = { alwaysinline }
62+
63+
; When forcing alwaysinline on all functions, it should not be added to
64+
; functions that already have noinline (would produce invalid IR).
65+
; CHECK-ALWAYSINLINE-ALL: define void @foo() #0 {
66+
; CHECK-ALWAYSINLINE-ALL: define void @goo() #1 {
67+
; CHECK-ALWAYSINLINE-ALL: define void @hoo() #0 {
68+
; CHECK-ALWAYSINLINE-ALL-DAG: attributes #0 = { alwaysinline }
69+
; CHECK-ALWAYSINLINE-ALL-DAG: attributes #1 = { noinline }
70+
71+
; When forcing noinline on all functions, it should not be added to
72+
; functions that already have alwaysinline (would produce invalid IR).
73+
; CHECK-NOINLINE-ALL: define void @foo() #0 {
74+
; CHECK-NOINLINE-ALL: define void @goo() #0 {
75+
; CHECK-NOINLINE-ALL: define void @hoo() #1 {
76+
; CHECK-NOINLINE-ALL-DAG: attributes #0 = { noinline }
77+
; CHECK-NOINLINE-ALL-DAG: attributes #1 = { alwaysinline }
5178

0 commit comments

Comments
 (0)