float f(int a, ...) {
  double tot = a;
  __builtin_va_list l;
  __builtin_va_start(l, a);
  tot += __builtin_va_arg(l, double);
  tot += __builtin_va_arg(l, double);
  tot += __builtin_va_arg(l, int);
  __builtin_va_end(l);
  return tot;
}


x86 assembly (clang, -O0):
<f>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
test   %al,%al
je     113c <f+0x3c>
movaps %xmm0,-0xb0(%rbp)
movaps %xmm1,-0xa0(%rbp)
movaps %xmm2,-0x90(%rbp)
movaps %xmm3,-0x80(%rbp)
movaps %xmm4,-0x70(%rbp)
movaps %xmm5,-0x60(%rbp)
movaps %xmm6,-0x50(%rbp)
movaps %xmm7,-0x40(%rbp)
mov    %r9,-0xb8(%rbp)
mov    %r8,-0xc0(%rbp)
mov    %rcx,-0xc8(%rbp)
mov    %rdx,-0xd0(%rbp)
mov    %rsi,-0xd8(%rbp)
mov    %edi,-0x4(%rbp)
cvtsi2sdl -0x4(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
lea    -0x30(%rbp),%rax
lea    -0xe0(%rbp),%rcx
mov    %rcx,0x10(%rax)
lea    0x10(%rbp),%rcx
mov    %rcx,0x8(%rax)
movl   $0x30,0x4(%rax)
movl   $0x8,(%rax)
lea    -0x30(%rbp),%rax
mov    %rax,-0xf8(%rbp)
add    $0x4,%rax
mov    %rax,-0xf0(%rbp)
mov    -0x2c(%rbp),%eax
mov    %eax,-0xe4(%rbp)
cmp    $0xa0,%eax
ja     11e6 <f+0xe6>
mov    -0xf0(%rbp),%rcx
mov    -0xe4(%rbp),%edx
mov    -0xf8(%rbp),%rsi
movslq %edx,%rax
add    0x10(%rsi),%rax
add    $0x10,%edx
mov    %edx,(%rcx)
mov    %rax,-0x100(%rbp)
jmp    1203 <f+0x103>
mov    -0xf8(%rbp),%rcx
mov    0x8(%rcx),%rdx
mov    %rdx,%rax
add    $0x8,%rdx
mov    %rdx,0x8(%rcx)
mov    %rax,-0x100(%rbp)
mov    -0x100(%rbp),%rax
movsd  (%rax),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
lea    -0x30(%rbp),%rax
mov    %rax,-0x118(%rbp)
add    $0x4,%rax
mov    %rax,-0x110(%rbp)
mov    -0x2c(%rbp),%eax
mov    %eax,-0x104(%rbp)
cmp    $0xa0,%eax
ja     126e <f+0x16e>
mov    -0x110(%rbp),%rcx
mov    -0x104(%rbp),%edx
mov    -0x118(%rbp),%rsi
movslq %edx,%rax
add    0x10(%rsi),%rax
add    $0x10,%edx
mov    %edx,(%rcx)
mov    %rax,-0x120(%rbp)
jmp    128b <f+0x18b>
mov    -0x118(%rbp),%rcx
mov    0x8(%rcx),%rdx
mov    %rdx,%rax
add    $0x8,%rdx
mov    %rdx,0x8(%rcx)
mov    %rax,-0x120(%rbp)
mov    -0x120(%rbp),%rax
movsd  (%rax),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
lea    -0x30(%rbp),%rax
mov    %rax,-0x130(%rbp)
mov    -0x30(%rbp),%eax
mov    %eax,-0x124(%rbp)
cmp    $0x28,%eax
ja     12e2 <f+0x1e2>
mov    -0x130(%rbp),%rcx
mov    -0x124(%rbp),%edx
movslq %edx,%rax
add    0x10(%rcx),%rax
add    $0x8,%edx
mov    %edx,(%rcx)
mov    %rax,-0x138(%rbp)
jmp    12ff <f+0x1ff>
mov    -0x130(%rbp),%rcx
mov    0x8(%rcx),%rdx
mov    %rdx,%rax
add    $0x8,%rdx
mov    %rdx,0x8(%rcx)
mov    %rax,-0x138(%rbp)
mov    -0x138(%rbp),%rax
cvtsi2sdl (%rax),%xmm1
movsd  -0x10(%rbp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<f>:
sub    $0x58,%rsp
mov    %rsi,-0x58(%rsp)
mov    %rdx,-0x50(%rsp)
mov    %rcx,-0x48(%rsp)
mov    %r8,-0x40(%rsp)
mov    %r9,-0x38(%rsp)
test   %al,%al
je     1148 <f+0x48>
movaps %xmm0,-0x30(%rsp)
movaps %xmm1,-0x20(%rsp)
movaps %xmm2,-0x10(%rsp)
movaps %xmm3,(%rsp)
movaps %xmm4,0x10(%rsp)
movaps %xmm5,0x20(%rsp)
movaps %xmm6,0x30(%rsp)
movaps %xmm7,0x40(%rsp)
movabs $0x3000000008,%rax
mov    %rax,-0x80(%rsp)
lea    -0x60(%rsp),%rax
mov    %rax,-0x70(%rsp)
lea    0x60(%rsp),%rax
mov    %rax,-0x78(%rsp)
mov    -0x7c(%rsp),%ecx
cmp    $0xa1,%rcx
jae    11a0 <f+0xa0>
mov    -0x70(%rsp),%rdx
lea    0x10(%rcx),%rax
mov    %eax,-0x7c(%rsp)
movsd  (%rdx,%rcx,1),%xmm0
cmp    $0x90,%ecx
ja     11b2 <f+0xb2>
add    -0x70(%rsp),%rax
add    $0x20,%ecx
mov    %ecx,-0x7c(%rsp)
jmp    11c0 <f+0xc0>
mov    -0x78(%rsp),%rax
lea    0x8(%rax),%rcx
mov    %rcx,-0x78(%rsp)
movsd  (%rax),%xmm0
mov    -0x78(%rsp),%rax
lea    0x8(%rax),%rcx
mov    %rcx,-0x78(%rsp)
movsd  (%rax),%xmm1
mov    -0x80(%rsp),%ecx
cmp    $0x28,%rcx
ja     11df <f+0xdf>
mov    %rcx,%rax
add    -0x70(%rsp),%rax
add    $0x8,%ecx
mov    %ecx,-0x80(%rsp)
jmp    11ed <f+0xed>
mov    -0x78(%rsp),%rax
lea    0x8(%rax),%rcx
mov    %rcx,-0x78(%rsp)
xorps  %xmm2,%xmm2
cvtsi2sd %edi,%xmm2
addsd  %xmm2,%xmm0
xorps  %xmm2,%xmm2
cvtsi2sdl (%rax),%xmm2
addsd  %xmm1,%xmm0
addsd  %xmm0,%xmm2
xorps  %xmm0,%xmm0
cvtsd2ss %xmm2,%xmm0
add    $0x58,%rsp
ret

LLVM IR (-O0):
%struct.__va_list_tag = type { i32, i32, i8*, i8* }
define float @f(i32 %0, ...) {
%2 = alloca i32
%3 = alloca double
%4 = alloca [1 x %struct.__va_list_tag]
store i32 %0, i32* %2
%5 = load i32, i32* %2
%6 = sitofp i32 %5 to double
store double %6, double* %3
%7 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %4, i64 0, i64 0
%8 = bitcast %struct.__va_list_tag* %7 to i8*
%9 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %4, i64 0, i64 0
%10 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %9, i32 0, i32 1
%11 = load i32, i32* %10
%12 = icmp ule i32 %11, 160
br i1 %12, label %13, label %19
13: ; preds = %1
%14 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %9, i32 0, i32 3
%15 = load i8*, i8** %14
%16 = getelementptr i8, i8* %15, i32 %11
%17 = bitcast i8* %16 to double*
%18 = add i32 %11, 16
store i32 %18, i32* %10
br label %24
19: ; preds = %1
%20 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %9, i32 0, i32 2
%21 = load i8*, i8** %20
%22 = bitcast i8* %21 to double*
%23 = getelementptr i8, i8* %21, i32 8
store i8* %23, i8** %20
br label %24
24: ; preds = %19, %13
%25 = phi double* [ %17, %13 ], [ %22, %19 ]
%26 = load double, double* %25
%27 = load double, double* %3
%28 = fadd double %27, %26
store double %28, double* %3
%29 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %4, i64 0, i64 0
%30 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %29, i32 0, i32 1
%31 = load i32, i32* %30
%32 = icmp ule i32 %31, 160
br i1 %32, label %33, label %39
33: ; preds = %24
%34 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %29, i32 0, i32 3
%35 = load i8*, i8** %34
%36 = getelementptr i8, i8* %35, i32 %31
%37 = bitcast i8* %36 to double*
%38 = add i32 %31, 16
store i32 %38, i32* %30
br label %44
39: ; preds = %24
%40 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %29, i32 0, i32 2
%41 = load i8*, i8** %40
%42 = bitcast i8* %41 to double*
%43 = getelementptr i8, i8* %41, i32 8
store i8* %43, i8** %40
br label %44
44: ; preds = %39, %33
%45 = phi double* [ %37, %33 ], [ %42, %39 ]
%46 = load double, double* %45
%47 = load double, double* %3
%48 = fadd double %47, %46
store double %48, double* %3
%49 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %4, i64 0, i64 0
%50 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %49, i32 0, i32 0
%51 = load i32, i32* %50
%52 = icmp ule i32 %51, 40
br i1 %52, label %53, label %59
53: ; preds = %44
%54 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %49, i32 0, i32 3
%55 = load i8*, i8** %54
%56 = getelementptr i8, i8* %55, i32 %51
%57 = bitcast i8* %56 to i32*
%58 = add i32 %51, 8
store i32 %58, i32* %50
br label %64
59: ; preds = %44
%60 = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %49, i32 0, i32 2
%61 = load i8*, i8** %60
%62 = bitcast i8* %61 to i32*
%63 = getelementptr i8, i8* %61, i32 8
store i8* %63, i8** %60
br label %64
64: ; preds = %59, %53
%65 = phi i32* [ %57, %53 ], [ %62, %59 ]
%66 = load i32, i32* %65
%67 = sitofp i32 %66 to double
%68 = load double, double* %3
%69 = fadd double %68, %67
store double %69, double* %3
%70 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %4, i64 0, i64 0
%71 = bitcast %struct.__va_list_tag* %70 to i8*
%72 = load double, double* %3
%73 = fptrunc double %72 to float
ret float %73
}

LLVM IR (-O2):
%struct.__va_list_tag = type { i32, i32, i8*, i8* }
define float @f(i32 %0, ...) {
%2 = alloca [1 x %struct.__va_list_tag]
%3 = bitcast [1 x %struct.__va_list_tag]* %2 to i8*
%4 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %2, i64 0, i64 0, i32 1
%5 = load i32, i32* %4
%6 = icmp ult i32 %5, 161
br i1 %6, label %13, label %7
7: ; preds = %1
%8 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %2, i64 0, i64 0, i32 2
%9 = load i8*, i8** %8
%10 = getelementptr i8, i8* %9, i64 8
store i8* %10, i8** %8
%11 = bitcast i8* %9 to double*
%12 = load double, double* %11
br label %28
13: ; preds = %1
%14 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %2, i64 0, i64 0, i32 3
%15 = load i8*, i8** %14
%16 = zext i32 %5 to i64
%17 = getelementptr i8, i8* %15, i64 %16
%18 = add nuw nsw i32 %5, 16
store i32 %18, i32* %4
%19 = bitcast i8* %17 to double*
%20 = load double, double* %19
%21 = icmp ult i32 %5, 145
br i1 %21, label %22, label %28
22: ; preds = %13
%23 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %2, i64 0, i64 0, i32 3
%24 = load i8*, i8** %23
%25 = zext i32 %18 to i64
%26 = getelementptr i8, i8* %24, i64 %25
%27 = add nuw nsw i32 %5, 32
store i32 %27, i32* %4
br label %33
28: ; preds = %7, %13
%29 = phi double [ %12, %7 ], [ %20, %13 ]
%30 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %2, i64 0, i64 0, i32 2
%31 = load i8*, i8** %30
%32 = getelementptr i8, i8* %31, i64 8
store i8* %32, i8** %30
br label %33
33: ; preds = %28, %22
%34 = phi double [ %20, %22 ], [ %29, %28 ]
%35 = phi i8* [ %26, %22 ], [ %31, %28 ]
%36 = bitcast i8* %35 to double*
%37 = load double, double* %36
%38 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %2, i64 0, i64 0, i32 0
%39 = load i32, i32* %38
%40 = icmp ult i32 %39, 41
br i1 %40, label %41, label %47
41: ; preds = %33
%42 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %2, i64 0, i64 0, i32 3
%43 = load i8*, i8** %42
%44 = zext i32 %39 to i64
%45 = getelementptr i8, i8* %43, i64 %44
%46 = add nuw nsw i32 %39, 8
store i32 %46, i32* %38
br label %51
47: ; preds = %33
%48 = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %2, i64 0, i64 0, i32 2
%49 = load i8*, i8** %48
%50 = getelementptr i8, i8* %49, i64 8
store i8* %50, i8** %48
br label %51
51: ; preds = %47, %41
%52 = phi i8* [ %45, %41 ], [ %49, %47 ]
%53 = bitcast i8* %52 to i32*
%54 = sitofp i32 %0 to double
%55 = fadd double %34, %54
%56 = fadd double %55, %37
%57 = load i32, i32* %53
%58 = sitofp i32 %57 to double
%59 = fadd double %56, %58
%60 = fptrunc double %59 to float
ret float %60
}