double variance_2(int size, double **block, int atx, int aty) {
  int i, j;
  double sum2 = 0.0;
  double sum = 0.0;
  double mean2;
  double mean;
  for (i = atx; i < atx + size; i++)
    for (j = aty; j < aty + size; j++) {
      sum2 += block[i][j] * block[i][j];
      sum += block[i][j];
    }
  mean2 = sum2 / (size * size);
  mean = sum / (size * size);
  return mean2 - mean * mean;
}


x86 assembly (clang, -O0):
<variance_2>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    -0x14(%rbp),%ecx
add    -0x4(%rbp),%ecx
cmp    %ecx,%eax
jge    11cb <variance_2+0xcb>
mov    -0x18(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    -0x18(%rbp),%ecx
add    -0x4(%rbp),%ecx
cmp    %ecx,%eax
jge    11b8 <variance_2+0xb8>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x28(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    113e <variance_2+0x3e>
jmp    11bd <variance_2+0xbd>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1127 <variance_2+0x27>
movsd  -0x28(%rbp),%xmm0
mov    -0x4(%rbp),%eax
imul   -0x4(%rbp),%eax
cvtsi2sd %eax,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x30(%rbp),%xmm0
mov    -0x4(%rbp),%eax
imul   -0x4(%rbp),%eax
cvtsi2sd %eax,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x38(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<variance_2>:
test   %edi,%edi
jle    1155 <variance_2+0x55>
movslq %ecx,%r8
add    %edi,%ecx
movslq %ecx,%rcx
movslq %edx,%r10
add    %edi,%edx
movslq %edx,%r9
xorpd  %xmm1,%xmm1
xorpd  %xmm0,%xmm0
nopl   0x0(%rax)
mov    (%rsi,%r10,8),%rdx
mov    %r8,%rax
nopw   0x0(%rax,%rax,1)
movsd  (%rdx,%rax,8),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm2,%xmm2
addsd  %xmm2,%xmm0
add    $0x1,%rax
cmp    %rcx,%rax
jl     1130 <variance_2+0x30>
add    $0x1,%r10
cmp    %r9,%r10
jl     1120 <variance_2+0x20>
jmp    115d <variance_2+0x5d>
xorpd  %xmm0,%xmm0
xorpd  %xmm1,%xmm1
imul   %edi,%edi
xorps  %xmm2,%xmm2
cvtsi2sd %edi,%xmm2
divsd  %xmm2,%xmm0
divsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm1
subsd  %xmm1,%xmm0
ret

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

LLVM IR (-O2):
define double @variance_2(i32 %0, double** nocapture %1, i32 %2, i32 %3) {
%5 = icmp sgt i32 %0, 0
br i1 %5, label %6, label %32
6: ; preds = %4
%7 = add nsw i32 %2, %0
%8 = add nsw i32 %3, %0
%9 = sext i32 %3 to i64
%10 = sext i32 %8 to i64
%11 = sext i32 %2 to i64
%12 = sext i32 %7 to i64
br label %13
13: ; preds = %29, %6
%14 = phi i64 [ %11, %6 ], [ %30, %29 ]
%15 = phi double [ 0.000000e+00, %6 ], [ %26, %29 ]
%16 = phi double [ 0.000000e+00, %6 ], [ %25, %29 ]
%17 = getelementptr inbounds double*, double** %1, i64 %14
%18 = load double*, double** %17
br label %19
19: ; preds = %13, %19
%20 = phi i64 [ %9, %13 ], [ %27, %19 ]
%21 = phi double [ %15, %13 ], [ %26, %19 ]
%22 = phi double [ %16, %13 ], [ %25, %19 ]
%23 = getelementptr inbounds double, double* %18, i64 %20
%24 = load double, double* %23
%25 = tail call double @llvm.fmuladd.f64(double %24, double %24, double %22)
%26 = fadd double %21, %24
%27 = add nsw i64 %20, 1
%28 = icmp slt i64 %27, %10
br i1 %28, label %19, label %29
29: ; preds = %19
%30 = add nsw i64 %14, 1
%31 = icmp slt i64 %30, %12
br i1 %31, label %13, label %32
32: ; preds = %29, %4
%33 = phi double [ 0.000000e+00, %4 ], [ %25, %29 ]
%34 = phi double [ 0.000000e+00, %4 ], [ %26, %29 ]
%35 = mul nsw i32 %0, %0
%36 = sitofp i32 %35 to double
%37 = fdiv double %33, %36
%38 = fdiv double %34, %36
%39 = fneg double %38
%40 = tail call double @llvm.fmuladd.f64(double %39, double %38, double %37)
ret double %40
}