void vector_fmul_window_c(float *dst, const float *src0, const float *src1,
                          const float *win, int len) {
  int i, j;
  dst += len;
  win += len;
  src0 += len;
  for (i = -len, j = len - 1; i < 0; i++, j--) {
    float s0 = src0[i];
    float s1 = src1[j];
    float wi = win[i];
    float wj = win[j];
    dst[i] = s0 * wj - s1 * wi;
    dst[j] = s0 * wi + s1 * wj;
  }
}


x86 assembly (clang, -O0):
<vector_fmul_window_c>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8d,-0x24(%rbp)
mov    -0x24(%rbp),%ecx
mov    -0x8(%rbp),%rax
movslq %ecx,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x8(%rbp)
mov    -0x24(%rbp),%ecx
mov    -0x20(%rbp),%rax
movslq %ecx,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x24(%rbp),%ecx
mov    -0x10(%rbp),%rax
movslq %ecx,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x10(%rbp)
xor    %eax,%eax
sub    -0x24(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    -0x24(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x2c(%rbp)
cmpl   $0x0,-0x28(%rbp)
jge    1230 <vector_fmul_window_c+0x130>
mov    -0x10(%rbp),%rax
movslq -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x34(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x38(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x30(%rbp),%xmm0
movss  -0x3c(%rbp),%xmm2
movss  -0x34(%rbp),%xmm1
mulss  -0x38(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movslq -0x28(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movss  -0x30(%rbp),%xmm0
movss  -0x38(%rbp),%xmm2
movss  -0x34(%rbp),%xmm1
mulss  -0x3c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x2c(%rbp)
jmp    1168 <vector_fmul_window_c+0x68>
pop    %rbp
ret

x86 assembly (clang, -O2):
<vector_fmul_window_c>:
test   %r8d,%r8d
jle    116a <vector_fmul_window_c+0x6a>
movslq %r8d,%rax
mov    %r8d,%r8d
lea    (%rdx,%rax,4),%r9
add    $0xfffffffffffffffc,%r9
lea    -0x4(,%rax,8),%rax
ff
xor    %edx,%edx
nopl   (%rax)
movss  (%rsi,%rdx,4),%xmm0
movss  (%r9),%xmm1
movss  (%rcx,%rdx,4),%xmm2
movss  (%rcx,%rax,1),%xmm3
movaps %xmm0,%xmm4
mulss  %xmm2,%xmm0
mulss  %xmm1,%xmm2
mulss  %xmm3,%xmm4
subss  %xmm2,%xmm4
movss  %xmm4,(%rdi,%rdx,4)
mulss  %xmm3,%xmm1
addss  %xmm1,%xmm0
movss  %xmm0,(%rdi,%rax,1)
add    $0x1,%rdx
add    $0xfffffffffffffffc,%r9
add    $0xfffffffffffffffc,%rax
cmp    %edx,%r8d
jne    1120 <vector_fmul_window_c+0x20>
ret

LLVM IR (-O0):
define void @vector_fmul_window_c(float* %0, float* %1, float* %2, float* %3, i32 %4) {
%6 = alloca float*
%7 = alloca float*
%8 = alloca float*
%9 = alloca float*
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca float
%14 = alloca float
%15 = alloca float
%16 = alloca float
store float* %0, float** %6
store float* %1, float** %7
store float* %2, float** %8
store float* %3, float** %9
store i32 %4, i32* %10
%17 = load i32, i32* %10
%18 = load float*, float** %6
%19 = sext i32 %17 to i64
%20 = getelementptr inbounds float, float* %18, i64 %19
store float* %20, float** %6
%21 = load i32, i32* %10
%22 = load float*, float** %9
%23 = sext i32 %21 to i64
%24 = getelementptr inbounds float, float* %22, i64 %23
store float* %24, float** %9
%25 = load i32, i32* %10
%26 = load float*, float** %7
%27 = sext i32 %25 to i64
%28 = getelementptr inbounds float, float* %26, i64 %27
store float* %28, float** %7
%29 = load i32, i32* %10
%30 = sub nsw i32 0, %29
store i32 %30, i32* %11
%31 = load i32, i32* %10
%32 = sub nsw i32 %31, 1
store i32 %32, i32* %12
br label %33
33: ; preds = %78, %5
%34 = load i32, i32* %11
%35 = icmp slt i32 %34, 0
br i1 %35, label %36, label %83
36: ; preds = %33
%37 = load float*, float** %7
%38 = load i32, i32* %11
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds float, float* %37, i64 %39
%41 = load float, float* %40
store float %41, float* %13
%42 = load float*, float** %8
%43 = load i32, i32* %12
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds float, float* %42, i64 %44
%46 = load float, float* %45
store float %46, float* %14
%47 = load float*, float** %9
%48 = load i32, i32* %11
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds float, float* %47, i64 %49
%51 = load float, float* %50
store float %51, float* %15
%52 = load float*, float** %9
%53 = load i32, i32* %12
%54 = sext i32 %53 to i64
%55 = getelementptr inbounds float, float* %52, i64 %54
%56 = load float, float* %55
store float %56, float* %16
%57 = load float, float* %13
%58 = load float, float* %16
%59 = load float, float* %14
%60 = load float, float* %15
%61 = fmul float %59, %60
%62 = fneg float %61
%63 = call float @llvm.fmuladd.f32(float %57, float %58, float %62)
%64 = load float*, float** %6
%65 = load i32, i32* %11
%66 = sext i32 %65 to i64
%67 = getelementptr inbounds float, float* %64, i64 %66
store float %63, float* %67
%68 = load float, float* %13
%69 = load float, float* %15
%70 = load float, float* %14
%71 = load float, float* %16
%72 = fmul float %70, %71
%73 = call float @llvm.fmuladd.f32(float %68, float %69, float %72)
%74 = load float*, float** %6
%75 = load i32, i32* %12
%76 = sext i32 %75 to i64
%77 = getelementptr inbounds float, float* %74, i64 %76
store float %73, float* %77
br label %78
78: ; preds = %36
%79 = load i32, i32* %11
%80 = add nsw i32 %79, 1
store i32 %80, i32* %11
%81 = load i32, i32* %12
%82 = add nsw i32 %81, -1
store i32 %82, i32* %12
br label %33
83: ; preds = %33
ret void
}

LLVM IR (-O2):
define void @vector_fmul_window_c(float* nocapture writeonly %0, float* nocapture %1, float* nocapture %2, float* nocapture %3, i32 %4) {
%6 = sext i32 %4 to i64
%7 = getelementptr inbounds float, float* %0, i64 %6
%8 = getelementptr inbounds float, float* %3, i64 %6
%9 = getelementptr inbounds float, float* %1, i64 %6
%10 = icmp sgt i32 %4, 0
br i1 %10, label %11, label %36
11: ; preds = %5
%12 = sub nsw i32 0, %4
%13 = sext i32 %12 to i64
br label %14
14: ; preds = %11, %14
%15 = phi i64 [ %13, %11 ], [ %33, %14 ]
%16 = phi i64 [ %6, %11 ], [ %17, %14 ]
%17 = add nsw i64 %16, -1
%18 = getelementptr inbounds float, float* %9, i64 %15
%19 = load float, float* %18
%20 = getelementptr inbounds float, float* %2, i64 %17
%21 = load float, float* %20
%22 = getelementptr inbounds float, float* %8, i64 %15
%23 = load float, float* %22
%24 = getelementptr inbounds float, float* %8, i64 %17
%25 = load float, float* %24
%26 = fneg float %21
%27 = fmul float %23, %26
%28 = tail call float @llvm.fmuladd.f32(float %19, float %25, float %27)
%29 = getelementptr inbounds float, float* %7, i64 %15
store float %28, float* %29
%30 = fmul float %21, %25
%31 = tail call float @llvm.fmuladd.f32(float %19, float %23, float %30)
%32 = getelementptr inbounds float, float* %7, i64 %17
store float %31, float* %32
%33 = add nsw i64 %15, 1
%34 = trunc i64 %33 to i32
%35 = icmp eq i32 %34, 0
br i1 %35, label %36, label %14
36: ; preds = %14, %5
ret void
}