1*9880d681SAndroid Build Coastguard Worker; The inliner should never inline recursive functions into other functions. 2*9880d681SAndroid Build Coastguard Worker; This effectively is just peeling off the first iteration of a loop, and the 3*9880d681SAndroid Build Coastguard Worker; inliner heuristics are not set up for this. 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; RUN: opt -inline -S < %s | FileCheck %s 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-apple-darwin10.3" 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker@g = common global i32 0 ; <i32*> [#uses=1] 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdefine internal void @foo(i32 %x) nounwind ssp { 13*9880d681SAndroid Build Coastguard Workerentry: 14*9880d681SAndroid Build Coastguard Worker %0 = icmp slt i32 %x, 0 ; <i1> [#uses=1] 15*9880d681SAndroid Build Coastguard Worker br i1 %0, label %return, label %bb 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Workerbb: ; preds = %entry 18*9880d681SAndroid Build Coastguard Worker %1 = sub nsw i32 %x, 1 ; <i32> [#uses=1] 19*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %1) nounwind ssp 20*9880d681SAndroid Build Coastguard Worker store volatile i32 1, i32* @g, align 4 21*9880d681SAndroid Build Coastguard Worker ret void 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Workerreturn: ; preds = %entry 24*9880d681SAndroid Build Coastguard Worker ret void 25*9880d681SAndroid Build Coastguard Worker} 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker;; CHECK-LABEL: @bonk( 29*9880d681SAndroid Build Coastguard Worker;; CHECK: call void @foo(i32 42) 30*9880d681SAndroid Build Coastguard Workerdefine void @bonk() nounwind ssp { 31*9880d681SAndroid Build Coastguard Workerentry: 32*9880d681SAndroid Build Coastguard Worker call void @foo(i32 42) nounwind ssp 33*9880d681SAndroid Build Coastguard Worker ret void 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker;; Here is an indirect case that should not be infinitely inlined. 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Workerdefine internal void @f1(i32 %x, i8* %Foo, i8* %Bar) nounwind ssp { 41*9880d681SAndroid Build Coastguard Workerentry: 42*9880d681SAndroid Build Coastguard Worker %0 = bitcast i8* %Bar to void (i32, i8*, i8*)* 43*9880d681SAndroid Build Coastguard Worker %1 = sub nsw i32 %x, 1 44*9880d681SAndroid Build Coastguard Worker call void %0(i32 %1, i8* %Foo, i8* %Bar) nounwind 45*9880d681SAndroid Build Coastguard Worker store volatile i32 42, i32* @g, align 4 46*9880d681SAndroid Build Coastguard Worker ret void 47*9880d681SAndroid Build Coastguard Worker} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerdefine internal void @f2(i32 %x, i8* %Foo, i8* %Bar) nounwind ssp { 50*9880d681SAndroid Build Coastguard Workerentry: 51*9880d681SAndroid Build Coastguard Worker %0 = icmp slt i32 %x, 0 ; <i1> [#uses=1] 52*9880d681SAndroid Build Coastguard Worker br i1 %0, label %return, label %bb 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Workerbb: ; preds = %entry 55*9880d681SAndroid Build Coastguard Worker %1 = bitcast i8* %Foo to void (i32, i8*, i8*)* ; <void (i32, i8*, i8*)*> [#uses=1] 56*9880d681SAndroid Build Coastguard Worker call void %1(i32 %x, i8* %Foo, i8* %Bar) nounwind 57*9880d681SAndroid Build Coastguard Worker store volatile i32 13, i32* @g, align 4 58*9880d681SAndroid Build Coastguard Worker ret void 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workerreturn: ; preds = %entry 61*9880d681SAndroid Build Coastguard Worker ret void 62*9880d681SAndroid Build Coastguard Worker} 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @top_level( 66*9880d681SAndroid Build Coastguard Worker; CHECK: call void @f2(i32 122 67*9880d681SAndroid Build Coastguard Worker; Here we inline one instance of the cycle, but we don't want to completely 68*9880d681SAndroid Build Coastguard Worker; unroll it. 69*9880d681SAndroid Build Coastguard Workerdefine void @top_level() nounwind ssp { 70*9880d681SAndroid Build Coastguard Workerentry: 71*9880d681SAndroid Build Coastguard Worker call void @f2(i32 123, i8* bitcast (void (i32, i8*, i8*)* @f1 to i8*), i8* bitcast (void (i32, i8*, i8*)* @f2 to i8*)) nounwind ssp 72*9880d681SAndroid Build Coastguard Worker ret void 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; Check that a recursive function, when called with a constant that makes the 77*9880d681SAndroid Build Coastguard Worker; recursive path dead code can actually be inlined. 78*9880d681SAndroid Build Coastguard Workerdefine i32 @fib(i32 %i) { 79*9880d681SAndroid Build Coastguard Workerentry: 80*9880d681SAndroid Build Coastguard Worker %is.zero = icmp eq i32 %i, 0 81*9880d681SAndroid Build Coastguard Worker br i1 %is.zero, label %zero.then, label %zero.else 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerzero.then: 84*9880d681SAndroid Build Coastguard Worker ret i32 0 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerzero.else: 87*9880d681SAndroid Build Coastguard Worker %is.one = icmp eq i32 %i, 1 88*9880d681SAndroid Build Coastguard Worker br i1 %is.one, label %one.then, label %one.else 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Workerone.then: 91*9880d681SAndroid Build Coastguard Worker ret i32 1 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Workerone.else: 94*9880d681SAndroid Build Coastguard Worker %i1 = sub i32 %i, 1 95*9880d681SAndroid Build Coastguard Worker %f1 = call i32 @fib(i32 %i1) 96*9880d681SAndroid Build Coastguard Worker %i2 = sub i32 %i, 2 97*9880d681SAndroid Build Coastguard Worker %f2 = call i32 @fib(i32 %i2) 98*9880d681SAndroid Build Coastguard Worker %f = add i32 %f1, %f2 99*9880d681SAndroid Build Coastguard Worker ret i32 %f 100*9880d681SAndroid Build Coastguard Worker} 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Workerdefine i32 @fib_caller() { 103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fib_caller( 104*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call 105*9880d681SAndroid Build Coastguard Worker; CHECK: ret 106*9880d681SAndroid Build Coastguard Worker %f1 = call i32 @fib(i32 0) 107*9880d681SAndroid Build Coastguard Worker %f2 = call i32 @fib(i32 1) 108*9880d681SAndroid Build Coastguard Worker %result = add i32 %f1, %f2 109*9880d681SAndroid Build Coastguard Worker ret i32 %result 110*9880d681SAndroid Build Coastguard Worker} 111