1*cee313d2SEric Christopher; RUN: opt < %s -partial-inliner -S -skip-partial-inlining-cost-analysis | FileCheck %s 2*cee313d2SEric Christopher; RUN: opt < %s -passes=partial-inliner -S -skip-partial-inlining-cost-analysis | FileCheck %s 3*cee313d2SEric Christopher 4*cee313d2SEric Christopher@stat = external global i32, align 4 5*cee313d2SEric Christopher 6*cee313d2SEric Christopherdefine i32 @vararg(i32 %count, ...) { 7*cee313d2SEric Christopherentry: 8*cee313d2SEric Christopher %vargs = alloca i8*, align 8 9*cee313d2SEric Christopher %stat1 = load i32, i32* @stat, align 4 10*cee313d2SEric Christopher %cmp = icmp slt i32 %stat1, 0 11*cee313d2SEric Christopher br i1 %cmp, label %bb2, label %bb1 12*cee313d2SEric Christopher 13*cee313d2SEric Christopherbb1: ; preds = %entry 14*cee313d2SEric Christopher %vg1 = add nsw i32 %stat1, 1 15*cee313d2SEric Christopher store i32 %vg1, i32* @stat, align 4 16*cee313d2SEric Christopher %vargs1 = bitcast i8** %vargs to i8* 17*cee313d2SEric Christopher call void @llvm.va_start(i8* %vargs1) 18*cee313d2SEric Christopher %va1 = va_arg i8** %vargs, i32 19*cee313d2SEric Christopher call void @foo(i32 %count, i32 %va1) #2 20*cee313d2SEric Christopher call void @llvm.va_end(i8* %vargs1) 21*cee313d2SEric Christopher br label %bb2 22*cee313d2SEric Christopher 23*cee313d2SEric Christopherbb2: ; preds = %bb1, %entry 24*cee313d2SEric Christopher %res = phi i32 [ 1, %bb1 ], [ 0, %entry ] 25*cee313d2SEric Christopher ret i32 %res 26*cee313d2SEric Christopher} 27*cee313d2SEric Christopher 28*cee313d2SEric Christopherdeclare void @foo(i32, i32) 29*cee313d2SEric Christopherdeclare void @llvm.va_start(i8*) 30*cee313d2SEric Christopherdeclare void @llvm.va_end(i8*) 31*cee313d2SEric Christopher 32*cee313d2SEric Christopherdefine i32 @caller1(i32 %arg) { 33*cee313d2SEric Christopherbb: 34*cee313d2SEric Christopher %tmp = tail call i32 (i32, ...) @vararg(i32 %arg) 35*cee313d2SEric Christopher ret i32 %tmp 36*cee313d2SEric Christopher} 37*cee313d2SEric Christopher; CHECK-LABEL: @caller1 38*cee313d2SEric Christopher; CHECK: codeRepl.i: 39*cee313d2SEric Christopher; CHECK-NEXT: call void (i32, i8**, i32, ...) @vararg.3.bb1(i32 %stat1.i, i8** %vargs.i, i32 %arg) 40*cee313d2SEric Christopher 41*cee313d2SEric Christopherdefine i32 @caller2(i32 %arg, float %arg2) { 42*cee313d2SEric Christopherbb: 43*cee313d2SEric Christopher %tmp = tail call i32 (i32, ...) @vararg(i32 %arg, i32 10, float %arg2) 44*cee313d2SEric Christopher ret i32 %tmp 45*cee313d2SEric Christopher} 46*cee313d2SEric Christopher 47*cee313d2SEric Christopher; CHECK-LABEL: @caller2 48*cee313d2SEric Christopher; CHECK: codeRepl.i: 49*cee313d2SEric Christopher; CHECK-NEXT: call void (i32, i8**, i32, ...) @vararg.3.bb1(i32 %stat1.i, i8** %vargs.i, i32 %arg, i32 10, float %arg2) 50*cee313d2SEric Christopher 51*cee313d2SEric Christopher; Test case to check that we do not extract a vararg function, if va_end is in 52*cee313d2SEric Christopher; a block that is not outlined. 53*cee313d2SEric Christopherdefine i32 @vararg_not_legal(i32 %count, ...) { 54*cee313d2SEric Christopherentry: 55*cee313d2SEric Christopher %vargs = alloca i8*, align 8 56*cee313d2SEric Christopher %vargs0 = bitcast i8** %vargs to i8* 57*cee313d2SEric Christopher %stat1 = load i32, i32* @stat, align 4 58*cee313d2SEric Christopher %cmp = icmp slt i32 %stat1, 0 59*cee313d2SEric Christopher br i1 %cmp, label %bb2, label %bb1 60*cee313d2SEric Christopher 61*cee313d2SEric Christopherbb1: ; preds = %entry 62*cee313d2SEric Christopher %vg1 = add nsw i32 %stat1, 1 63*cee313d2SEric Christopher store i32 %vg1, i32* @stat, align 4 64*cee313d2SEric Christopher %vargs1 = bitcast i8** %vargs to i8* 65*cee313d2SEric Christopher call void @llvm.va_start(i8* %vargs1) 66*cee313d2SEric Christopher %va1 = va_arg i8** %vargs, i32 67*cee313d2SEric Christopher call void @foo(i32 %count, i32 %va1) 68*cee313d2SEric Christopher br label %bb2 69*cee313d2SEric Christopher 70*cee313d2SEric Christopherbb2: ; preds = %bb1, %entry 71*cee313d2SEric Christopher %res = phi i32 [ 1, %bb1 ], [ 0, %entry ] 72*cee313d2SEric Christopher %ptr = phi i8* [ %vargs1, %bb1 ], [ %vargs0, %entry] 73*cee313d2SEric Christopher call void @llvm.va_end(i8* %ptr) 74*cee313d2SEric Christopher ret i32 %res 75*cee313d2SEric Christopher} 76*cee313d2SEric Christopher 77*cee313d2SEric Christopher; CHECK-LABEL: @caller3 78*cee313d2SEric Christopher; CHECK: tail call i32 (i32, ...) @vararg_not_legal(i32 %arg, i32 %arg) 79*cee313d2SEric Christopherdefine i32 @caller3(i32 %arg) { 80*cee313d2SEric Christopherbb: 81*cee313d2SEric Christopher %res = tail call i32 (i32, ...) @vararg_not_legal(i32 %arg, i32 %arg) 82*cee313d2SEric Christopher ret i32 %res 83*cee313d2SEric Christopher} 84*cee313d2SEric Christopher 85*cee313d2SEric Christopherdeclare i32* @err(i32*) 86*cee313d2SEric Christopher 87*cee313d2SEric Christopherdefine signext i32 @vararg2(i32 * %l, ...) { 88*cee313d2SEric Christopherentry: 89*cee313d2SEric Christopher br i1 undef, label %cleanup, label %cond.end 90*cee313d2SEric Christopher 91*cee313d2SEric Christophercond.end: ; preds = %entry 92*cee313d2SEric Christopher %call51 = call i32* @err(i32* nonnull %l) 93*cee313d2SEric Christopher unreachable 94*cee313d2SEric Christopher 95*cee313d2SEric Christophercleanup: ; preds = %entry 96*cee313d2SEric Christopher ret i32 0 97*cee313d2SEric Christopher} 98*cee313d2SEric Christopher 99*cee313d2SEric Christopherdefine i32* @caller_with_signext(i32* %foo) { 100*cee313d2SEric Christopherentry: 101*cee313d2SEric Christopher %call1 = tail call signext i32 (i32*, ...) @vararg2(i32* %foo, i32 signext 8) 102*cee313d2SEric Christopher unreachable 103*cee313d2SEric Christopher} 104*cee313d2SEric Christopher 105*cee313d2SEric Christopher; CHECK-LABEL: @caller_with_signext 106*cee313d2SEric Christopher; CHECK: codeRepl.i: 107*cee313d2SEric Christopher; CHECK-NEXT: call void (i32*, ...) @vararg2.1.cond.end(i32* %foo, i32 signext 8) 108