122 lines · plain
1; RUN: llc < %s -mcpu=generic -mtriple=x86_64-pc-win32 | FileCheck %s2 3; Verify that the var arg parameters which are passed in registers are stored4; in home stack slots allocated by the caller and that AP is correctly5; calculated.6define void @average_va(i32 %count, ...) nounwind {7entry:8; CHECK: pushq9; CHECK-DAG: movq %r9, 40(%rsp)10; CHECK-DAG: movq %r8, 32(%rsp)11; CHECK-DAG: movq %rdx, 24(%rsp)12; CHECK: leaq 24(%rsp), %rax13 14 %ap = alloca ptr, align 8 ; <ptr> [#uses=1]15 call void @llvm.va_start(ptr %ap)16 ret void17}18 19declare void @llvm.va_start(ptr) nounwind20declare void @llvm.va_copy(ptr, ptr) nounwind21 22; CHECK-LABEL: f5:23; CHECK: pushq24; CHECK: leaq 56(%rsp),25define ptr @f5(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, ...) nounwind {26entry:27 %ap = alloca ptr, align 828 call void @llvm.va_start(ptr %ap)29 ret ptr %ap30}31 32; CHECK-LABEL: f4:33; CHECK: pushq34; CHECK: leaq 48(%rsp),35define ptr @f4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind {36entry:37 %ap = alloca ptr, align 838 call void @llvm.va_start(ptr %ap)39 ret ptr %ap40}41 42; CHECK-LABEL: f3:43; CHECK: pushq44; CHECK: leaq 40(%rsp),45define ptr @f3(i64 %a0, i64 %a1, i64 %a2, ...) nounwind {46entry:47 %ap = alloca ptr, align 848 call void @llvm.va_start(ptr %ap)49 ret ptr %ap50}51 52; WinX86_64 uses char* for va_list. Verify that the correct amount of bytes53; are copied using va_copy.54 55; CHECK-LABEL: copy1:56; CHECK: subq $1657; CHECK: leaq 32(%rsp), [[REG_copy1:%[a-z]+]]58; CHECK: movq [[REG_copy1]], 8(%rsp)59; CHECK: movq [[REG_copy1]], (%rsp)60; CHECK: addq $1661; CHECK: ret62define void @copy1(i64 %a0, ...) nounwind {63entry:64 %ap = alloca ptr, align 865 %cp = alloca ptr, align 866 call void @llvm.va_start(ptr %ap)67 call void @llvm.va_copy(ptr %cp, ptr %ap)68 ret void69}70 71; CHECK-LABEL: copy4:72; CHECK: subq $1673; CHECK: leaq 56(%rsp), [[REG_copy4:%[a-z]+]]74; CHECK: movq [[REG_copy4]], 8(%rsp)75; CHECK: movq [[REG_copy4]], (%rsp)76; CHECK: addq $1677; CHECK: ret78define void @copy4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind {79entry:80 %ap = alloca ptr, align 881 %cp = alloca ptr, align 882 call void @llvm.va_start(ptr %ap)83 call void @llvm.va_copy(ptr %cp, ptr %ap)84 ret void85}86 87; CHECK-LABEL: arg4:88; CHECK: pushq89; va_start (optimized away as overwritten by va_arg)90; va_arg:91; CHECK: leaq 52(%rsp), [[REG_arg4_2:%[a-z]+]]92; CHECK: movq [[REG_arg4_2]], (%rsp)93; CHECK: movl 48(%rsp), %eax94; CHECK: popq95; CHECK: ret96define i32 @arg4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind {97entry:98 %ap = alloca ptr, align 899 call void @llvm.va_start(ptr %ap)100 %tmp = va_arg ptr %ap, i32101 ret i32 %tmp102}103 104define void @sret_arg(ptr sret(i32) %agg.result, ptr nocapture readnone %format, ...) {105entry:106 %ap = alloca ptr107 call void @llvm.va_start(ptr %ap)108 %tmp = va_arg ptr %ap, i32109 store i32 %tmp, ptr %agg.result110 ret void111}112; CHECK-LABEL: sret_arg:113; CHECK: pushq114; CHECK: movq %rcx, %rax115; CHECK-DAG: movq %r9, 40(%rsp)116; CHECK-DAG: movq %r8, 32(%rsp)117; CHECK-DAG: leaq 36(%rsp), %[[sret:[^ ]*]]118; CHECK-DAG: movl %r8d, (%rax)119; CHECK-DAG: movq %[[sret]], (%rsp)120; CHECK: popq121; CHECK: retq122