Skip to content

Commit 4e952ed

Browse files
committed
Added test option to avoid using full lto pipeline, updated tests accordingly
1 parent 74225b6 commit 4e952ed

File tree

7 files changed

+207
-138
lines changed

7 files changed

+207
-138
lines changed

llvm/lib/Transforms/IPO/FunctionAttrs.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ static cl::opt<bool> DisableThinLTOPropagation(
109109
"disable-thinlto-funcattrs", cl::init(true), cl::Hidden,
110110
cl::desc("Don't propagate function-attrs in thinLTO"));
111111

112+
static cl::opt<bool> ForceLTOFuncAttrs(
113+
"force-lto-funcattrs", cl::init(false), cl::Hidden,
114+
cl::desc("Force LTO behaviour for function-attrs pass. Intended for testing"
115+
"purposes only"));
116+
112117
static void addCapturesStat(CaptureInfo CI) {
113118
if (capturesNothing(CI))
114119
++NumCapturesNone;
@@ -2334,7 +2339,7 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
23342339
// We use this information when inferring norecurse attribute: If there is
23352340
// no function whose address is taken and all functions have internal
23362341
// linkage, there is no path for a callback to any user function.
2337-
if (IsLTOPostLink) {
2342+
if (IsLTOPostLink || ForceLTOFuncAttrs) {
23382343
bool AnyFunctionsAddressIsTaken = false;
23392344
// Get the parent Module of the Function
23402345
Module &M = *C.begin()->getFunction().getParent();
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 5
2+
; RUN: opt < %s -passes=function-attrs -force-lto-funcattrs -S | FileCheck %s
3+
4+
; This test includes a call to a library function which is not marked as
5+
; NoCallback. All functions except main() are internal and main is marked
6+
; norecurse, so as to not block norecurse to be added to bob().
7+
8+
@.str = private unnamed_addr constant [12 x i8] c"Hello World\00", align 1
9+
10+
; Function Attrs: nofree noinline nounwind uwtable
11+
define internal void @bob() #0 {
12+
; CHECK: Function Attrs: nofree noinline norecurse nounwind uwtable
13+
; CHECK-LABEL: define internal void @bob(
14+
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
15+
; CHECK-NEXT: [[ENTRY:.*:]]
16+
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str)
17+
; CHECK-NEXT: ret void
18+
;
19+
entry:
20+
%call = tail call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str)
21+
ret void
22+
}
23+
24+
; Function Attrs: nofree nounwind
25+
declare noundef i32 @printf(ptr noundef readonly captures(none), ...) local_unnamed_addr #1
26+
27+
; Function Attrs: nofree norecurse nounwind uwtable
28+
define dso_local noundef i32 @main() #2 {
29+
; CHECK: Function Attrs: nofree norecurse nounwind uwtable
30+
; CHECK-LABEL: define dso_local noundef i32 @main(
31+
; CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
32+
; CHECK-NEXT: [[ENTRY:.*:]]
33+
; CHECK-NEXT: tail call void @bob()
34+
; CHECK-NEXT: ret i32 0
35+
;
36+
entry:
37+
tail call void @bob()
38+
ret i32 0
39+
}
40+
41+
attributes #0 = { nofree noinline nounwind uwtable }
42+
attributes #1 = { nofree nounwind }
43+
attributes #2 = { nofree norecurse nounwind uwtable }
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 5
2+
; RUN: opt < %s -passes=function-attrs -force-lto-funcattrs -S | FileCheck %s
3+
4+
; This test includes a call to a library function which is not marked as
5+
; NoCallback. Function bob() does not have internal linkage and hence prevents
6+
; norecurse to be added.
7+
8+
@.str = private unnamed_addr constant [12 x i8] c"Hello World\00", align 1
9+
10+
; Function Attrs: nofree noinline nounwind uwtable
11+
define dso_local void @bob() #0 {
12+
; CHECK: Function Attrs: nofree noinline nounwind uwtable
13+
; CHECK-LABEL: define dso_local void @bob(
14+
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
15+
; CHECK-NEXT: [[ENTRY:.*:]]
16+
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str)
17+
; CHECK-NEXT: ret void
18+
;
19+
entry:
20+
%call = tail call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str)
21+
ret void
22+
}
23+
24+
; Function Attrs: nofree nounwind
25+
declare noundef i32 @printf(ptr noundef readonly captures(none), ...) local_unnamed_addr #1
26+
27+
; Function Attrs: nofree norecurse nounwind uwtable
28+
define dso_local noundef i32 @main() #2 {
29+
; CHECK: Function Attrs: nofree norecurse nounwind uwtable
30+
; CHECK-LABEL: define dso_local noundef i32 @main(
31+
; CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
32+
; CHECK-NEXT: [[ENTRY:.*:]]
33+
; CHECK-NEXT: tail call void @bob()
34+
; CHECK-NEXT: ret i32 0
35+
;
36+
entry:
37+
tail call void @bob()
38+
ret i32 0
39+
}
40+
41+
attributes #0 = { nofree noinline nounwind uwtable }
42+
attributes #1 = { nofree nounwind }
43+
attributes #2 = { nofree norecurse nounwind uwtable }

llvm/test/Transforms/FunctionAttrs/norecurse_lto.ll

Lines changed: 0 additions & 36 deletions
This file was deleted.
Lines changed: 61 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,68 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 5
2-
; RUN: opt < %s -passes="lto<O2>" -S | FileCheck %s
2+
; RUN: opt < %s -passes=function-attrs -force-lto-funcattrs -S | FileCheck %s
33

44
; This test includes a call graph with multiple SCCs. The purpose of this is
55
; to check that norecurse is not added when a function is part of non-singular
66
; SCC.
77
; There are three different SCCs in this test:
8-
; SCC#1: main, foo, bar, foo1, bar1
8+
; SCC#1: f1, foo, bar, foo1, bar1
99
; SCC#2: bar2, bar3, bar4
1010
; SCC#3: baz, fun
1111
; None of these functions should be marked as norecurse
1212

1313
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
14-
define internal void @bar1() local_unnamed_addr #0 {
14+
define internal void @bar1() #0 {
1515
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
16-
; CHECK-LABEL: define internal fastcc void @bar1(
17-
; CHECK-SAME: ) unnamed_addr #[[ATTR0:[0-9]+]] {
16+
; CHECK-LABEL: define internal void @bar1(
17+
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
1818
; CHECK-NEXT: [[ENTRY:.*:]]
19-
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @main()
19+
; CHECK-NEXT: tail call void @f1()
2020
; CHECK-NEXT: ret void
2121
;
2222
entry:
23-
%call = tail call i32 @main()
23+
tail call void @f1()
2424
ret void
2525
}
2626

2727
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
28-
define dso_local noundef i32 @main() local_unnamed_addr #0 {
28+
define internal void @f1() #0 {
2929
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
30-
; CHECK-LABEL: define dso_local noundef i32 @main(
31-
; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
30+
; CHECK-LABEL: define internal void @f1(
31+
; CHECK-SAME: ) #[[ATTR0]] {
3232
; CHECK-NEXT: [[ENTRY:.*:]]
33-
; CHECK-NEXT: tail call fastcc void @foo()
34-
; CHECK-NEXT: tail call fastcc void @bar2()
35-
; CHECK-NEXT: tail call fastcc void @baz()
36-
; CHECK-NEXT: ret i32 0
33+
; CHECK-NEXT: tail call void @foo()
34+
; CHECK-NEXT: tail call void @bar2()
35+
; CHECK-NEXT: tail call void @baz()
36+
; CHECK-NEXT: ret void
3737
;
3838
entry:
3939
tail call void @foo()
4040
tail call void @bar2()
4141
tail call void @baz()
42+
ret void
43+
}
44+
45+
; Function Attrs: nofree noinline norecurse nosync nounwind memory(none) uwtable
46+
define dso_local noundef i32 @main() #1 {
47+
; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind memory(none) uwtable
48+
; CHECK-LABEL: define dso_local noundef i32 @main(
49+
; CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
50+
; CHECK-NEXT: [[ENTRY:.*:]]
51+
; CHECK-NEXT: tail call void @f1()
52+
; CHECK-NEXT: ret i32 0
53+
;
54+
entry:
55+
tail call void @f1()
4256
ret i32 0
4357
}
4458

4559
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
46-
define internal void @foo1() local_unnamed_addr #0 {
60+
define internal void @foo1() #0 {
4761
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
48-
; CHECK-LABEL: define internal fastcc void @foo1(
49-
; CHECK-SAME: ) unnamed_addr #[[ATTR0]] {
62+
; CHECK-LABEL: define internal void @foo1(
63+
; CHECK-SAME: ) #[[ATTR0]] {
5064
; CHECK-NEXT: [[ENTRY:.*:]]
51-
; CHECK-NEXT: tail call fastcc void @bar1()
65+
; CHECK-NEXT: tail call void @bar1()
5266
; CHECK-NEXT: ret void
5367
;
5468
entry:
@@ -57,12 +71,12 @@ entry:
5771
}
5872

5973
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
60-
define internal void @bar() local_unnamed_addr #0 {
74+
define internal void @bar() #0 {
6175
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
62-
; CHECK-LABEL: define internal fastcc void @bar(
63-
; CHECK-SAME: ) unnamed_addr #[[ATTR0]] {
76+
; CHECK-LABEL: define internal void @bar(
77+
; CHECK-SAME: ) #[[ATTR0]] {
6478
; CHECK-NEXT: [[ENTRY:.*:]]
65-
; CHECK-NEXT: tail call fastcc void @foo1()
79+
; CHECK-NEXT: tail call void @foo1()
6680
; CHECK-NEXT: ret void
6781
;
6882
entry:
@@ -71,12 +85,12 @@ entry:
7185
}
7286

7387
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
74-
define internal void @foo() local_unnamed_addr #0 {
88+
define internal void @foo() #0 {
7589
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
76-
; CHECK-LABEL: define internal fastcc void @foo(
77-
; CHECK-SAME: ) unnamed_addr #[[ATTR0]] {
90+
; CHECK-LABEL: define internal void @foo(
91+
; CHECK-SAME: ) #[[ATTR0]] {
7892
; CHECK-NEXT: [[ENTRY:.*:]]
79-
; CHECK-NEXT: tail call fastcc void @bar()
93+
; CHECK-NEXT: tail call void @bar()
8094
; CHECK-NEXT: ret void
8195
;
8296
entry:
@@ -85,12 +99,12 @@ entry:
8599
}
86100

87101
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
88-
define internal void @bar4() local_unnamed_addr #0 {
102+
define internal void @bar4() #0 {
89103
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
90-
; CHECK-LABEL: define internal fastcc void @bar4(
91-
; CHECK-SAME: ) unnamed_addr #[[ATTR0]] {
104+
; CHECK-LABEL: define internal void @bar4(
105+
; CHECK-SAME: ) #[[ATTR0]] {
92106
; CHECK-NEXT: [[ENTRY:.*:]]
93-
; CHECK-NEXT: tail call fastcc void @bar2()
107+
; CHECK-NEXT: tail call void @bar2()
94108
; CHECK-NEXT: ret void
95109
;
96110
entry:
@@ -99,12 +113,12 @@ entry:
99113
}
100114

101115
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
102-
define internal void @bar2() local_unnamed_addr #0 {
116+
define internal void @bar2() #0 {
103117
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
104-
; CHECK-LABEL: define internal fastcc void @bar2(
105-
; CHECK-SAME: ) unnamed_addr #[[ATTR0]] {
118+
; CHECK-LABEL: define internal void @bar2(
119+
; CHECK-SAME: ) #[[ATTR0]] {
106120
; CHECK-NEXT: [[ENTRY:.*:]]
107-
; CHECK-NEXT: tail call fastcc void @bar3()
121+
; CHECK-NEXT: tail call void @bar3()
108122
; CHECK-NEXT: ret void
109123
;
110124
entry:
@@ -113,12 +127,12 @@ entry:
113127
}
114128

115129
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
116-
define internal void @bar3() local_unnamed_addr #0 {
130+
define internal void @bar3() #0 {
117131
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
118-
; CHECK-LABEL: define internal fastcc void @bar3(
119-
; CHECK-SAME: ) unnamed_addr #[[ATTR0]] {
132+
; CHECK-LABEL: define internal void @bar3(
133+
; CHECK-SAME: ) #[[ATTR0]] {
120134
; CHECK-NEXT: [[ENTRY:.*:]]
121-
; CHECK-NEXT: tail call fastcc void @bar4()
135+
; CHECK-NEXT: tail call void @bar4()
122136
; CHECK-NEXT: ret void
123137
;
124138
entry:
@@ -127,12 +141,12 @@ entry:
127141
}
128142

129143
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
130-
define internal void @fun() local_unnamed_addr #0 {
144+
define internal void @fun() #0 {
131145
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
132-
; CHECK-LABEL: define internal fastcc void @fun(
133-
; CHECK-SAME: ) unnamed_addr #[[ATTR0]] {
146+
; CHECK-LABEL: define internal void @fun(
147+
; CHECK-SAME: ) #[[ATTR0]] {
134148
; CHECK-NEXT: [[ENTRY:.*:]]
135-
; CHECK-NEXT: tail call fastcc void @baz()
149+
; CHECK-NEXT: tail call void @baz()
136150
; CHECK-NEXT: ret void
137151
;
138152
entry:
@@ -141,12 +155,12 @@ entry:
141155
}
142156

143157
; Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
144-
define internal void @baz() local_unnamed_addr #0 {
158+
define internal void @baz() #0 {
145159
; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
146-
; CHECK-LABEL: define internal fastcc void @baz(
147-
; CHECK-SAME: ) unnamed_addr #[[ATTR0]] {
160+
; CHECK-LABEL: define internal void @baz(
161+
; CHECK-SAME: ) #[[ATTR0]] {
148162
; CHECK-NEXT: [[ENTRY:.*:]]
149-
; CHECK-NEXT: tail call fastcc void @fun()
163+
; CHECK-NEXT: tail call void @fun()
150164
; CHECK-NEXT: ret void
151165
;
152166
entry:
@@ -155,3 +169,4 @@ entry:
155169
}
156170

157171
attributes #0 = { nofree noinline nosync nounwind memory(none) uwtable }
172+
attributes #1 = { nofree noinline norecurse nosync nounwind memory(none) uwtable }

0 commit comments

Comments
 (0)