void test_foo_3(float fv, double dv, float _Complex fc, double _Complex dc) {
  char *cp1 = foo(fv);
  char *cp2 = foo(dv);
  int *ip = foo(fc);
  long *lp = foo(dc);
}


x86 assembly (clang, -O0):
<test_foo_3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
movlpd %xmm2,-0x8(%rbp)
movsd  %xmm3,-0x18(%rbp)
movsd  %xmm4,-0x10(%rbp)
movss  %xmm0,-0x1c(%rbp)
movsd  %xmm1,-0x28(%rbp)
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
mov    %al,-0x61(%rbp)
call   1030 <foo@plt>
mov    %eax,%ecx
mov    -0x61(%rbp),%al
movslq %ecx,%rcx
mov    %rcx,-0x30(%rbp)
movsd  -0x28(%rbp),%xmm0
call   1030 <foo@plt>
cltq
mov    %rax,-0x38(%rbp)
movss  -0x8(%rbp),%xmm1
movss  -0x4(%rbp),%xmm0
movss  %xmm1,-0x48(%rbp)
movss  %xmm0,-0x44(%rbp)
movsd  -0x48(%rbp),%xmm0
mov    $0x1,%al
call   1030 <foo@plt>
cltq
mov    %rax,-0x40(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
movsd  %xmm1,-0x60(%rbp)
movsd  %xmm0,-0x58(%rbp)
movsd  -0x60(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm1
mov    $0x2,%al
call   1030 <foo@plt>
cltq
mov    %rax,-0x50(%rbp)
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_foo_3>:
sub    $0x38,%rsp
movsd  %xmm4,0x18(%rsp)
movsd  %xmm3,0x10(%rsp)
movaps %xmm2,0x20(%rsp)
movsd  %xmm1,0x8(%rsp)
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   1030 <foo@plt>
movsd  0x8(%rsp),%xmm0
mov    $0x1,%al
call   1030 <foo@plt>
movaps 0x20(%rsp),%xmm0
mov    $0x1,%al
call   1030 <foo@plt>
movsd  0x10(%rsp),%xmm0
movsd  0x18(%rsp),%xmm1
mov    $0x2,%al
add    $0x38,%rsp
jmp    1030 <foo@plt>

LLVM IR (-O0):
define void @test_foo_3(float %0, double %1, <2 x float> %2, double %3, double %4) {
%6 = alloca { float, float }
%7 = alloca { double, double }
%8 = alloca float
%9 = alloca double
%10 = alloca i8*
%11 = alloca i8*
%12 = alloca i32*
%13 = alloca { float, float }
%14 = alloca i64*
%15 = alloca { double, double }
%16 = bitcast { float, float }* %6 to <2 x float>*
store <2 x float> %2, <2 x float>* %16
%17 = getelementptr inbounds { double, double }, { double, double }* %7, i32 0, i32 0
store double %3, double* %17
%18 = getelementptr inbounds { double, double }, { double, double }* %7, i32 0, i32 1
store double %4, double* %18
store float %0, float* %8
store double %1, double* %9
%19 = load float, float* %8
%20 = fpext float %19 to double
%21 = call i32 (double, ...) bitcast (i32 (...)* @foo to i32 (double, ...)*)(double %20)
%22 = sext i32 %21 to i64
%23 = inttoptr i64 %22 to i8*
store i8* %23, i8** %10
%24 = load double, double* %9
%25 = call i32 (double, ...) bitcast (i32 (...)* @foo to i32 (double, ...)*)(double %24)
%26 = sext i32 %25 to i64
%27 = inttoptr i64 %26 to i8*
store i8* %27, i8** %11
%28 = getelementptr inbounds { float, float }, { float, float }* %6, i32 0, i32 0
%29 = load float, float* %28
%30 = getelementptr inbounds { float, float }, { float, float }* %6, i32 0, i32 1
%31 = load float, float* %30
%32 = getelementptr inbounds { float, float }, { float, float }* %13, i32 0, i32 0
%33 = getelementptr inbounds { float, float }, { float, float }* %13, i32 0, i32 1
store float %29, float* %32
store float %31, float* %33
%34 = bitcast { float, float }* %13 to <2 x float>*
%35 = load <2 x float>, <2 x float>* %34
%36 = call i32 (<2 x float>, ...) bitcast (i32 (...)* @foo to i32 (<2 x float>, ...)*)(<2 x float> %35)
%37 = sext i32 %36 to i64
%38 = inttoptr i64 %37 to i32*
store i32* %38, i32** %12
%39 = getelementptr inbounds { double, double }, { double, double }* %7, i32 0, i32 0
%40 = load double, double* %39
%41 = getelementptr inbounds { double, double }, { double, double }* %7, i32 0, i32 1
%42 = load double, double* %41
%43 = getelementptr inbounds { double, double }, { double, double }* %15, i32 0, i32 0
%44 = getelementptr inbounds { double, double }, { double, double }* %15, i32 0, i32 1
store double %40, double* %43
store double %42, double* %44
%45 = getelementptr inbounds { double, double }, { double, double }* %15, i32 0, i32 0
%46 = load double, double* %45
%47 = getelementptr inbounds { double, double }, { double, double }* %15, i32 0, i32 1
%48 = load double, double* %47
%49 = call i32 (double, double, ...) bitcast (i32 (...)* @foo to i32 (double, double, ...)*)(double %46, double %48)
%50 = sext i32 %49 to i64
%51 = inttoptr i64 %50 to i64*
store i64* %51, i64** %14
ret void
}

LLVM IR (-O2):
define void @test_foo_3(float %0, double %1, <2 x float> %2, double %3, double %4) {
%6 = fpext float %0 to double
%7 = tail call i32 (double, ...) bitcast (i32 (...)* @foo to i32 (double, ...)*)(double %6)
%8 = tail call i32 (double, ...) bitcast (i32 (...)* @foo to i32 (double, ...)*)(double %1)
%9 = tail call i32 (<2 x float>, ...) bitcast (i32 (...)* @foo to i32 (<2 x float>, ...)*)(<2 x float> %2)
%10 = tail call i32 (double, double, ...) bitcast (i32 (...)* @foo to i32 (double, double, ...)*)(double %3, double %4)
ret void
}