1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=generic -mtriple=x86_64-pc-win32 | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Verify that the var arg parameters which are passed in registers are stored 4*9880d681SAndroid Build Coastguard Worker; in home stack slots allocated by the caller and that AP is correctly 5*9880d681SAndroid Build Coastguard Worker; calculated. 6*9880d681SAndroid Build Coastguard Workerdefine void @average_va(i32 %count, ...) nounwind { 7*9880d681SAndroid Build Coastguard Workerentry: 8*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 9*9880d681SAndroid Build Coastguard Worker; CHECK: movq %r9, 40(%rsp) 10*9880d681SAndroid Build Coastguard Worker; CHECK: movq %r8, 32(%rsp) 11*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rdx, 24(%rsp) 12*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 24(%rsp), %rax 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 ; <i8**> [#uses=1] 15*9880d681SAndroid Build Coastguard Worker %ap1 = bitcast i8** %ap to i8* ; <i8*> [#uses=1] 16*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap1) 17*9880d681SAndroid Build Coastguard Worker ret void 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_start(i8*) nounwind 21*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_copy(i8*, i8*) nounwind 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 24*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 25*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 56(%rsp), 26*9880d681SAndroid Build Coastguard Workerdefine i8* @f5(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, ...) nounwind { 27*9880d681SAndroid Build Coastguard Workerentry: 28*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 29*9880d681SAndroid Build Coastguard Worker %ap1 = bitcast i8** %ap to i8* 30*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap1) 31*9880d681SAndroid Build Coastguard Worker ret i8* %ap1 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 35*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 36*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 48(%rsp), 37*9880d681SAndroid Build Coastguard Workerdefine i8* @f4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind { 38*9880d681SAndroid Build Coastguard Workerentry: 39*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 40*9880d681SAndroid Build Coastguard Worker %ap1 = bitcast i8** %ap to i8* 41*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap1) 42*9880d681SAndroid Build Coastguard Worker ret i8* %ap1 43*9880d681SAndroid Build Coastguard Worker} 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 46*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 47*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 40(%rsp), 48*9880d681SAndroid Build Coastguard Workerdefine i8* @f3(i64 %a0, i64 %a1, i64 %a2, ...) nounwind { 49*9880d681SAndroid Build Coastguard Workerentry: 50*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 51*9880d681SAndroid Build Coastguard Worker %ap1 = bitcast i8** %ap to i8* 52*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap1) 53*9880d681SAndroid Build Coastguard Worker ret i8* %ap1 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker; WinX86_64 uses char* for va_list. Verify that the correct amount of bytes 57*9880d681SAndroid Build Coastguard Worker; are copied using va_copy. 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: copy1: 60*9880d681SAndroid Build Coastguard Worker; CHECK: subq $16 61*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 32(%rsp), [[REG_copy1:%[a-z]+]] 62*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_copy1]], 8(%rsp) 63*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_copy1]], (%rsp) 64*9880d681SAndroid Build Coastguard Worker; CHECK: addq $16 65*9880d681SAndroid Build Coastguard Worker; CHECK: ret 66*9880d681SAndroid Build Coastguard Workerdefine void @copy1(i64 %a0, ...) nounwind { 67*9880d681SAndroid Build Coastguard Workerentry: 68*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 69*9880d681SAndroid Build Coastguard Worker %cp = alloca i8*, align 8 70*9880d681SAndroid Build Coastguard Worker %ap1 = bitcast i8** %ap to i8* 71*9880d681SAndroid Build Coastguard Worker %cp1 = bitcast i8** %cp to i8* 72*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap1) 73*9880d681SAndroid Build Coastguard Worker call void @llvm.va_copy(i8* %cp1, i8* %ap1) 74*9880d681SAndroid Build Coastguard Worker ret void 75*9880d681SAndroid Build Coastguard Worker} 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: copy4: 78*9880d681SAndroid Build Coastguard Worker; CHECK: subq $16 79*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 56(%rsp), [[REG_copy4:%[a-z]+]] 80*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_copy4]], 8(%rsp) 81*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_copy4]], (%rsp) 82*9880d681SAndroid Build Coastguard Worker; CHECK: addq $16 83*9880d681SAndroid Build Coastguard Worker; CHECK: ret 84*9880d681SAndroid Build Coastguard Workerdefine void @copy4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind { 85*9880d681SAndroid Build Coastguard Workerentry: 86*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 87*9880d681SAndroid Build Coastguard Worker %cp = alloca i8*, align 8 88*9880d681SAndroid Build Coastguard Worker %ap1 = bitcast i8** %ap to i8* 89*9880d681SAndroid Build Coastguard Worker %cp1 = bitcast i8** %cp to i8* 90*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap1) 91*9880d681SAndroid Build Coastguard Worker call void @llvm.va_copy(i8* %cp1, i8* %ap1) 92*9880d681SAndroid Build Coastguard Worker ret void 93*9880d681SAndroid Build Coastguard Worker} 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: arg4: 96*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 97*9880d681SAndroid Build Coastguard Worker; va_start: 98*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 48(%rsp), [[REG_arg4_1:%[a-z]+]] 99*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_arg4_1]], (%rsp) 100*9880d681SAndroid Build Coastguard Worker; va_arg: 101*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 52(%rsp), [[REG_arg4_2:%[a-z]+]] 102*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_arg4_2]], (%rsp) 103*9880d681SAndroid Build Coastguard Worker; CHECK: movl 48(%rsp), %eax 104*9880d681SAndroid Build Coastguard Worker; CHECK: popq 105*9880d681SAndroid Build Coastguard Worker; CHECK: ret 106*9880d681SAndroid Build Coastguard Workerdefine i32 @arg4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind { 107*9880d681SAndroid Build Coastguard Workerentry: 108*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 109*9880d681SAndroid Build Coastguard Worker %ap1 = bitcast i8** %ap to i8* 110*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap1) 111*9880d681SAndroid Build Coastguard Worker %tmp = va_arg i8** %ap, i32 112*9880d681SAndroid Build Coastguard Worker ret i32 %tmp 113*9880d681SAndroid Build Coastguard Worker} 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workerdefine void @sret_arg(i32* sret %agg.result, i8* nocapture readnone %format, ...) { 116*9880d681SAndroid Build Coastguard Workerentry: 117*9880d681SAndroid Build Coastguard Worker %ap = alloca i8* 118*9880d681SAndroid Build Coastguard Worker %ap_i8 = bitcast i8** %ap to i8* 119*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap_i8) 120*9880d681SAndroid Build Coastguard Worker %tmp = va_arg i8** %ap, i32 121*9880d681SAndroid Build Coastguard Worker store i32 %tmp, i32* %agg.result 122*9880d681SAndroid Build Coastguard Worker ret void 123*9880d681SAndroid Build Coastguard Worker} 124*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sret_arg: 125*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 126*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: movq %r9, 40(%rsp) 127*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: movq %r8, 32(%rsp) 128*9880d681SAndroid Build Coastguard Worker; CHECK: movl 32(%rsp), %[[tmp:[^ ]*]] 129*9880d681SAndroid Build Coastguard Worker; CHECK: movl %[[tmp]], (%[[sret:[^ ]*]]) 130*9880d681SAndroid Build Coastguard Worker; CHECK: movq %[[sret]], %rax 131*9880d681SAndroid Build Coastguard Worker; CHECK: popq 132*9880d681SAndroid Build Coastguard Worker; CHECK: retq 133