double third_auto(double *y, unsigned long n, long d1, long d2) {
  double autocorr = 0.0, mean = 0.0, skew = 0.0, ym;
  unsigned long i, maxd;
  maxd = d2;
  if (d1 > d2)
    maxd = d1;
  for (i = maxd; i < n; i++)
    mean += y[i];
  mean /= (double)(n - maxd);
  for (i = maxd; i < n; i++) {
    ym = y[i] - mean;
    skew += ym * ym * ym;
    autocorr += ym * (y[i - d1] - mean) * (y[i - d2] - mean);
  }
  return (autocorr / skew);
}


x86 assembly (clang, -O0):
<third_auto>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
jle    114a <third_auto+0x4a>
mov    -0x18(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    1188 <third_auto+0x88>
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x48(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x48(%rbp)
jmp    1152 <third_auto+0x52>
mov    -0x10(%rbp),%rax
mov    -0x50(%rbp),%rcx
sub    %rcx,%rax
movq   %rax,%xmm1
movaps 0xe61(%rip),%xmm0
punpckldq %xmm0,%xmm1
movapd 0xe65(%rip),%xmm0
subpd  %xmm0,%xmm1
movaps %xmm1,%xmm0
unpckhpd %xmm1,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x50(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    126e <third_auto+0x16e>
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x40(%rbp),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%rcx
sub    -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
subsd  -0x30(%rbp),%xmm1
mulsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%rcx
sub    -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
subsd  -0x30(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x48(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x48(%rbp)
jmp    11d0 <third_auto+0xd0>
movsd  -0x28(%rbp),%xmm0
divsd  -0x38(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<third_auto>:
cmp    %rcx,%rdx
mov    %rcx,%r8
cmovg  %rdx,%r8
movsd  0xeee(%rip),%xmm0
cmp    %rsi,%r8
jae    1238 <third_auto+0x138>
mov    %esi,%r10d
sub    %r8d,%r10d
mov    %r8,%r9
not    %r9
add    %rsi,%r9
xorpd  %xmm1,%xmm1
mov    %r8,%rax
and    $0x7,%r10
je     114f <third_auto+0x4f>
nopw   0x0(%rax,%rax,1)
addsd  (%rdi,%rax,8),%xmm1
add    $0x1,%rax
add    $0xffffffffffffffff,%r10
jne    1140 <third_auto+0x40>
cmp    $0x7,%r9
jb     1198 <third_auto+0x98>
cs nopw 0x0(%rax,%rax,1)
nop
addsd  (%rdi,%rax,8),%xmm1
addsd  0x8(%rdi,%rax,8),%xmm1
addsd  0x10(%rdi,%rax,8),%xmm1
addsd  0x18(%rdi,%rax,8),%xmm1
addsd  0x20(%rdi,%rax,8),%xmm1
addsd  0x28(%rdi,%rax,8),%xmm1
addsd  0x30(%rdi,%rax,8),%xmm1
addsd  0x38(%rdi,%rax,8),%xmm1
add    $0x8,%rax
cmp    %rax,%rsi
jne    1160 <third_auto+0x60>
mov    %rsi,%rax
sub    %r8,%rax
jbe    1238 <third_auto+0x138>
movq   %rax,%xmm0
punpckldq 0xe5f(%rip),%xmm0
subpd  0xe67(%rip),%xmm0
movapd %xmm0,%xmm2
unpckhpd %xmm0,%xmm2
addsd  %xmm0,%xmm2
divsd  %xmm2,%xmm1
movapd %xmm1,%xmm2
unpcklpd %xmm1,%xmm2
shl    $0x3,%rcx
mov    %rdi,%rax
sub    %rcx,%rax
shl    $0x3,%rdx
mov    %rdi,%rcx
sub    %rdx,%rcx
xorpd  %xmm0,%xmm0
nopl   0x0(%rax)
movsd  (%rcx,%r8,8),%xmm3
movhpd (%rdi,%r8,8),%xmm3
subpd  %xmm2,%xmm3
movapd %xmm3,%xmm4
unpckhpd %xmm3,%xmm4
mulpd  %xmm3,%xmm4
movsd  (%rax,%r8,8),%xmm5
subsd  %xmm1,%xmm5
shufpd $0x2,%xmm3,%xmm5
mulpd  %xmm4,%xmm5
addpd  %xmm5,%xmm0
add    $0x1,%r8
cmp    %r8,%rsi
jne    11f0 <third_auto+0xf0>
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
divsd  %xmm1,%xmm0
ret

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

LLVM IR (-O2):
define double @third_auto(double* nocapture %0, i64 %1, i64 %2, i64 %3) {
%5 = icmp sgt i64 %2, %3
%6 = select i1 %5, i64 %2, i64 %3
%7 = icmp ult i64 %6, %1
br i1 %7, label %8, label %98
8: ; preds = %4
%9 = sub i64 %1, %6
%10 = xor i64 %6, -1
%11 = add i64 %10, %1
%12 = and i64 %9, 7
%13 = icmp eq i64 %12, 0
br i1 %13, label %24, label %14
14: ; preds = %8, %14
%15 = phi i64 [ %21, %14 ], [ %6, %8 ]
%16 = phi double [ %20, %14 ], [ 0.000000e+00, %8 ]
%17 = phi i64 [ %22, %14 ], [ 0, %8 ]
%18 = getelementptr inbounds double, double* %0, i64 %15
%19 = load double, double* %18
%20 = fadd double %16, %19
%21 = add nuw i64 %15, 1
%22 = add i64 %17, 1
%23 = icmp eq i64 %22, %12
br i1 %23, label %24, label %14
24: ; preds = %14, %8
%25 = phi double [ undef, %8 ], [ %20, %14 ]
%26 = phi i64 [ %6, %8 ], [ %21, %14 ]
%27 = phi double [ 0.000000e+00, %8 ], [ %20, %14 ]
%28 = icmp ult i64 %11, 7
br i1 %28, label %65, label %29
29: ; preds = %24, %29
%30 = phi i64 [ %63, %29 ], [ %26, %24 ]
%31 = phi double [ %62, %29 ], [ %27, %24 ]
%32 = getelementptr inbounds double, double* %0, i64 %30
%33 = load double, double* %32
%34 = fadd double %31, %33
%35 = add nuw i64 %30, 1
%36 = getelementptr inbounds double, double* %0, i64 %35
%37 = load double, double* %36
%38 = fadd double %34, %37
%39 = add nuw i64 %30, 2
%40 = getelementptr inbounds double, double* %0, i64 %39
%41 = load double, double* %40
%42 = fadd double %38, %41
%43 = add nuw i64 %30, 3
%44 = getelementptr inbounds double, double* %0, i64 %43
%45 = load double, double* %44
%46 = fadd double %42, %45
%47 = add nuw i64 %30, 4
%48 = getelementptr inbounds double, double* %0, i64 %47
%49 = load double, double* %48
%50 = fadd double %46, %49
%51 = add nuw i64 %30, 5
%52 = getelementptr inbounds double, double* %0, i64 %51
%53 = load double, double* %52
%54 = fadd double %50, %53
%55 = add nuw i64 %30, 6
%56 = getelementptr inbounds double, double* %0, i64 %55
%57 = load double, double* %56
%58 = fadd double %54, %57
%59 = add nuw i64 %30, 7
%60 = getelementptr inbounds double, double* %0, i64 %59
%61 = load double, double* %60
%62 = fadd double %58, %61
%63 = add nuw i64 %30, 8
%64 = icmp eq i64 %63, %1
br i1 %64, label %65, label %29
65: ; preds = %29, %24
%66 = phi double [ %25, %24 ], [ %62, %29 ]
%67 = sub i64 %1, %6
%68 = uitofp i64 %67 to double
%69 = fdiv double %66, %68
br i1 %7, label %70, label %98
70: ; preds = %65
%71 = insertelement <2 x double> poison, double %69, i64 0
%72 = shufflevector <2 x double> %71, <2 x double> poison, <2 x i32> zeroinitializer
br label %73
73: ; preds = %70, %73
%74 = phi i64 [ %92, %73 ], [ %6, %70 ]
%75 = phi <2 x double> [ %91, %73 ], [ zeroinitializer, %70 ]
%76 = getelementptr inbounds double, double* %0, i64 %74
%77 = load double, double* %76
%78 = sub i64 %74, %2
%79 = getelementptr inbounds double, double* %0, i64 %78
%80 = load double, double* %79
%81 = insertelement <2 x double> poison, double %80, i64 0
%82 = insertelement <2 x double> %81, double %77, i64 1
%83 = fsub <2 x double> %82, %72
%84 = shufflevector <2 x double> %83, <2 x double> undef, <2 x i32> <i32 1, i32 1>
%85 = fmul <2 x double> %84, %83
%86 = sub i64 %74, %3
%87 = getelementptr inbounds double, double* %0, i64 %86
%88 = load double, double* %87
%89 = fsub double %88, %69
%90 = insertelement <2 x double> %83, double %89, i64 0
%91 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %85, <2 x double> %90, <2 x double> %75)
%92 = add nuw i64 %74, 1
%93 = icmp eq i64 %92, %1
br i1 %93, label %94, label %73
94: ; preds = %73
%95 = extractelement <2 x double> %91, i64 0
%96 = extractelement <2 x double> %91, i64 1
%97 = fdiv double %95, %96
br label %98
98: ; preds = %4, %94, %65
%99 = phi double [ %97, %94 ], [ 0x7FF8000000000000, %65 ], [ 0x7FF8000000000000, %4 ]
ret double %99
}