void mp_mul_cmuladd(int nfft, double din1[], double din2[], double dinout[]) {
  int j;
  double xr, xi, yr, yi;
  dinout[1] += din1[1] * din2[1];
  dinout[2] += din1[2] * din2[2];
  for (j = 3; j < nfft; j += 2) {
    xr = din1[j];
    xi = din1[j + 1];
    yr = din2[j];
    yi = din2[j + 1];
    dinout[j] += xr * yr - xi * yi;
    dinout[j + 1] += xr * yi + xi * yr;
  }
  dinout[nfft + 1] += din1[nfft + 1] * din2[nfft + 1];
}


x86 assembly (clang, -O0):
<mp_mul_cmuladd>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rax)
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  0x10(%rax),%xmm2
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x10(%rax)
movl   $0x3,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    124e <mp_mul_cmuladd+0x14e>
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm1
mulsd  -0x48(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x30(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm1
mulsd  -0x40(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x24(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x24(%rbp)
jmp    116a <mp_mul_cmuladd+0x6a>
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x4(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x20(%rbp),%rax
mov    -0x4(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
pop    %rbp
ret

x86 assembly (clang, -O2):
<mp_mul_cmuladd>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
movsd  0x8(%rsi),%xmm0
mulsd  0x8(%rdx),%xmm0
addsd  0x8(%rcx),%xmm0
movsd  %xmm0,0x8(%rcx)
movsd  0x10(%rsi),%xmm0
mulsd  0x10(%rdx),%xmm0
addsd  0x10(%rcx),%xmm0
movsd  %xmm0,0x10(%rcx)
cmp    $0x4,%edi
jl     12f8 <mp_mul_cmuladd+0x1f8>
mov    %edi,%r8d
cmp    $0x6,%r8
mov    $0x5,%r9d
cmovae %r8,%r9
mov    $0x5,%r11d
add    $0xfffffffffffffffc,%r9
mov    $0x3,%eax
cmp    $0x2,%r9
jb     129b <mp_mul_cmuladd+0x19b>
lea    0x18(%rcx),%r10
cmp    $0x6,%r8
cmovae %r8,%r11
add    $0xfffffffffffffffc,%r11
movabs $0x1ffffffffffffffe,%rbx
ff ff 1f
and    %r11,%rbx
lea    (%rcx,%rbx,8),%r11
add    $0x28,%r11
lea    0x18(%rsi),%r14
lea    (%rsi,%rbx,8),%r15
add    $0x28,%r15
lea    0x18(%rdx),%r12
lea    (%rdx,%rbx,8),%rbx
add    $0x28,%rbx
cmp    %r15,%r10
setb   %bpl
cmp    %r11,%r14
setb   %r14b
cmp    %rbx,%r10
setb   %bl
cmp    %r11,%r12
setb   %r10b
test   %r14b,%bpl
jne    129b <mp_mul_cmuladd+0x19b>
and    %r10b,%bl
jne    129b <mp_mul_cmuladd+0x19b>
shr    %r9
add    $0x1,%r9
movabs $0x7ffffffffffffffe,%r10
ff ff 7f
and    %r9,%r10
lea    (%r9,%r9,1),%rax
or     $0x3,%rax
mov    $0x18,%r11d
mov    %r10,%rbx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movupd (%rsi,%r11,1),%xmm0
movupd 0x10(%rsi,%r11,1),%xmm1
movapd %xmm0,%xmm2
unpcklpd %xmm1,%xmm2
unpckhpd %xmm1,%xmm0
movupd (%rdx,%r11,1),%xmm1
movupd 0x10(%rdx,%r11,1),%xmm3
movapd %xmm1,%xmm4
unpcklpd %xmm3,%xmm4
unpckhpd %xmm3,%xmm1
movapd %xmm1,%xmm3
mulpd  %xmm0,%xmm3
mulpd  %xmm2,%xmm1
mulpd  %xmm4,%xmm2
subpd  %xmm3,%xmm2
movupd (%rcx,%r11,1),%xmm3
movupd 0x10(%rcx,%r11,1),%xmm5
movapd %xmm3,%xmm6
unpcklpd %xmm5,%xmm6
addpd  %xmm2,%xmm6
unpckhpd %xmm5,%xmm3
mulpd  %xmm0,%xmm4
addpd  %xmm4,%xmm1
addpd  %xmm3,%xmm1
movapd %xmm6,%xmm0
unpckhpd %xmm1,%xmm0
unpcklpd %xmm1,%xmm6
movupd %xmm6,(%rcx,%r11,1)
movupd %xmm0,0x10(%rcx,%r11,1)
add    $0x20,%r11
add    $0xfffffffffffffffe,%rbx
jne    1200 <mp_mul_cmuladd+0x100>
cmp    %r10,%r9
je     12f8 <mp_mul_cmuladd+0x1f8>
movapd 0xd5d(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movupd (%rdx,%rax,8),%xmm1
movsd  (%rsi,%rax,8),%xmm2
movsd  0x8(%rsi,%rax,8),%xmm3
movapd %xmm3,%xmm4
xorpd  %xmm0,%xmm4
unpcklpd %xmm3,%xmm4
unpcklpd %xmm2,%xmm2
mulpd  %xmm1,%xmm2
shufpd $0x1,%xmm1,%xmm1
mulpd  %xmm4,%xmm1
addpd  %xmm1,%xmm2
movupd (%rcx,%rax,8),%xmm1
addpd  %xmm2,%xmm1
movupd %xmm1,(%rcx,%rax,8)
add    $0x2,%rax
cmp    %r8,%rax
jb     12b0 <mp_mul_cmuladd+0x1b0>
movslq %edi,%rax
movsd  0x8(%rsi,%rax,8),%xmm0
mulsd  0x8(%rdx,%rax,8),%xmm0
addsd  0x8(%rcx,%rax,8),%xmm0
movsd  %xmm0,0x8(%rcx,%rax,8)
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @mp_mul_cmuladd(i32 %0, double* %1, double* %2, double* %3) {
%5 = alloca i32
%6 = alloca double*
%7 = alloca double*
%8 = alloca double*
%9 = alloca i32
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
store i32 %0, i32* %5
store double* %1, double** %6
store double* %2, double** %7
store double* %3, double** %8
%14 = load double*, double** %6
%15 = getelementptr inbounds double, double* %14, i64 1
%16 = load double, double* %15
%17 = load double*, double** %7
%18 = getelementptr inbounds double, double* %17, i64 1
%19 = load double, double* %18
%20 = load double*, double** %8
%21 = getelementptr inbounds double, double* %20, i64 1
%22 = load double, double* %21
%23 = call double @llvm.fmuladd.f64(double %16, double %19, double %22)
store double %23, double* %21
%24 = load double*, double** %6
%25 = getelementptr inbounds double, double* %24, i64 2
%26 = load double, double* %25
%27 = load double*, double** %7
%28 = getelementptr inbounds double, double* %27, i64 2
%29 = load double, double* %28
%30 = load double*, double** %8
%31 = getelementptr inbounds double, double* %30, i64 2
%32 = load double, double* %31
%33 = call double @llvm.fmuladd.f64(double %26, double %29, double %32)
store double %33, double* %31
store i32 3, i32* %9
br label %34
34: ; preds = %87, %4
%35 = load i32, i32* %9
%36 = load i32, i32* %5
%37 = icmp slt i32 %35, %36
br i1 %37, label %38, label %90
38: ; preds = %34
%39 = load double*, double** %6
%40 = load i32, i32* %9
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds double, double* %39, i64 %41
%43 = load double, double* %42
store double %43, double* %10
%44 = load double*, double** %6
%45 = load i32, i32* %9
%46 = add nsw i32 %45, 1
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds double, double* %44, i64 %47
%49 = load double, double* %48
store double %49, double* %11
%50 = load double*, double** %7
%51 = load i32, i32* %9
%52 = sext i32 %51 to i64
%53 = getelementptr inbounds double, double* %50, i64 %52
%54 = load double, double* %53
store double %54, double* %12
%55 = load double*, double** %7
%56 = load i32, i32* %9
%57 = add nsw i32 %56, 1
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds double, double* %55, i64 %58
%60 = load double, double* %59
store double %60, double* %13
%61 = load double, double* %10
%62 = load double, double* %12
%63 = load double, double* %11
%64 = load double, double* %13
%65 = fmul double %63, %64
%66 = fneg double %65
%67 = call double @llvm.fmuladd.f64(double %61, double %62, double %66)
%68 = load double*, double** %8
%69 = load i32, i32* %9
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds double, double* %68, i64 %70
%72 = load double, double* %71
%73 = fadd double %72, %67
store double %73, double* %71
%74 = load double, double* %10
%75 = load double, double* %13
%76 = load double, double* %11
%77 = load double, double* %12
%78 = fmul double %76, %77
%79 = call double @llvm.fmuladd.f64(double %74, double %75, double %78)
%80 = load double*, double** %8
%81 = load i32, i32* %9
%82 = add nsw i32 %81, 1
%83 = sext i32 %82 to i64
%84 = getelementptr inbounds double, double* %80, i64 %83
%85 = load double, double* %84
%86 = fadd double %85, %79
store double %86, double* %84
br label %87
87: ; preds = %38
%88 = load i32, i32* %9
%89 = add nsw i32 %88, 2
store i32 %89, i32* %9
br label %34
90: ; preds = %34
%91 = load double*, double** %6
%92 = load i32, i32* %5
%93 = add nsw i32 %92, 1
%94 = sext i32 %93 to i64
%95 = getelementptr inbounds double, double* %91, i64 %94
%96 = load double, double* %95
%97 = load double*, double** %7
%98 = load i32, i32* %5
%99 = add nsw i32 %98, 1
%100 = sext i32 %99 to i64
%101 = getelementptr inbounds double, double* %97, i64 %100
%102 = load double, double* %101
%103 = load double*, double** %8
%104 = load i32, i32* %5
%105 = add nsw i32 %104, 1
%106 = sext i32 %105 to i64
%107 = getelementptr inbounds double, double* %103, i64 %106
%108 = load double, double* %107
%109 = call double @llvm.fmuladd.f64(double %96, double %102, double %108)
store double %109, double* %107
ret void
}

LLVM IR (-O2):
define void @mp_mul_cmuladd(i32 %0, double* nocapture %1, double* nocapture %2, double* nocapture %3) {
%5 = getelementptr inbounds double, double* %1, i64 1
%6 = load double, double* %5
%7 = getelementptr inbounds double, double* %2, i64 1
%8 = load double, double* %7
%9 = getelementptr inbounds double, double* %3, i64 1
%10 = load double, double* %9
%11 = tail call double @llvm.fmuladd.f64(double %6, double %8, double %10)
store double %11, double* %9
%12 = getelementptr inbounds double, double* %1, i64 2
%13 = load double, double* %12
%14 = getelementptr inbounds double, double* %2, i64 2
%15 = load double, double* %14
%16 = getelementptr inbounds double, double* %3, i64 2
%17 = load double, double* %16
%18 = tail call double @llvm.fmuladd.f64(double %13, double %15, double %17)
store double %18, double* %16
%19 = icmp sgt i32 %0, 3
br i1 %19, label %20, label %111
20: ; preds = %4
%21 = zext i32 %0 to i64
%22 = call i64 @llvm.umax.i64(i64 %21, i64 5)
%23 = add nsw i64 %22, -4
%24 = lshr i64 %23, 1
%25 = add nuw nsw i64 %24, 1
%26 = icmp ult i64 %23, 2
br i1 %26, label %84, label %27
27: ; preds = %20
%28 = getelementptr double, double* %3, i64 3
%29 = call i64 @llvm.umax.i64(i64 %21, i64 5)
%30 = add nsw i64 %29, -4
%31 = and i64 %30, -2
%32 = add nuw nsw i64 %31, 5
%33 = getelementptr double, double* %3, i64 %32
%34 = getelementptr double, double* %1, i64 3
%35 = getelementptr double, double* %1, i64 %32
%36 = getelementptr double, double* %2, i64 3
%37 = getelementptr double, double* %2, i64 %32
%38 = icmp ult double* %28, %35
%39 = icmp ult double* %34, %33
%40 = and i1 %38, %39
%41 = icmp ult double* %28, %37
%42 = icmp ult double* %36, %33
%43 = and i1 %41, %42
%44 = or i1 %40, %43
br i1 %44, label %84, label %45
45: ; preds = %27
%46 = and i64 %25, 9223372036854775806
%47 = shl nuw i64 %25, 1
%48 = or i64 %47, 3
%49 = getelementptr inbounds double, double* %3, i64 -1
br label %50
50: ; preds = %50, %45
%51 = phi i64 [ 0, %45 ], [ %80, %50 ]
%52 = shl i64 %51, 1
%53 = or i64 %52, 3
%54 = getelementptr inbounds double, double* %1, i64 %53
%55 = bitcast double* %54 to <4 x double>*
%56 = load <4 x double>, <4 x double>* %55
%57 = shufflevector <4 x double> %56, <4 x double> poison, <2 x i32> <i32 0, i32 2>
%58 = shufflevector <4 x double> %56, <4 x double> poison, <2 x i32> <i32 1, i32 3>
%59 = add i64 %52, 4
%60 = getelementptr inbounds double, double* %2, i64 %53
%61 = bitcast double* %60 to <4 x double>*
%62 = load <4 x double>, <4 x double>* %61
%63 = shufflevector <4 x double> %62, <4 x double> poison, <2 x i32> <i32 0, i32 2>
%64 = shufflevector <4 x double> %62, <4 x double> poison, <2 x i32> <i32 1, i32 3>
%65 = fneg <2 x double> %58
%66 = fmul <2 x double> %64, %65
%67 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %57, <2 x double> %63, <2 x double> %66)
%68 = getelementptr inbounds double, double* %3, i64 %53
%69 = bitcast double* %68 to <4 x double>*
%70 = load <4 x double>, <4 x double>* %69
%71 = shufflevector <4 x double> %70, <4 x double> poison, <2 x i32> <i32 0, i32 2>
%72 = shufflevector <4 x double> %70, <4 x double> poison, <2 x i32> <i32 1, i32 3>
%73 = fadd <2 x double> %71, %67
%74 = fmul <2 x double> %58, %63
%75 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %57, <2 x double> %64, <2 x double> %74)
%76 = fadd <2 x double> %75, %72
%77 = getelementptr inbounds double, double* %49, i64 %59
%78 = bitcast double* %77 to <4 x double>*
%79 = shufflevector <2 x double> %73, <2 x double> %76, <4 x i32> <i32 0, i32 2, i32 1, i32 3>
store <4 x double> %79, <4 x double>* %78
%80 = add nuw i64 %51, 2
%81 = icmp eq i64 %80, %46
br i1 %81, label %82, label %50
82: ; preds = %50
%83 = icmp eq i64 %25, %46
br i1 %83, label %111, label %84
84: ; preds = %27, %20, %82
%85 = phi i64 [ 3, %27 ], [ 3, %20 ], [ %48, %82 ]
br label %86
86: ; preds = %84, %86
%87 = phi i64 [ %109, %86 ], [ %85, %84 ]
%88 = getelementptr inbounds double, double* %1, i64 %87
%89 = load double, double* %88
%90 = add nuw nsw i64 %87, 1
%91 = getelementptr inbounds double, double* %1, i64 %90
%92 = load double, double* %91
%93 = getelementptr inbounds double, double* %2, i64 %87
%94 = bitcast double* %93 to <2 x double>*
%95 = load <2 x double>, <2 x double>* %94
%96 = fneg double %92
%97 = getelementptr inbounds double, double* %3, i64 %87
%98 = insertelement <2 x double> poison, double %92, i64 0
%99 = insertelement <2 x double> %98, double %96, i64 1
%100 = fmul <2 x double> %95, %99
%101 = shufflevector <2 x double> %100, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%102 = insertelement <2 x double> poison, double %89, i64 0
%103 = shufflevector <2 x double> %102, <2 x double> poison, <2 x i32> zeroinitializer
%104 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %103, <2 x double> %95, <2 x double> %101)
%105 = bitcast double* %97 to <2 x double>*
%106 = load <2 x double>, <2 x double>* %105
%107 = fadd <2 x double> %106, %104
%108 = bitcast double* %97 to <2 x double>*
store <2 x double> %107, <2 x double>* %108
%109 = add nuw nsw i64 %87, 2
%110 = icmp ult i64 %109, %21
br i1 %110, label %86, label %111
111: ; preds = %86, %82, %4
%112 = add nsw i32 %0, 1
%113 = sext i32 %112 to i64
%114 = getelementptr inbounds double, double* %1, i64 %113
%115 = load double, double* %114
%116 = getelementptr inbounds double, double* %2, i64 %113
%117 = load double, double* %116
%118 = getelementptr inbounds double, double* %3, i64 %113
%119 = load double, double* %118
%120 = tail call double @llvm.fmuladd.f64(double %115, double %117, double %119)
store double %120, double* %118
ret void
}