1 ; RUN: opt < %s -passes=inline -inline-threshold=20 -S | FileCheck %s
2 ; RUN: opt < %s -passes='cgscc(inline)' -inline-threshold=20 -S | FileCheck %s
4 define internal i32 @callee1(i32 %A, i32 %B) {
9 define i32 @caller1() {
10 ; CHECK-LABEL: define i32 @caller1(
11 ; CHECK-NEXT: ret i32 3
13 %X = call i32 @callee1( i32 10, i32 3 )
17 define i32 @caller2() {
18 ; Check that we can constant-prop through instructions after inlining callee21
19 ; to get constants in the inlined callsite to callee22.
20 ; FIXME: Currently, the threshold is fixed at 20 because we don't perform
21 ; *recursive* cost analysis to realize that the nested call site will definitely
22 ; inline and be cheap. We should eventually do that and lower the threshold here
25 ; CHECK-LABEL: @caller2(
26 ; CHECK-NOT: call void @callee2
29 %x = call i32 @callee21(i32 42, i32 48)
33 define i32 @callee21(i32 %x, i32 %y) {
35 %result = call i32 @callee22(i32 %sub)
41 define i32 @callee22(i32 %x) {
42 %icmp = icmp ugt i32 %x, 42
43 br i1 %icmp, label %bb.true, label %bb.false
45 ; This block musn't be counted in the inline cost.
60 define i32 @caller3() {
61 ; Check that even if the expensive path is hidden behind several basic blocks,
62 ; it doesn't count toward the inline cost when constant-prop proves those paths
65 ; CHECK-LABEL: @caller3(
70 %x = call i32 @callee3(i32 42, i32 48)
74 define i32 @callee3(i32 %x, i32 %y) {
76 %icmp = icmp ugt i32 %sub, 42
77 br i1 %icmp, label %bb.true, label %bb.false
80 %icmp2 = icmp ult i32 %sub, 64
81 br i1 %icmp2, label %bb.true.true, label %bb.true.false
84 ; This block musn't be counted in the inline cost.
96 ; This block musn't be counted in the inline cost.
108 %result = phi i32 [ %x8, %bb.true.true ], [ %y8, %bb.true.false ]
115 declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
117 define i8 @caller4(i8 %z) {
118 ; Check that we can constant fold through intrinsics such as the
119 ; overflow-detecting arithmetic intrinsics. These are particularly important
120 ; as they are used heavily in standard library code and generic C++ code where
121 ; the arguments are oftent constant but complete generality is required.
123 ; CHECK-LABEL: @caller4(
128 %x = call i8 @callee4(i8 254, i8 14, i8 %z)
132 define i8 @callee4(i8 %x, i8 %y, i8 %z) {
133 %uadd = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %x, i8 %y)
134 %o = extractvalue {i8, i1} %uadd, 1
135 br i1 %o, label %bb.true, label %bb.false
141 ; This block musn't be counted in the inline cost.
153 define i64 @caller5(i64 %y) {
154 ; Check that we can round trip constants through various kinds of casts etc w/o
155 ; losing track of the constant prop in the inline cost analysis.
157 ; CHECK-LABEL: @caller5(
162 %x = call i64 @callee5(i64 42, i64 %y)
166 define i64 @callee5(i64 %x, i64 %y) {
167 %inttoptr = inttoptr i64 %x to ptr
168 %ptrtoint = ptrtoint ptr %inttoptr to i64
169 %trunc = trunc i64 %ptrtoint to i32
170 %zext = zext i32 %trunc to i64
171 %cmp = icmp eq i64 %zext, 42
172 br i1 %cmp, label %bb.true, label %bb.false
178 ; This block musn't be counted in the inline cost.
190 define float @caller6() {
191 ; Check that we can constant-prop through fcmp instructions
193 ; CHECK-LABEL: @caller6(
196 %x = call float @callee6(float 42.0)
200 define float @callee6(float %x) {
201 %icmp = fcmp ugt float %x, 42.0
202 br i1 %icmp, label %bb.true, label %bb.false
205 ; This block musn't be counted in the inline cost.
206 %x1 = fadd float %x, 1.0
207 %x2 = fadd float %x1, 1.0
208 %x3 = fadd float %x2, 1.0
209 %x4 = fadd float %x3, 1.0
210 %x5 = fadd float %x4, 1.0
211 %x6 = fadd float %x5, 1.0
212 %x7 = fadd float %x6, 1.0
213 %x8 = fadd float %x7, 1.0
222 define i32 @PR13412.main() {
223 ; This is a somewhat complicated three layer subprogram that was reported to
224 ; compute the wrong value for a branch due to assuming that an argument
225 ; mid-inline couldn't be equal to another pointer.
227 ; After inlining, the branch should point directly to the exit block, not to
228 ; the intermediate block.
229 ; CHECK: @PR13412.main
230 ; CHECK: br i1 true, label %[[TRUE_DEST:.*]], label %[[FALSE_DEST:.*]]
231 ; CHECK: [[FALSE_DEST]]:
232 ; CHECK-NEXT: call void @PR13412.fail()
233 ; CHECK: [[TRUE_DEST]]:
234 ; CHECK-NEXT: ret i32 0
239 %call = call i1 @PR13412.first(ptr %i1, ptr %i1)
240 br i1 %call, label %cond.end, label %cond.false
243 call void @PR13412.fail()
250 define internal i1 @PR13412.first(ptr %a, ptr %b) {
252 %call = call ptr @PR13412.second(ptr %a, ptr %b)
253 %cmp = icmp eq ptr %call, %b
257 declare void @PR13412.fail()
259 define internal ptr @PR13412.second(ptr %a, ptr %b) {
261 %sub.ptr.lhs.cast = ptrtoint ptr %b to i64
262 %sub.ptr.rhs.cast = ptrtoint ptr %a to i64
263 %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
264 %sub.ptr.div = ashr exact i64 %sub.ptr.sub, 2
265 %cmp = icmp ugt i64 %sub.ptr.div, 1
266 br i1 %cmp, label %if.then, label %if.end3
269 %0 = load i32, ptr %a
270 %1 = load i32, ptr %b
271 %cmp1 = icmp eq i32 %0, %1
272 br i1 %cmp1, label %return, label %if.end3
278 %retval.0 = phi ptr [ %b, %if.end3 ], [ %a, %if.then ]
282 declare i32 @PR28802.external(i32 returned %p1)
284 define internal i32 @PR28802.callee() {
289 %0 = phi i32 [ 0, %entry ]
290 %call = call i32 @PR28802.external(i32 %0)
294 define i32 @PR28802() {
296 %call = call i32 @PR28802.callee()
300 ; CHECK-LABEL: define i32 @PR28802(
301 ; CHECK: %[[call:.*]] = call i32 @PR28802.external(i32 0)
302 ; CHECK: ret i32 %[[call]]
304 define internal i32 @PR28848.callee(i32 %p2, i1 %c) {
306 br i1 %c, label %cond.end, label %cond.true
312 %cond = phi i32 [ 0, %cond.true ], [ %p2, %entry ]
313 %or = or i32 %cond, %p2
317 define i32 @PR28848() {
319 %call = call i32 @PR28848.callee(i32 0, i1 false)
322 ; CHECK-LABEL: define i32 @PR28848(
325 define internal void @callee7(i16 %param1, i16 %param2) {
330 %phi = phi i16 [ %param2, %entry ]
331 %add = add i16 %phi, %param1
335 declare i16 @caller7.external(i16 returned)
337 define void @caller7() {
339 %call = call i16 @caller7.external(i16 1)
340 call void @callee7(i16 0, i16 %call)
343 ; CHECK-LABEL: define void @caller7(
344 ; CHECK: %call = call i16 @caller7.external(i16 1)
345 ; CHECK-NEXT: ret void
347 define float @caller8(float %y) {
348 ; Check that we can constant-prop through fneg instructions
350 ; CHECK-LABEL: @caller8(
353 %x = call float @callee8(float -42.0, float %y)
357 define float @callee8(float %x, float %y) {
359 %icmp = fcmp ugt float %neg, 42.0
360 br i1 %icmp, label %bb.true, label %bb.false
363 ; This block musn't be counted in the inline cost.
364 %y1 = fadd float %y, 1.0
365 %y2 = fadd float %y1, 1.0
366 %y3 = fadd float %y2, 1.0
367 %y4 = fadd float %y3, 1.0
368 %y5 = fadd float %y4, 1.0
369 %y6 = fadd float %y5, 1.0
370 %y7 = fadd float %y6, 1.0
371 %y8 = fadd float %y7, 1.0