1 ; RUN: opt < %s -passes='cgscc(inline)' -inline-threshold=0 -S | FileCheck %s
3 ; The 'test1_' prefixed functions test the basic 'last callsite' inline
4 ; threshold adjustment where we specifically inline the last call site of an
5 ; internal function regardless of cost.
7 define internal void @test1_f() {
10 store volatile i32 0, ptr %p
11 store volatile i32 0, ptr %p
12 store volatile i32 0, ptr %p
13 store volatile i32 0, ptr %p
14 store volatile i32 0, ptr %p
15 store volatile i32 0, ptr %p
16 store volatile i32 0, ptr %p
17 store volatile i32 0, ptr %p
21 ; Identical to @test1_f but doesn't get inlined because there is more than one
22 ; call. If this *does* get inlined, the body used both here and in @test1_f
23 ; isn't a good test for different threshold based on the last call.
24 define internal void @test1_g() {
27 store volatile i32 0, ptr %p
28 store volatile i32 0, ptr %p
29 store volatile i32 0, ptr %p
30 store volatile i32 0, ptr %p
31 store volatile i32 0, ptr %p
32 store volatile i32 0, ptr %p
33 store volatile i32 0, ptr %p
34 store volatile i32 0, ptr %p
38 define void @test1() {
39 ; CHECK-LABEL: define void @test1()
46 ; CHECK: call void @test1_g()
47 ; CHECK: call void @test1_g()
53 ; The 'test2_' prefixed functions test that we can discover the last callsite
54 ; bonus after having inlined the prior call site. For this to work, we need
55 ; a callsite dependent cost so we have a trivial predicate guarding all the
56 ; cost, and set that in a particular direction.
58 define internal void @test2_f(i1 %b) {
61 br i1 %b, label %then, label %exit
64 store volatile i32 0, ptr %p
65 store volatile i32 0, ptr %p
66 store volatile i32 0, ptr %p
67 store volatile i32 0, ptr %p
68 store volatile i32 0, ptr %p
69 store volatile i32 0, ptr %p
70 store volatile i32 0, ptr %p
71 store volatile i32 0, ptr %p
78 ; Identical to @test2_f but doesn't get inlined because there is more than one
79 ; call. If this *does* get inlined, the body used both here and in @test2_f
80 ; isn't a good test for different threshold based on the last call.
81 define internal void @test2_g(i1 %b) {
84 br i1 %b, label %then, label %exit
87 store volatile i32 0, ptr %p
88 store volatile i32 0, ptr %p
89 store volatile i32 0, ptr %p
90 store volatile i32 0, ptr %p
91 store volatile i32 0, ptr %p
92 store volatile i32 0, ptr %p
93 store volatile i32 0, ptr %p
94 store volatile i32 0, ptr %p
101 define void @test2() {
102 ; CHECK-LABEL: define void @test2()
104 ; The first call is trivial to inline due to the argument.
105 call void @test2_f(i1 false)
106 ; CHECK-NOT: @test2_f
108 ; The second call is too expensive to inline unless we update the number of
109 ; calls after inlining the second.
110 call void @test2_f(i1 true)
111 ; CHECK-NOT: @test2_f
113 ; Check that two calls with the hard predicate remain uninlined.
114 call void @test2_g(i1 true)
115 call void @test2_g(i1 true)
116 ; CHECK: call void @test2_g(i1 true)
117 ; CHECK: call void @test2_g(i1 true)
123 ; The 'test3_' prefixed functions are similar to the 'test2_' functions but the
124 ; relative order of the trivial and hard to inline callsites is reversed. This
125 ; checks that the order of calls isn't significant to whether we observe the
126 ; "last callsite" threshold difference because the next-to-last gets inlined.
127 ; FIXME: We don't currently catch this case.
129 define internal void @test3_f(i1 %b) {
132 br i1 %b, label %then, label %exit
135 store volatile i32 0, ptr %p
136 store volatile i32 0, ptr %p
137 store volatile i32 0, ptr %p
138 store volatile i32 0, ptr %p
139 store volatile i32 0, ptr %p
140 store volatile i32 0, ptr %p
141 store volatile i32 0, ptr %p
142 store volatile i32 0, ptr %p
149 ; Identical to @test3_f but doesn't get inlined because there is more than one
150 ; call. If this *does* get inlined, the body used both here and in @test3_f
151 ; isn't a good test for different threshold based on the last call.
152 define internal void @test3_g(i1 %b) {
155 br i1 %b, label %then, label %exit
158 store volatile i32 0, ptr %p
159 store volatile i32 0, ptr %p
160 store volatile i32 0, ptr %p
161 store volatile i32 0, ptr %p
162 store volatile i32 0, ptr %p
163 store volatile i32 0, ptr %p
164 store volatile i32 0, ptr %p
165 store volatile i32 0, ptr %p
172 define void @test3() {
173 ; CHECK-LABEL: define void @test3()
175 ; The first call is too expensive to inline unless we update the number of
176 ; calls after inlining the second.
177 call void @test3_f(i1 true)
178 ; FIXME: We should inline this call without iteration.
179 ; CHECK: call void @test3_f(i1 true)
181 ; But the second call is trivial to inline due to the argument.
182 call void @test3_f(i1 false)
183 ; CHECK-NOT: @test3_f
185 ; Check that two calls with the hard predicate remain uninlined.
186 call void @test3_g(i1 true)
187 call void @test3_g(i1 true)
188 ; CHECK: call void @test3_g(i1 true)
189 ; CHECK: call void @test3_g(i1 true)
195 ; The 'test4_' prefixed functions are similar to the 'test2_' prefixed
196 ; functions but include unusual constant expressions that make discovering that
197 ; a function is dead harder.
199 define internal void @test4_f(i1 %b) {
202 br i1 %b, label %then, label %exit
205 store volatile i32 0, ptr %p
206 store volatile i32 0, ptr %p
207 store volatile i32 0, ptr %p
208 store volatile i32 0, ptr %p
209 store volatile i32 0, ptr %p
210 store volatile i32 0, ptr %p
211 store volatile i32 0, ptr %p
212 store volatile i32 0, ptr %p
219 ; Identical to @test4_f but doesn't get inlined because there is more than one
220 ; call. If this *does* get inlined, the body used both here and in @test4_f
221 ; isn't a good test for different threshold based on the last call.
222 define internal void @test4_g(i1 %b) {
225 br i1 %b, label %then, label %exit
228 store volatile i32 0, ptr %p
229 store volatile i32 0, ptr %p
230 store volatile i32 0, ptr %p
231 store volatile i32 0, ptr %p
232 store volatile i32 0, ptr %p
233 store volatile i32 0, ptr %p
234 store volatile i32 0, ptr %p
235 store volatile i32 0, ptr %p
242 define void @test4() {
243 ; CHECK-LABEL: define void @test4()
245 ; The first call is trivial to inline due to the argument. However this
246 ; argument also uses the function being called as part of a complex
247 ; constant expression. Merely inlining and deleting the call isn't enough to
248 ; drop the use count here, we need to GC the dead constant expression as
250 call void @test4_f(i1 icmp ne (i64 ptrtoint (ptr @test4_f to i64), i64 ptrtoint(ptr @test4_f to i64)))
251 ; CHECK-NOT: @test4_f
253 ; The second call is too expensive to inline unless we update the number of
254 ; calls after inlining the second.
255 call void @test4_f(i1 true)
256 ; CHECK-NOT: @test4_f
258 ; And check that a single call to a function which is used by a complex
259 ; constant expression cannot be inlined because the constant expression forms
260 ; a second use. If this part starts failing we need to use more complex
261 ; constant expressions to reference a particular function with them.
263 store volatile i64 mul (i64 ptrtoint (ptr @test4_g to i64), i64 ptrtoint(ptr @test4_g to i64)), ptr %sink
264 call void @test4_g(i1 true)
265 ; CHECK: store volatile i64 mul (i64 ptrtoint (ptr @test4_g to i64), i64 ptrtoint (ptr @test4_g to i64)), ptr %sink
266 ; CHECK: call void @test4_g(i1 true)