double covariance_s(const double *restrict in0, const double *restrict in1,
                    const double *restrict weight, double missval1,
                    double missval2, long gridsize) {
  long i;
  double sum0, sum1, sum01, wsum0, wsum00;
  double out;
  sum0 = sum1 = sum01 = 0;
  wsum0 = wsum00 = 0;
  for (i = 0; i < gridsize; ++i) {
    if ((weight[i] < missval1 || missval1 < weight[i]) &&
        (in0[i] < missval1 || missval1 < in0[i]) &&
        (in1[i] < missval2 || missval2 < in1[i])) {
      sum0 += weight[i] * in0[i];
      sum1 += weight[i] * in1[i];
      sum01 += weight[i] * in0[i] * in1[i];
      wsum0 += weight[i];
      wsum00 += weight[i] * weight[i];
    }
  }
  out = (wsum0 < 0 || 0 < wsum0)
            ? (sum01 * wsum0 - sum0 * sum1) / (wsum0 * wsum0)
            : missval1;
  return (out);
}


x86 assembly (clang, -O0):
<covariance_s>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movsd  %xmm0,-0x20(%rbp)
movsd  %xmm1,-0x28(%rbp)
mov    %rcx,-0x30(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x60(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x30(%rbp),%rax
jge    12ee <covariance_s+0x1ee>
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
movsd  -0x20(%rbp),%xmm0
ucomisd %xmm1,%xmm0
ja     1194 <covariance_s+0x94>
movsd  -0x20(%rbp),%xmm1
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
jbe    12d8 <covariance_s+0x1d8>
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
movsd  -0x20(%rbp),%xmm0
ucomisd %xmm1,%xmm0
ja     11cc <covariance_s+0xcc>
movsd  -0x20(%rbp),%xmm1
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
jbe    12d8 <covariance_s+0x1d8>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
movsd  -0x28(%rbp),%xmm0
ucomisd %xmm1,%xmm0
ja     1204 <covariance_s+0x104>
movsd  -0x28(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
jbe    12d8 <covariance_s+0x1d8>
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x48(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x50(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x60(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    12dd <covariance_s+0x1dd>
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    114e <covariance_s+0x4e>
xorps  %xmm0,%xmm0
ucomisd -0x58(%rbp),%xmm0
ja     130e <covariance_s+0x20e>
movsd  -0x58(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1359 <covariance_s+0x259>
movsd  -0x50(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  -0x48(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x58(%rbp),%xmm1
mulsd  -0x58(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
jmp    1363 <covariance_s+0x263>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x68(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<covariance_s>:
test   %rcx,%rcx
jle    119e <covariance_s+0x9e>
xorpd  %xmm8,%xmm8
xorpd  %xmm2,%xmm2
xor    %eax,%eax
xorpd  %xmm3,%xmm3
jmp    1129 <covariance_s+0x29>
nopw   0x0(%rax,%rax,1)
add    $0x1,%rax
cmp    %rax,%rcx
je     1171 <covariance_s+0x71>
movsd  (%rdx,%rax,8),%xmm5
ucomisd %xmm5,%xmm0
je     1120 <covariance_s+0x20>
movsd  (%rdi,%rax,8),%xmm6
ucomisd %xmm6,%xmm0
je     1120 <covariance_s+0x20>
movsd  (%rsi,%rax,8),%xmm7
ucomisd %xmm7,%xmm1
je     1120 <covariance_s+0x20>
movapd %xmm5,%xmm4
unpcklpd %xmm5,%xmm4
addsd  %xmm5,%xmm2
mulsd  %xmm6,%xmm5
unpcklpd %xmm7,%xmm6
mulpd  %xmm4,%xmm6
addpd  %xmm6,%xmm8
mulsd  %xmm7,%xmm5
addsd  %xmm5,%xmm3
jmp    1120 <covariance_s+0x20>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm2
je     119e <covariance_s+0x9e>
movapd %xmm8,%xmm0
unpckhpd %xmm8,%xmm0
mulsd  %xmm8,%xmm0
mulsd  %xmm2,%xmm3
subsd  %xmm0,%xmm3
mulsd  %xmm2,%xmm2
divsd  %xmm2,%xmm3
movapd %xmm3,%xmm0
ret

LLVM IR (-O0):
define double @covariance_s(double* noalias %0, double* noalias %1, double* noalias %2, double %3, double %4, i64 %5) {
%7 = alloca double*
%8 = alloca double*
%9 = alloca double*
%10 = alloca double
%11 = alloca double
%12 = alloca i64
%13 = alloca i64
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca double
store double* %0, double** %7
store double* %1, double** %8
store double* %2, double** %9
store double %3, double* %10
store double %4, double* %11
store i64 %5, i64* %12
store double 0.000000e+00, double* %16
store double 0.000000e+00, double* %15
store double 0.000000e+00, double* %14
store double 0.000000e+00, double* %18
store double 0.000000e+00, double* %17
store i64 0, i64* %13
br label %20
20: ; preds = %119, %6
%21 = load i64, i64* %13
%22 = load i64, i64* %12
%23 = icmp slt i64 %21, %22
br i1 %23, label %24, label %122
24: ; preds = %20
%25 = load double*, double** %9
%26 = load i64, i64* %13
%27 = getelementptr inbounds double, double* %25, i64 %26
%28 = load double, double* %27
%29 = load double, double* %10
%30 = fcmp olt double %28, %29
br i1 %30, label %38, label %31
31: ; preds = %24
%32 = load double, double* %10
%33 = load double*, double** %9
%34 = load i64, i64* %13
%35 = getelementptr inbounds double, double* %33, i64 %34
%36 = load double, double* %35
%37 = fcmp olt double %32, %36
br i1 %37, label %38, label %118
38: ; preds = %31, %24
%39 = load double*, double** %7
%40 = load i64, i64* %13
%41 = getelementptr inbounds double, double* %39, i64 %40
%42 = load double, double* %41
%43 = load double, double* %10
%44 = fcmp olt double %42, %43
br i1 %44, label %52, label %45
45: ; preds = %38
%46 = load double, double* %10
%47 = load double*, double** %7
%48 = load i64, i64* %13
%49 = getelementptr inbounds double, double* %47, i64 %48
%50 = load double, double* %49
%51 = fcmp olt double %46, %50
br i1 %51, label %52, label %118
52: ; preds = %45, %38
%53 = load double*, double** %8
%54 = load i64, i64* %13
%55 = getelementptr inbounds double, double* %53, i64 %54
%56 = load double, double* %55
%57 = load double, double* %11
%58 = fcmp olt double %56, %57
br i1 %58, label %66, label %59
59: ; preds = %52
%60 = load double, double* %11
%61 = load double*, double** %8
%62 = load i64, i64* %13
%63 = getelementptr inbounds double, double* %61, i64 %62
%64 = load double, double* %63
%65 = fcmp olt double %60, %64
br i1 %65, label %66, label %118
66: ; preds = %59, %52
%67 = load double*, double** %9
%68 = load i64, i64* %13
%69 = getelementptr inbounds double, double* %67, i64 %68
%70 = load double, double* %69
%71 = load double*, double** %7
%72 = load i64, i64* %13
%73 = getelementptr inbounds double, double* %71, i64 %72
%74 = load double, double* %73
%75 = load double, double* %14
%76 = call double @llvm.fmuladd.f64(double %70, double %74, double %75)
store double %76, double* %14
%77 = load double*, double** %9
%78 = load i64, i64* %13
%79 = getelementptr inbounds double, double* %77, i64 %78
%80 = load double, double* %79
%81 = load double*, double** %8
%82 = load i64, i64* %13
%83 = getelementptr inbounds double, double* %81, i64 %82
%84 = load double, double* %83
%85 = load double, double* %15
%86 = call double @llvm.fmuladd.f64(double %80, double %84, double %85)
store double %86, double* %15
%87 = load double*, double** %9
%88 = load i64, i64* %13
%89 = getelementptr inbounds double, double* %87, i64 %88
%90 = load double, double* %89
%91 = load double*, double** %7
%92 = load i64, i64* %13
%93 = getelementptr inbounds double, double* %91, i64 %92
%94 = load double, double* %93
%95 = fmul double %90, %94
%96 = load double*, double** %8
%97 = load i64, i64* %13
%98 = getelementptr inbounds double, double* %96, i64 %97
%99 = load double, double* %98
%100 = load double, double* %16
%101 = call double @llvm.fmuladd.f64(double %95, double %99, double %100)
store double %101, double* %16
%102 = load double*, double** %9
%103 = load i64, i64* %13
%104 = getelementptr inbounds double, double* %102, i64 %103
%105 = load double, double* %104
%106 = load double, double* %17
%107 = fadd double %106, %105
store double %107, double* %17
%108 = load double*, double** %9
%109 = load i64, i64* %13
%110 = getelementptr inbounds double, double* %108, i64 %109
%111 = load double, double* %110
%112 = load double*, double** %9
%113 = load i64, i64* %13
%114 = getelementptr inbounds double, double* %112, i64 %113
%115 = load double, double* %114
%116 = load double, double* %18
%117 = call double @llvm.fmuladd.f64(double %111, double %115, double %116)
store double %117, double* %18
br label %118
118: ; preds = %66, %59, %45, %31
br label %119
119: ; preds = %118
%120 = load i64, i64* %13
%121 = add nsw i64 %120, 1
store i64 %121, i64* %13
br label %20
122: ; preds = %20
%123 = load double, double* %17
%124 = fcmp olt double %123, 0.000000e+00
br i1 %124, label %128, label %125
125: ; preds = %122
%126 = load double, double* %17
%127 = fcmp olt double 0.000000e+00, %126
br i1 %127, label %128, label %140
128: ; preds = %125, %122
%129 = load double, double* %16
%130 = load double, double* %17
%131 = load double, double* %14
%132 = load double, double* %15
%133 = fmul double %131, %132
%134 = fneg double %133
%135 = call double @llvm.fmuladd.f64(double %129, double %130, double %134)
%136 = load double, double* %17
%137 = load double, double* %17
%138 = fmul double %136, %137
%139 = fdiv double %135, %138
br label %142
140: ; preds = %125
%141 = load double, double* %10
br label %142
142: ; preds = %140, %128
%143 = phi double [ %139, %128 ], [ %141, %140 ]
store double %143, double* %19
%144 = load double, double* %19
ret double %144
}

LLVM IR (-O2):
define double @covariance_s(double* noalias nocapture %0, double* noalias nocapture %1, double* noalias nocapture %2, double %3, double %4, i64 %5) {
%7 = icmp sgt i64 %5, 0
br i1 %7, label %8, label %49
8: ; preds = %6, %33
%9 = phi i64 [ %37, %33 ], [ 0, %6 ]
%10 = phi double [ %35, %33 ], [ 0.000000e+00, %6 ]
%11 = phi double [ %34, %33 ], [ 0.000000e+00, %6 ]
%12 = phi <2 x double> [ %36, %33 ], [ zeroinitializer, %6 ]
%13 = getelementptr inbounds double, double* %2, i64 %9
%14 = load double, double* %13
%15 = fcmp ueq double %14, %3
br i1 %15, label %33, label %16
16: ; preds = %8
%17 = getelementptr inbounds double, double* %0, i64 %9
%18 = load double, double* %17
%19 = fcmp ueq double %18, %3
br i1 %19, label %33, label %20
20: ; preds = %16
%21 = getelementptr inbounds double, double* %1, i64 %9
%22 = load double, double* %21
%23 = fcmp ueq double %22, %4
br i1 %23, label %33, label %24
24: ; preds = %20
%25 = insertelement <2 x double> poison, double %14, i64 0
%26 = shufflevector <2 x double> %25, <2 x double> poison, <2 x i32> zeroinitializer
%27 = insertelement <2 x double> poison, double %18, i64 0
%28 = insertelement <2 x double> %27, double %22, i64 1
%29 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %26, <2 x double> %28, <2 x double> %12)
%30 = fmul double %14, %18
%31 = tail call double @llvm.fmuladd.f64(double %30, double %22, double %11)
%32 = fadd double %10, %14
br label %33
33: ; preds = %20, %16, %8, %24
%34 = phi double [ %31, %24 ], [ %11, %8 ], [ %11, %16 ], [ %11, %20 ]
%35 = phi double [ %32, %24 ], [ %10, %8 ], [ %10, %16 ], [ %10, %20 ]
%36 = phi <2 x double> [ %29, %24 ], [ %12, %8 ], [ %12, %16 ], [ %12, %20 ]
%37 = add nuw nsw i64 %9, 1
%38 = icmp eq i64 %37, %5
br i1 %38, label %39, label %8
39: ; preds = %33
%40 = fcmp ueq double %35, 0.000000e+00
br i1 %40, label %49, label %41
41: ; preds = %39
%42 = extractelement <2 x double> %36, i64 0
%43 = fneg double %42
%44 = extractelement <2 x double> %36, i64 1
%45 = fmul double %44, %43
%46 = tail call double @llvm.fmuladd.f64(double %34, double %35, double %45)
%47 = fmul double %35, %35
%48 = fdiv double %46, %47
br label %49
49: ; preds = %6, %39, %41
%50 = phi double [ %48, %41 ], [ %3, %39 ], [ %3, %6 ]
ret double %50
}