void __attribute__((no)) doubles(int i, ...) {
  __builtin_va_list args;
  __builtin_va_start(args, i);
  if (__builtin_va_arg(args, int) != 1)
    __builtin_abort();
  if (__builtin_va_arg(args, double) != 2)
    __builtin_abort();
  if (__builtin_va_arg(args, double) != 3)
    __builtin_abort();
  __builtin_va_end(args);
}


x86 assembly (clang, -O0):
<doubles>:
push   %rbp
mov    %rsp,%rbp
sub    $0x130,%rsp
test   %al,%al
je     1149 <doubles+0x39>
movaps %xmm0,-0xa0(%rbp)
movaps %xmm1,-0x90(%rbp)
movaps %xmm2,-0x80(%rbp)
movaps %xmm3,-0x70(%rbp)
movaps %xmm4,-0x60(%rbp)
movaps %xmm5,-0x50(%rbp)
movaps %xmm6,-0x40(%rbp)
movaps %xmm7,-0x30(%rbp)
mov    %r9,-0xa8(%rbp)
mov    %r8,-0xb0(%rbp)
mov    %rcx,-0xb8(%rbp)
mov    %rdx,-0xc0(%rbp)
mov    %rsi,-0xc8(%rbp)
mov    %edi,-0x4(%rbp)
lea    -0x20(%rbp),%rax
lea    -0xd0(%rbp),%rcx
mov    %rcx,0x10(%rax)
lea    0x10(%rbp),%rcx
mov    %rcx,0x8(%rax)
movl   $0x30,0x4(%rax)
movl   $0x8,(%rax)
lea    -0x20(%rbp),%rax
mov    %rax,-0xe0(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0xd4(%rbp)
cmp    $0x28,%eax
ja     11d5 <doubles+0xc5>
mov    -0xe0(%rbp),%rcx
mov    -0xd4(%rbp),%edx
movslq %edx,%rax
add    0x10(%rcx),%rax
add    $0x8,%edx
mov    %edx,(%rcx)
mov    %rax,-0xe8(%rbp)
jmp    11f2 <doubles+0xe2>
mov    -0xe0(%rbp),%rcx
mov    0x8(%rcx),%rdx
mov    %rdx,%rax
add    $0x8,%rdx
mov    %rdx,0x8(%rcx)
mov    %rax,-0xe8(%rbp)
mov    -0xe8(%rbp),%rax
cmpl   $0x1,(%rax)
je     1207 <doubles+0xf7>
call   1030 <abort@plt>
lea    -0x20(%rbp),%rax
mov    %rax,-0x100(%rbp)
add    $0x4,%rax
mov    %rax,-0xf8(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,-0xec(%rbp)
cmp    $0xa0,%eax
ja     125d <doubles+0x14d>
mov    -0xf8(%rbp),%rcx
mov    -0xec(%rbp),%edx
mov    -0x100(%rbp),%rsi
movslq %edx,%rax
add    0x10(%rsi),%rax
add    $0x10,%edx
mov    %edx,(%rcx)
mov    %rax,-0x108(%rbp)
jmp    127a <doubles+0x16a>
mov    -0x100(%rbp),%rcx
mov    0x8(%rcx),%rdx
mov    %rdx,%rax
add    $0x8,%rdx
mov    %rdx,0x8(%rcx)
mov    %rax,-0x108(%rbp)
mov    -0x108(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xd73(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    12a2 <doubles+0x192>
jp     12a2 <doubles+0x192>
jmp    12a7 <doubles+0x197>
call   1030 <abort@plt>
lea    -0x20(%rbp),%rax
mov    %rax,-0x120(%rbp)
add    $0x4,%rax
mov    %rax,-0x118(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,-0x10c(%rbp)
cmp    $0xa0,%eax
ja     12fd <doubles+0x1ed>
mov    -0x118(%rbp),%rcx
mov    -0x10c(%rbp),%edx
mov    -0x120(%rbp),%rsi
movslq %edx,%rax
add    0x10(%rsi),%rax
add    $0x10,%edx
mov    %edx,(%rcx)
mov    %rax,-0x128(%rbp)
jmp    131a <doubles+0x20a>
mov    -0x120(%rbp),%rcx
mov    0x8(%rcx),%rdx
mov    %rdx,%rax
add    $0x8,%rdx
mov    %rdx,0x8(%rcx)
mov    %rax,-0x128(%rbp)
mov    -0x128(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xcdb(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1342 <doubles+0x232>
jp     1342 <doubles+0x232>
jmp    1347 <doubles+0x237>
call   1030 <abort@plt>
add    $0x130,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<doubles>:
sub    $0xd8,%rsp
mov    %rsi,0x28(%rsp)
mov    %rdx,0x30(%rsp)
mov    %rcx,0x38(%rsp)
mov    %r8,0x40(%rsp)
mov    %r9,0x48(%rsp)
test   %al,%al
je     116c <doubles+0x5c>
movapd %xmm0,0x50(%rsp)
movaps %xmm1,0x60(%rsp)
movaps %xmm2,0x70(%rsp)
movaps %xmm3,0x80(%rsp)
movaps %xmm4,0x90(%rsp)
movaps %xmm5,0xa0(%rsp)
movaps %xmm6,0xb0(%rsp)
movaps %xmm7,0xc0(%rsp)
lea    0x20(%rsp),%rax
mov    %rax,0x10(%rsp)
lea    0xe0(%rsp),%rax
mov    %rax,0x8(%rsp)
movabs $0x3000000008,%rax
mov    %rax,(%rsp)
mov    $0x8,%ecx
cmp    $0x28,%rcx
ja     11ae <doubles+0x9e>
mov    $0x8,%eax
add    0x10(%rsp),%rax
add    $0x8,%ecx
mov    %ecx,(%rsp)
jmp    11bc <doubles+0xac>
mov    0x8(%rsp),%rax
lea    0x8(%rax),%rcx
mov    %rcx,0x8(%rsp)
cmpl   $0x1,(%rax)
jne    1239 <doubles+0x129>
mov    0x4(%rsp),%eax
cmp    $0xa0,%rax
ja     11de <doubles+0xce>
mov    %rax,%rcx
add    0x10(%rsp),%rcx
add    $0x10,%eax
mov    %eax,0x4(%rsp)
jmp    11ec <doubles+0xdc>
mov    0x8(%rsp),%rcx
lea    0x8(%rcx),%rdx
mov    %rdx,0x8(%rsp)
movsd  (%rcx),%xmm0
ucomisd 0xe08(%rip),%xmm0
jne    1239 <doubles+0x129>
jp     1239 <doubles+0x129>
cmp    $0xa0,%eax
ja     1213 <doubles+0x103>
mov    %eax,%ecx
add    0x10(%rsp),%rcx
add    $0x10,%eax
mov    %eax,0x4(%rsp)
jmp    1221 <doubles+0x111>
mov    0x8(%rsp),%rcx
lea    0x8(%rcx),%rax
mov    %rax,0x8(%rsp)
movsd  (%rcx),%xmm0
ucomisd 0xddb(%rip),%xmm0
jne    1239 <doubles+0x129>
jp     1239 <doubles+0x129>
add    $0xd8,%rsp
ret
call   1030 <abort@plt>

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

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