| ; RUN: opt < %s -inline -inline-threshold=20 -S | FileCheck %s |
| |
| define internal i32 @callee1(i32 %A, i32 %B) { |
| %C = sdiv i32 %A, %B |
| ret i32 %C |
| } |
| |
| define i32 @caller1() { |
| ; CHECK: define i32 @caller1 |
| ; CHECK-NEXT: ret i32 3 |
| |
| %X = call i32 @callee1( i32 10, i32 3 ) |
| ret i32 %X |
| } |
| |
| define i32 @caller2() { |
| ; Check that we can constant-prop through instructions after inlining callee21 |
| ; to get constants in the inlined callsite to callee22. |
| ; FIXME: Currently, the threshold is fixed at 20 because we don't perform |
| ; *recursive* cost analysis to realize that the nested call site will definitely |
| ; inline and be cheap. We should eventually do that and lower the threshold here |
| ; to 1. |
| ; |
| ; CHECK: @caller2 |
| ; CHECK-NOT: call void @callee2 |
| ; CHECK: ret |
| |
| %x = call i32 @callee21(i32 42, i32 48) |
| ret i32 %x |
| } |
| |
| define i32 @callee21(i32 %x, i32 %y) { |
| %sub = sub i32 %y, %x |
| %result = call i32 @callee22(i32 %sub) |
| ret i32 %result |
| } |
| |
| declare i8* @getptr() |
| |
| define i32 @callee22(i32 %x) { |
| %icmp = icmp ugt i32 %x, 42 |
| br i1 %icmp, label %bb.true, label %bb.false |
| bb.true: |
| ; This block musn't be counted in the inline cost. |
| %x1 = add i32 %x, 1 |
| %x2 = add i32 %x1, 1 |
| %x3 = add i32 %x2, 1 |
| %x4 = add i32 %x3, 1 |
| %x5 = add i32 %x4, 1 |
| %x6 = add i32 %x5, 1 |
| %x7 = add i32 %x6, 1 |
| %x8 = add i32 %x7, 1 |
| |
| ret i32 %x8 |
| bb.false: |
| ret i32 %x |
| } |
| |
| define i32 @caller3() { |
| ; Check that even if the expensive path is hidden behind several basic blocks, |
| ; it doesn't count toward the inline cost when constant-prop proves those paths |
| ; dead. |
| ; |
| ; CHECK: @caller3 |
| ; CHECK-NOT: call |
| ; CHECK: ret i32 6 |
| |
| entry: |
| %x = call i32 @callee3(i32 42, i32 48) |
| ret i32 %x |
| } |
| |
| define i32 @callee3(i32 %x, i32 %y) { |
| %sub = sub i32 %y, %x |
| %icmp = icmp ugt i32 %sub, 42 |
| br i1 %icmp, label %bb.true, label %bb.false |
| |
| bb.true: |
| %icmp2 = icmp ult i32 %sub, 64 |
| br i1 %icmp2, label %bb.true.true, label %bb.true.false |
| |
| bb.true.true: |
| ; This block musn't be counted in the inline cost. |
| %x1 = add i32 %x, 1 |
| %x2 = add i32 %x1, 1 |
| %x3 = add i32 %x2, 1 |
| %x4 = add i32 %x3, 1 |
| %x5 = add i32 %x4, 1 |
| %x6 = add i32 %x5, 1 |
| %x7 = add i32 %x6, 1 |
| %x8 = add i32 %x7, 1 |
| br label %bb.merge |
| |
| bb.true.false: |
| ; This block musn't be counted in the inline cost. |
| %y1 = add i32 %y, 1 |
| %y2 = add i32 %y1, 1 |
| %y3 = add i32 %y2, 1 |
| %y4 = add i32 %y3, 1 |
| %y5 = add i32 %y4, 1 |
| %y6 = add i32 %y5, 1 |
| %y7 = add i32 %y6, 1 |
| %y8 = add i32 %y7, 1 |
| br label %bb.merge |
| |
| bb.merge: |
| %result = phi i32 [ %x8, %bb.true.true ], [ %y8, %bb.true.false ] |
| ret i32 %result |
| |
| bb.false: |
| ret i32 %sub |
| } |
| |
| |
| define i32 @PR13412.main() { |
| ; This is a somewhat complicated three layer subprogram that was reported to |
| ; compute the wrong value for a branch due to assuming that an argument |
| ; mid-inline couldn't be equal to another pointer. |
| ; |
| ; After inlining, the branch should point directly to the exit block, not to |
| ; the intermediate block. |
| ; CHECK: @PR13412.main |
| ; CHECK: br i1 true, label %[[TRUE_DEST:.*]], label %[[FALSE_DEST:.*]] |
| ; CHECK: [[FALSE_DEST]]: |
| ; CHECK-NEXT: call void @PR13412.fail() |
| ; CHECK: [[TRUE_DEST]]: |
| ; CHECK-NEXT: ret i32 0 |
| |
| entry: |
| %i1 = alloca i64 |
| store i64 0, i64* %i1 |
| %arraydecay = bitcast i64* %i1 to i32* |
| %call = call i1 @PR13412.first(i32* %arraydecay, i32* %arraydecay) |
| br i1 %call, label %cond.end, label %cond.false |
| |
| cond.false: |
| call void @PR13412.fail() |
| br label %cond.end |
| |
| cond.end: |
| ret i32 0 |
| } |
| |
| define internal i1 @PR13412.first(i32* %a, i32* %b) { |
| entry: |
| %call = call i32* @PR13412.second(i32* %a, i32* %b) |
| %cmp = icmp eq i32* %call, %b |
| ret i1 %cmp |
| } |
| |
| declare void @PR13412.fail() |
| |
| define internal i32* @PR13412.second(i32* %a, i32* %b) { |
| entry: |
| %sub.ptr.lhs.cast = ptrtoint i32* %b to i64 |
| %sub.ptr.rhs.cast = ptrtoint i32* %a to i64 |
| %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast |
| %sub.ptr.div = ashr exact i64 %sub.ptr.sub, 2 |
| %cmp = icmp ugt i64 %sub.ptr.div, 1 |
| br i1 %cmp, label %if.then, label %if.end3 |
| |
| if.then: |
| %0 = load i32* %a |
| %1 = load i32* %b |
| %cmp1 = icmp eq i32 %0, %1 |
| br i1 %cmp1, label %return, label %if.end3 |
| |
| if.end3: |
| br label %return |
| |
| return: |
| %retval.0 = phi i32* [ %b, %if.end3 ], [ %a, %if.then ] |
| ret i32* %retval.0 |
| } |