#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
double fabs(double);
double sqrt(double);
float coherenceWindowed(int len, float *data1, float *data2) {
  double sum1 = 0;
  double sum2 = 0;
  double sum3 = 0;
  for (int i = 0; i < len; i++) {
    sum1 += data1[i] * data2[i];
    sum2 += data1[i] * data1[i];
    sum3 += data2[i] * data2[i];
  }
  return (fabs(sum1) / 1.0 * (sqrt(sum2 * sum3)));
}


x86 assembly (clang, -O0):
<coherenceWindowed>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11d4 <coherenceWindowed+0xc4>
mov    -0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
mulss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
mulss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
mulss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1142 <coherenceWindowed+0x32>
movsd  -0x20(%rbp),%xmm0
movaps 0xe30(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  0xe14(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x30(%rbp),%xmm0
call   1030 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  -0x40(%rbp),%xmm0
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<coherenceWindowed>:
sub    $0x18,%rsp
xorpd  %xmm1,%xmm1
xorpd  %xmm6,%xmm6
xorpd  %xmm0,%xmm0
test   %edi,%edi
jle    11e8 <coherenceWindowed+0xd8>
mov    %edi,%eax
cmp    $0x1,%edi
jne    113b <coherenceWindowed+0x2b>
xorpd  %xmm6,%xmm6
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
jmp    11b2 <coherenceWindowed+0xa2>
mov    %eax,%edi
and    $0xfffffffe,%edi
xorpd  %xmm6,%xmm6
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
movss  (%rsi,%rcx,4),%xmm2
movss  0x4(%rsi,%rcx,4),%xmm3
movaps %xmm2,%xmm4
shufps $0x0,%xmm2,%xmm4
movss  (%rdx,%rcx,4),%xmm5
unpcklps %xmm5,%xmm2
mulps  %xmm4,%xmm2
cvtps2pd %xmm2,%xmm2
movss  0x4(%rdx,%rcx,4),%xmm4
addpd  %xmm6,%xmm2
mulss  %xmm5,%xmm5
cvtss2sd %xmm5,%xmm5
addsd  %xmm0,%xmm5
movaps %xmm3,%xmm0
shufps $0x0,%xmm3,%xmm0
unpcklps %xmm4,%xmm3
mulps  %xmm0,%xmm3
cvtps2pd %xmm3,%xmm6
addpd  %xmm2,%xmm6
mulss  %xmm4,%xmm4
xorps  %xmm0,%xmm0
cvtss2sd %xmm4,%xmm0
addsd  %xmm5,%xmm0
add    $0x2,%rcx
cmp    %rcx,%rdi
jne    1150 <coherenceWindowed+0x40>
test   $0x1,%al
je     11e0 <coherenceWindowed+0xd0>
movss  (%rdx,%rcx,4),%xmm2
movss  (%rsi,%rcx,4),%xmm3
movaps %xmm3,%xmm4
shufps $0x0,%xmm3,%xmm4
unpcklps %xmm2,%xmm3
mulps  %xmm4,%xmm3
cvtps2pd %xmm3,%xmm3
addpd  %xmm3,%xmm6
mulss  %xmm2,%xmm2
cvtss2sd %xmm2,%xmm2
addsd  %xmm2,%xmm0
mulsd  %xmm6,%xmm0
unpckhpd %xmm6,%xmm6
andpd  0xe10(%rip),%xmm6
ucomisd %xmm1,%xmm0
jb     11fc <coherenceWindowed+0xec>
sqrtsd %xmm0,%xmm0
jmp    120b <coherenceWindowed+0xfb>
movapd %xmm6,(%rsp)
call   1030 <sqrt@plt>
movapd (%rsp),%xmm6
mulsd  %xmm0,%xmm6
xorps  %xmm0,%xmm0
cvtsd2ss %xmm6,%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
define float @coherenceWindowed(i32 %0, float* %1, float* %2) {
%4 = alloca i32
%5 = alloca float*
%6 = alloca float*
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca i32
store i32 %0, i32* %4
store float* %1, float** %5
store float* %2, float** %6
store double 0.000000e+00, double* %7
store double 0.000000e+00, double* %8
store double 0.000000e+00, double* %9
store i32 0, i32* %10
br label %11
11: ; preds = %58, %3
%12 = load i32, i32* %10
%13 = load i32, i32* %4
%14 = icmp slt i32 %12, %13
br i1 %14, label %15, label %61
15: ; preds = %11
%16 = load float*, float** %5
%17 = load i32, i32* %10
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds float, float* %16, i64 %18
%20 = load float, float* %19
%21 = load float*, float** %6
%22 = load i32, i32* %10
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds float, float* %21, i64 %23
%25 = load float, float* %24
%26 = fmul float %20, %25
%27 = fpext float %26 to double
%28 = load double, double* %7
%29 = fadd double %28, %27
store double %29, double* %7
%30 = load float*, float** %5
%31 = load i32, i32* %10
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds float, float* %30, i64 %32
%34 = load float, float* %33
%35 = load float*, float** %5
%36 = load i32, i32* %10
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds float, float* %35, i64 %37
%39 = load float, float* %38
%40 = fmul float %34, %39
%41 = fpext float %40 to double
%42 = load double, double* %8
%43 = fadd double %42, %41
store double %43, double* %8
%44 = load float*, float** %6
%45 = load i32, i32* %10
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds float, float* %44, i64 %46
%48 = load float, float* %47
%49 = load float*, float** %6
%50 = load i32, i32* %10
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds float, float* %49, i64 %51
%53 = load float, float* %52
%54 = fmul float %48, %53
%55 = fpext float %54 to double
%56 = load double, double* %9
%57 = fadd double %56, %55
store double %57, double* %9
br label %58
58: ; preds = %15
%59 = load i32, i32* %10
%60 = add nsw i32 %59, 1
store i32 %60, i32* %10
br label %11
61: ; preds = %11
%62 = load double, double* %7
%63 = call double @llvm.fabs.f64(double %62)
%64 = fdiv double %63, 1.000000e+00
%65 = load double, double* %8
%66 = load double, double* %9
%67 = fmul double %65, %66
%68 = call double @sqrt(double %67)
%69 = fmul double %64, %68
%70 = fptrunc double %69 to float
ret float %70
}

LLVM IR (-O2):
define float @coherenceWindowed(i32 %0, float* nocapture %1, float* nocapture %2) {
%4 = icmp sgt i32 %0, 0
br i1 %4, label %5, label %38
5: ; preds = %3
%6 = zext i32 %0 to i64
%7 = and i64 %6, 1
%8 = icmp eq i32 %0, 1
br i1 %8, label %11, label %9
9: ; preds = %5
%10 = and i64 %6, 4294967294
br label %45
11: ; preds = %45, %5
%12 = phi <2 x double> [ undef, %5 ], [ %73, %45 ]
%13 = phi double [ undef, %5 ], [ %76, %45 ]
%14 = phi i64 [ 0, %5 ], [ %77, %45 ]
%15 = phi double [ 0.000000e+00, %5 ], [ %76, %45 ]
%16 = phi <2 x double> [ zeroinitializer, %5 ], [ %73, %45 ]
%17 = icmp eq i64 %7, 0
br i1 %17, label %32, label %18
18: ; preds = %11
%19 = getelementptr inbounds float, float* %1, i64 %14
%20 = load float, float* %19
%21 = getelementptr inbounds float, float* %2, i64 %14
%22 = load float, float* %21
%23 = insertelement <2 x float> poison, float %20, i64 0
%24 = shufflevector <2 x float> %23, <2 x float> poison, <2 x i32> zeroinitializer
%25 = insertelement <2 x float> %23, float %22, i64 1
%26 = fmul <2 x float> %24, %25
%27 = fpext <2 x float> %26 to <2 x double>
%28 = fadd <2 x double> %16, %27
%29 = fmul float %22, %22
%30 = fpext float %29 to double
%31 = fadd double %15, %30
br label %32
32: ; preds = %11, %18
%33 = phi <2 x double> [ %12, %11 ], [ %28, %18 ]
%34 = phi double [ %13, %11 ], [ %31, %18 ]
%35 = extractelement <2 x double> %33, i64 0
%36 = fmul double %35, %34
%37 = extractelement <2 x double> %33, i64 1
br label %38
38: ; preds = %32, %3
%39 = phi double [ 0.000000e+00, %3 ], [ %37, %32 ]
%40 = phi double [ 0.000000e+00, %3 ], [ %36, %32 ]
%41 = tail call double @llvm.fabs.f64(double %39)
%42 = tail call double @sqrt(double %40)
%43 = fmul double %41, %42
%44 = fptrunc double %43 to float
ret float %44
45: ; preds = %45, %9
%46 = phi i64 [ 0, %9 ], [ %77, %45 ]
%47 = phi double [ 0.000000e+00, %9 ], [ %76, %45 ]
%48 = phi <2 x double> [ zeroinitializer, %9 ], [ %73, %45 ]
%49 = phi i64 [ 0, %9 ], [ %78, %45 ]
%50 = getelementptr inbounds float, float* %1, i64 %46
%51 = load float, float* %50
%52 = getelementptr inbounds float, float* %2, i64 %46
%53 = load float, float* %52
%54 = insertelement <2 x float> poison, float %51, i64 0
%55 = shufflevector <2 x float> %54, <2 x float> poison, <2 x i32> zeroinitializer
%56 = insertelement <2 x float> %54, float %53, i64 1
%57 = fmul <2 x float> %55, %56
%58 = fpext <2 x float> %57 to <2 x double>
%59 = fadd <2 x double> %48, %58
%60 = fmul float %53, %53
%61 = fpext float %60 to double
%62 = fadd double %47, %61
%63 = or i64 %46, 1
%64 = getelementptr inbounds float, float* %1, i64 %63
%65 = load float, float* %64
%66 = getelementptr inbounds float, float* %2, i64 %63
%67 = load float, float* %66
%68 = insertelement <2 x float> poison, float %65, i64 0
%69 = shufflevector <2 x float> %68, <2 x float> poison, <2 x i32> zeroinitializer
%70 = insertelement <2 x float> %68, float %67, i64 1
%71 = fmul <2 x float> %69, %70
%72 = fpext <2 x float> %71 to <2 x double>
%73 = fadd <2 x double> %59, %72
%74 = fmul float %67, %67
%75 = fpext float %74 to double
%76 = fadd double %62, %75
%77 = add nuw nsw i64 %46, 2
%78 = add i64 %49, 2
%79 = icmp eq i64 %78, %10
br i1 %79, label %11, label %45
}