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