_Complex float ffi_test_47(_Complex float x, _Complex double y) {
  return x + 2 * y;
}


x86 assembly (clang, -O0):
<ffi_test_47>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
movlpd %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x20(%rbp)
movsd  %xmm2,-0x18(%rbp)
movss  -0x10(%rbp),%xmm1
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm1,%xmm1
movsd  %xmm1,-0x60(%rbp)
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x20(%rbp),%xmm4
movsd  %xmm4,-0x50(%rbp)
movsd  -0x18(%rbp),%xmm2
movsd  %xmm2,-0x48(%rbp)
movsd  0xeb1(%rip),%xmm0
mulsd  %xmm4,%xmm0
xorps  %xmm3,%xmm3
mulsd  %xmm2,%xmm3
movsd  0xe9e(%rip),%xmm1
mulsd  %xmm2,%xmm1
xorps  %xmm2,%xmm2
mulsd  %xmm4,%xmm2
subsd  %xmm3,%xmm0
movsd  %xmm0,-0x40(%rbp)
addsd  %xmm2,%xmm1
movsd  %xmm1,-0x38(%rbp)
ucomisd %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  %xmm1,-0x28(%rbp)
jnp    11d5 <ffi_test_47+0xd5>
movsd  -0x38(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm0
ucomisd %xmm1,%xmm1
movsd  %xmm0,-0x30(%rbp)
movsd  %xmm1,-0x28(%rbp)
jnp    11d5 <ffi_test_47+0xd5>
movsd  -0x48(%rbp),%xmm3
movsd  -0x50(%rbp),%xmm2
movsd  0xe3d(%rip),%xmm0
xorps  %xmm1,%xmm1
call   1210 <__muldc3>
movsd  %xmm0,-0x30(%rbp)
movsd  %xmm1,-0x28(%rbp)
movsd  -0x58(%rbp),%xmm0
movsd  -0x60(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm3
movsd  -0x28(%rbp),%xmm2
addsd  %xmm3,%xmm1
addsd  %xmm2,%xmm0
cvtsd2ss %xmm1,%xmm1
cvtsd2ss %xmm0,%xmm0
movss  %xmm1,-0x8(%rbp)
movss  %xmm0,-0x4(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret
xchg   %ax,%ax

x86 assembly (clang, -O2):
<ffi_test_47>:
sub    $0x18,%rsp
movapd %xmm2,%xmm3
movapd %xmm1,%xmm2
movaps %xmm0,%xmm6
movapd %xmm3,%xmm0
unpcklpd %xmm3,%xmm0
xorpd  %xmm4,%xmm4
movhpd 0xedd(%rip),%xmm4
mulpd  %xmm0,%xmm4
movsd  0xed1(%rip),%xmm0
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,%xmm5
subpd  %xmm4,%xmm5
addpd  %xmm4,%xmm1
movapd %xmm1,%xmm0
movsd  %xmm5,%xmm0
ucomisd %xmm5,%xmm5
jp     1161 <ffi_test_47+0x61>
cvtps2pd %xmm6,%xmm1
addpd  %xmm0,%xmm1
cvtpd2ps %xmm1,%xmm0
add    $0x18,%rsp
ret
unpckhpd %xmm1,%xmm1
ucomisd %xmm1,%xmm1
jnp    1151 <ffi_test_47+0x51>
movsd  0xe8d(%rip),%xmm0
xorpd  %xmm1,%xmm1
movaps %xmm6,(%rsp)
call   1190 <__muldc3>
movaps (%rsp),%xmm6
unpcklpd %xmm1,%xmm0
jmp    1151 <ffi_test_47+0x51>
nopw   0x0(%rax,%rax,1)

LLVM IR (-O0):
define <2 x float> @ffi_test_47(<2 x float> %0, double %1, double %2) {
%4 = alloca { float, float }
%5 = alloca { float, float }
%6 = alloca { double, double }
%7 = bitcast { float, float }* %5 to <2 x float>*
store <2 x float> %0, <2 x float>* %7
%8 = getelementptr inbounds { double, double }, { double, double }* %6, i32 0, i32 0
store double %1, double* %8
%9 = getelementptr inbounds { double, double }, { double, double }* %6, i32 0, i32 1
store double %2, double* %9
%10 = getelementptr inbounds { float, float }, { float, float }* %5, i32 0, i32 0
%11 = load float, float* %10
%12 = getelementptr inbounds { float, float }, { float, float }* %5, i32 0, i32 1
%13 = load float, float* %12
%14 = fpext float %11 to double
%15 = fpext float %13 to double
%16 = getelementptr inbounds { double, double }, { double, double }* %6, i32 0, i32 0
%17 = load double, double* %16
%18 = getelementptr inbounds { double, double }, { double, double }* %6, i32 0, i32 1
%19 = load double, double* %18
%20 = fmul double 2.000000e+00, %17
%21 = fmul double 0.000000e+00, %19
%22 = fmul double 2.000000e+00, %19
%23 = fmul double 0.000000e+00, %17
%24 = fsub double %20, %21
%25 = fadd double %22, %23
%26 = fcmp uno double %24, %24
br i1 %26, label %27, label %33
27: ; preds = %3
%28 = fcmp uno double %25, %25
br i1 %28, label %29, label %33
29: ; preds = %27
%30 = call { double, double } @__muldc3(double 2.000000e+00, double 0.000000e+00, double %17, double %19)
%31 = extractvalue { double, double } %30, 0
%32 = extractvalue { double, double } %30, 1
br label %33
33: ; preds = %29, %27, %3
%34 = phi double [ %24, %3 ], [ %24, %27 ], [ %31, %29 ]
%35 = phi double [ %25, %3 ], [ %25, %27 ], [ %32, %29 ]
%36 = fadd double %14, %34
%37 = fadd double %15, %35
%38 = fptrunc double %36 to float
%39 = fptrunc double %37 to float
%40 = getelementptr inbounds { float, float }, { float, float }* %4, i32 0, i32 0
%41 = getelementptr inbounds { float, float }, { float, float }* %4, i32 0, i32 1
store float %38, float* %40
store float %39, float* %41
%42 = bitcast { float, float }* %4 to <2 x float>*
%43 = load <2 x float>, <2 x float>* %42
ret <2 x float> %43
}

LLVM IR (-O2):
define <2 x float> @ffi_test_47(<2 x float> %0, double %1, double %2) {
%4 = insertelement <2 x double> poison, double %2, i64 0
%5 = shufflevector <2 x double> %4, <2 x double> poison, <2 x i32> zeroinitializer
%6 = fmul <2 x double> %5, <double 0.000000e+00, double 2.000000e+00>
%7 = insertelement <2 x double> poison, double %1, i64 0
%8 = shufflevector <2 x double> %7, <2 x double> poison, <2 x i32> zeroinitializer
%9 = fmul <2 x double> %8, <double 2.000000e+00, double 0.000000e+00>
%10 = fsub <2 x double> %9, %6
%11 = fadd <2 x double> %9, %6
%12 = shufflevector <2 x double> %10, <2 x double> %11, <2 x i32> <i32 0, i32 3>
%13 = extractelement <2 x double> %10, i64 0
%14 = fcmp uno double %13, 0.000000e+00
br i1 %14, label %15, label %24
15: ; preds = %3
%16 = extractelement <2 x double> %11, i64 1
%17 = fcmp uno double %16, 0.000000e+00
br i1 %17, label %18, label %24
18: ; preds = %15
%19 = tail call { double, double } @__muldc3(double 2.000000e+00, double 0.000000e+00, double %1, double %2)
%20 = extractvalue { double, double } %19, 0
%21 = extractvalue { double, double } %19, 1
%22 = insertelement <2 x double> poison, double %20, i64 0
%23 = insertelement <2 x double> %22, double %21, i64 1
br label %24
24: ; preds = %18, %15, %3
%25 = phi <2 x double> [ %12, %3 ], [ %12, %15 ], [ %23, %18 ]
%26 = fpext <2 x float> %0 to <2 x double>
%27 = fadd <2 x double> %25, %26
%28 = fptrunc <2 x double> %27 to <2 x float>
ret <2 x float> %28
}