__complex float foo(__complex float a, __complex float b) { return a * b; }


x86 assembly (clang, -O0):
<foo>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movlpd %xmm0,-0x10(%rbp)
movlpd %xmm1,-0x18(%rbp)
movss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
movss  -0xc(%rbp),%xmm2
movss  %xmm2,-0x3c(%rbp)
movss  -0x18(%rbp),%xmm4
movss  %xmm4,-0x38(%rbp)
movss  -0x14(%rbp),%xmm5
movss  %xmm5,-0x34(%rbp)
movaps %xmm0,%xmm1
mulss  %xmm4,%xmm1
movaps %xmm2,%xmm3
mulss  %xmm5,%xmm3
mulss  %xmm5,%xmm0
mulss  %xmm4,%xmm2
subss  %xmm3,%xmm1
movss  %xmm1,-0x30(%rbp)
addss  %xmm2,%xmm0
movss  %xmm0,-0x2c(%rbp)
ucomiss %xmm1,%xmm1
movss  %xmm1,-0x28(%rbp)
movss  %xmm0,-0x24(%rbp)
jnp    11c4 <foo+0xc4>
movss  -0x2c(%rbp),%xmm0
movss  -0x30(%rbp),%xmm1
ucomiss %xmm0,%xmm0
movss  %xmm1,-0x28(%rbp)
movss  %xmm0,-0x24(%rbp)
jnp    11c4 <foo+0xc4>
movss  -0x34(%rbp),%xmm3
movss  -0x38(%rbp),%xmm2
movss  -0x3c(%rbp),%xmm1
movss  -0x40(%rbp),%xmm0
call   11f0 <__mulsc3>
movlpd %xmm0,-0x20(%rbp)
movss  -0x20(%rbp),%xmm1
movss  -0x1c(%rbp),%xmm0
movss  %xmm1,-0x28(%rbp)
movss  %xmm0,-0x24(%rbp)
movss  -0x28(%rbp),%xmm1
movss  -0x24(%rbp),%xmm0
movss  %xmm1,-0x8(%rbp)
movss  %xmm0,-0x4(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)

x86 assembly (clang, -O2):
<foo>:
movaps %xmm1,%xmm2
movaps %xmm0,%xmm4
movaps %xmm1,%xmm3
shufps $0xe1,%xmm1,%xmm3
mulps  %xmm1,%xmm0
mulps  %xmm4,%xmm3
movaps %xmm0,%xmm1
shufps $0x55,%xmm0,%xmm1
subss  %xmm1,%xmm0
movaps %xmm3,%xmm1
shufps $0x55,%xmm3,%xmm1
addss  %xmm3,%xmm1
ucomiss %xmm0,%xmm0
jp     1132 <foo+0x32>
unpcklps %xmm1,%xmm0
ret
ucomiss %xmm1,%xmm1
jnp    112e <foo+0x2e>
push   %rax
movaps %xmm2,%xmm3
shufps $0x55,%xmm2,%xmm3
movaps %xmm4,%xmm1
shufps $0x55,%xmm4,%xmm1
movaps %xmm4,%xmm0
call   1160 <__mulsc3>
movaps %xmm0,%xmm1
shufps $0x55,%xmm0,%xmm1
add    $0x8,%rsp
unpcklps %xmm1,%xmm0
ret
nopl   (%rax)

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

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