void bgsub_classify(unsigned char *image, int size, float *m, float *bgsub) {
  int i;
  for (i = 0; i < size; ++i) {
    bgsub[i] = (image[i] - m[i]) * (image[i] - m[i]);
  }
}


x86 assembly (clang, -O0):
<bgsub_classify>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    117f <bgsub_classify+0x7f>
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cvtsi2ss %eax,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
subss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cvtsi2ss %eax,%xmm1
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
subss  (%rax,%rcx,4),%xmm1
mulss  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    111a <bgsub_classify+0x1a>
pop    %rbp
ret

x86 assembly (clang, -O2):
<bgsub_classify>:
test   %esi,%esi
jle    12e0 <bgsub_classify+0x1e0>
mov    %esi,%r8d
cmp    $0x8,%esi
jae    1193 <bgsub_classify+0x93>
xor    %esi,%esi
mov    %rsi,%r9
not    %r9
test   $0x1,%r8b
je     113f <bgsub_classify+0x3f>
movzbl (%rdi,%rsi,1),%eax
xorps  %xmm0,%xmm0
cvtsi2ss %eax,%xmm0
subss  (%rdx,%rsi,4),%xmm0
mulss  %xmm0,%xmm0
movss  %xmm0,(%rcx,%rsi,4)
or     $0x1,%rsi
add    %r8,%r9
je     12e0 <bgsub_classify+0x1e0>
nopl   0x0(%rax,%rax,1)
movzbl (%rdi,%rsi,1),%eax
xorps  %xmm0,%xmm0
cvtsi2ss %eax,%xmm0
subss  (%rdx,%rsi,4),%xmm0
mulss  %xmm0,%xmm0
movss  %xmm0,(%rcx,%rsi,4)
movzbl 0x1(%rdi,%rsi,1),%eax
xorps  %xmm0,%xmm0
cvtsi2ss %eax,%xmm0
subss  0x4(%rdx,%rsi,4),%xmm0
mulss  %xmm0,%xmm0
movss  %xmm0,0x4(%rcx,%rsi,4)
add    $0x2,%rsi
cmp    %rsi,%r8
jne    1150 <bgsub_classify+0x50>
jmp    12e0 <bgsub_classify+0x1e0>
lea    (%rcx,%r8,4),%rsi
lea    (%rdi,%r8,1),%rax
cmp    %rcx,%rax
seta   %r10b
lea    (%rdx,%r8,4),%rax
cmp    %rdi,%rsi
seta   %r11b
cmp    %rcx,%rax
seta   %al
cmp    %rdx,%rsi
seta   %r9b
xor    %esi,%esi
test   %r11b,%r10b
jne    1116 <bgsub_classify+0x16>
and    %r9b,%al
jne    1116 <bgsub_classify+0x16>
mov    %r8d,%esi
and    $0xfffffff8,%esi
lea    -0x8(%rsi),%rax
mov    %rax,%r9
shr    $0x3,%r9
add    $0x1,%r9
test   %rax,%rax
je     12e1 <bgsub_classify+0x1e1>
mov    %r9,%r10
and    $0xfffffffffffffffe,%r10
xor    %eax,%eax
pxor   %xmm0,%xmm0
nopl   0x0(%rax)
movd   (%rdi,%rax,1),%xmm1
movd   0x4(%rdi,%rax,1),%xmm2
punpcklbw %xmm0,%xmm1
punpcklwd %xmm0,%xmm1
cvtdq2ps %xmm1,%xmm1
punpcklbw %xmm0,%xmm2
punpcklwd %xmm0,%xmm2
cvtdq2ps %xmm2,%xmm2
movups (%rdx,%rax,4),%xmm3
subps  %xmm3,%xmm1
movups 0x10(%rdx,%rax,4),%xmm3
subps  %xmm3,%xmm2
mulps  %xmm1,%xmm1
mulps  %xmm2,%xmm2
movups %xmm1,(%rcx,%rax,4)
movups %xmm2,0x10(%rcx,%rax,4)
movd   0x8(%rdi,%rax,1),%xmm1
movd   0xc(%rdi,%rax,1),%xmm2
punpcklbw %xmm0,%xmm1
punpcklwd %xmm0,%xmm1
cvtdq2ps %xmm1,%xmm1
punpcklbw %xmm0,%xmm2
punpcklwd %xmm0,%xmm2
cvtdq2ps %xmm2,%xmm2
movups 0x20(%rdx,%rax,4),%xmm3
subps  %xmm3,%xmm1
movups 0x30(%rdx,%rax,4),%xmm3
subps  %xmm3,%xmm2
mulps  %xmm1,%xmm1
mulps  %xmm2,%xmm2
movups %xmm1,0x20(%rcx,%rax,4)
movups %xmm2,0x30(%rcx,%rax,4)
add    $0x10,%rax
add    $0xfffffffffffffffe,%r10
jne    1200 <bgsub_classify+0x100>
test   $0x1,%r9b
je     12d7 <bgsub_classify+0x1d7>
movd   (%rdi,%rax,1),%xmm0
movd   0x4(%rdi,%rax,1),%xmm1
xorps  %xmm2,%xmm2
punpcklbw %xmm2,%xmm0
punpcklwd %xmm2,%xmm0
cvtdq2ps %xmm0,%xmm0
punpcklbw %xmm2,%xmm1
punpcklwd %xmm2,%xmm1
cvtdq2ps %xmm1,%xmm1
movups (%rdx,%rax,4),%xmm2
subps  %xmm2,%xmm0
movups 0x10(%rdx,%rax,4),%xmm2
subps  %xmm2,%xmm1
mulps  %xmm0,%xmm0
mulps  %xmm1,%xmm1
movups %xmm0,(%rcx,%rax,4)
movups %xmm1,0x10(%rcx,%rax,4)
cmp    %r8,%rsi
jne    1116 <bgsub_classify+0x16>
ret
xor    %eax,%eax
test   $0x1,%r9b
jne    1295 <bgsub_classify+0x195>
jmp    12d7 <bgsub_classify+0x1d7>

LLVM IR (-O0):
define void @bgsub_classify(i8* %0, i32 %1, float* %2, float* %3) {
%5 = alloca i8*
%6 = alloca i32
%7 = alloca float*
%8 = alloca float*
%9 = alloca i32
store i8* %0, i8** %5
store i32 %1, i32* %6
store float* %2, float** %7
store float* %3, float** %8
store i32 0, i32* %9
br label %10
10: ; preds = %46, %4
%11 = load i32, i32* %9
%12 = load i32, i32* %6
%13 = icmp slt i32 %11, %12
br i1 %13, label %14, label %49
14: ; preds = %10
%15 = load i8*, i8** %5
%16 = load i32, i32* %9
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %15, i64 %17
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
%21 = sitofp i32 %20 to float
%22 = load float*, float** %7
%23 = load i32, i32* %9
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds float, float* %22, i64 %24
%26 = load float, float* %25
%27 = fsub float %21, %26
%28 = load i8*, i8** %5
%29 = load i32, i32* %9
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds i8, i8* %28, i64 %30
%32 = load i8, i8* %31
%33 = zext i8 %32 to i32
%34 = sitofp i32 %33 to float
%35 = load float*, float** %7
%36 = load i32, i32* %9
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds float, float* %35, i64 %37
%39 = load float, float* %38
%40 = fsub float %34, %39
%41 = fmul float %27, %40
%42 = load float*, float** %8
%43 = load i32, i32* %9
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds float, float* %42, i64 %44
store float %41, float* %45
br label %46
46: ; preds = %14
%47 = load i32, i32* %9
%48 = add nsw i32 %47, 1
store i32 %48, i32* %9
br label %10
49: ; preds = %10
ret void
}

LLVM IR (-O2):
define void @bgsub_classify(i8* nocapture %0, i32 %1, float* nocapture %2, float* nocapture writeonly %3) {
%5 = bitcast float* %3 to i8*
%6 = icmp sgt i32 %1, 0
br i1 %6, label %7, label %150
7: ; preds = %4
%8 = zext i32 %1 to i64
%9 = icmp ult i32 %1, 8
br i1 %9, label %110, label %10
10: ; preds = %7
%11 = getelementptr float, float* %3, i64 %8
%12 = bitcast float* %11 to i8*
%13 = getelementptr i8, i8* %0, i64 %8
%14 = getelementptr float, float* %2, i64 %8
%15 = icmp ugt i8* %13, %5
%16 = icmp ugt i8* %12, %0
%17 = and i1 %15, %16
%18 = icmp ugt float* %14, %3
%19 = icmp ugt float* %11, %2
%20 = and i1 %18, %19
%21 = or i1 %17, %20
br i1 %21, label %110, label %22
22: ; preds = %10
%23 = and i64 %8, 4294967288
%24 = add nsw i64 %23, -8
%25 = lshr exact i64 %24, 3
%26 = add nuw nsw i64 %25, 1
%27 = and i64 %26, 1
%28 = icmp eq i64 %24, 0
br i1 %28, label %82, label %29
29: ; preds = %22
%30 = and i64 %26, 4611686018427387902
br label %31
31: ; preds = %31, %29
%32 = phi i64 [ 0, %29 ], [ %79, %31 ]
%33 = phi i64 [ 0, %29 ], [ %80, %31 ]
%34 = getelementptr inbounds i8, i8* %0, i64 %32
%35 = bitcast i8* %34 to <4 x i8>*
%36 = load <4 x i8>, <4 x i8>* %35
%37 = getelementptr inbounds i8, i8* %34, i64 4
%38 = bitcast i8* %37 to <4 x i8>*
%39 = load <4 x i8>, <4 x i8>* %38
%40 = uitofp <4 x i8> %36 to <4 x float>
%41 = uitofp <4 x i8> %39 to <4 x float>
%42 = getelementptr inbounds float, float* %2, i64 %32
%43 = bitcast float* %42 to <4 x float>*
%44 = load <4 x float>, <4 x float>* %43
%45 = getelementptr inbounds float, float* %42, i64 4
%46 = bitcast float* %45 to <4 x float>*
%47 = load <4 x float>, <4 x float>* %46
%48 = fsub <4 x float> %40, %44
%49 = fsub <4 x float> %41, %47
%50 = fmul <4 x float> %48, %48
%51 = fmul <4 x float> %49, %49
%52 = getelementptr inbounds float, float* %3, i64 %32
%53 = bitcast float* %52 to <4 x float>*
store <4 x float> %50, <4 x float>* %53
%54 = getelementptr inbounds float, float* %52, i64 4
%55 = bitcast float* %54 to <4 x float>*
store <4 x float> %51, <4 x float>* %55
%56 = or i64 %32, 8
%57 = getelementptr inbounds i8, i8* %0, i64 %56
%58 = bitcast i8* %57 to <4 x i8>*
%59 = load <4 x i8>, <4 x i8>* %58
%60 = getelementptr inbounds i8, i8* %57, i64 4
%61 = bitcast i8* %60 to <4 x i8>*
%62 = load <4 x i8>, <4 x i8>* %61
%63 = uitofp <4 x i8> %59 to <4 x float>
%64 = uitofp <4 x i8> %62 to <4 x float>
%65 = getelementptr inbounds float, float* %2, i64 %56
%66 = bitcast float* %65 to <4 x float>*
%67 = load <4 x float>, <4 x float>* %66
%68 = getelementptr inbounds float, float* %65, i64 4
%69 = bitcast float* %68 to <4 x float>*
%70 = load <4 x float>, <4 x float>* %69
%71 = fsub <4 x float> %63, %67
%72 = fsub <4 x float> %64, %70
%73 = fmul <4 x float> %71, %71
%74 = fmul <4 x float> %72, %72
%75 = getelementptr inbounds float, float* %3, i64 %56
%76 = bitcast float* %75 to <4 x float>*
store <4 x float> %73, <4 x float>* %76
%77 = getelementptr inbounds float, float* %75, i64 4
%78 = bitcast float* %77 to <4 x float>*
store <4 x float> %74, <4 x float>* %78
%79 = add nuw i64 %32, 16
%80 = add i64 %33, 2
%81 = icmp eq i64 %80, %30
br i1 %81, label %82, label %31
82: ; preds = %31, %22
%83 = phi i64 [ 0, %22 ], [ %79, %31 ]
%84 = icmp eq i64 %27, 0
br i1 %84, label %108, label %85
85: ; preds = %82
%86 = getelementptr inbounds i8, i8* %0, i64 %83
%87 = bitcast i8* %86 to <4 x i8>*
%88 = load <4 x i8>, <4 x i8>* %87
%89 = getelementptr inbounds i8, i8* %86, i64 4
%90 = bitcast i8* %89 to <4 x i8>*
%91 = load <4 x i8>, <4 x i8>* %90
%92 = uitofp <4 x i8> %88 to <4 x float>
%93 = uitofp <4 x i8> %91 to <4 x float>
%94 = getelementptr inbounds float, float* %2, i64 %83
%95 = bitcast float* %94 to <4 x float>*
%96 = load <4 x float>, <4 x float>* %95
%97 = getelementptr inbounds float, float* %94, i64 4
%98 = bitcast float* %97 to <4 x float>*
%99 = load <4 x float>, <4 x float>* %98
%100 = fsub <4 x float> %92, %96
%101 = fsub <4 x float> %93, %99
%102 = fmul <4 x float> %100, %100
%103 = fmul <4 x float> %101, %101
%104 = getelementptr inbounds float, float* %3, i64 %83
%105 = bitcast float* %104 to <4 x float>*
store <4 x float> %102, <4 x float>* %105
%106 = getelementptr inbounds float, float* %104, i64 4
%107 = bitcast float* %106 to <4 x float>*
store <4 x float> %103, <4 x float>* %107
br label %108
108: ; preds = %82, %85
%109 = icmp eq i64 %23, %8
br i1 %109, label %150, label %110
110: ; preds = %10, %7, %108
%111 = phi i64 [ 0, %10 ], [ 0, %7 ], [ %23, %108 ]
%112 = xor i64 %111, -1
%113 = and i64 %8, 1
%114 = icmp eq i64 %113, 0
br i1 %114, label %125, label %115
115: ; preds = %110
%116 = getelementptr inbounds i8, i8* %0, i64 %111
%117 = load i8, i8* %116
%118 = uitofp i8 %117 to float
%119 = getelementptr inbounds float, float* %2, i64 %111
%120 = load float, float* %119
%121 = fsub float %118, %120
%122 = fmul float %121, %121
%123 = getelementptr inbounds float, float* %3, i64 %111
store float %122, float* %123
%124 = or i64 %111, 1
br label %125
125: ; preds = %115, %110
%126 = phi i64 [ %111, %110 ], [ %124, %115 ]
%127 = sub nsw i64 0, %8
%128 = icmp eq i64 %112, %127
br i1 %128, label %150, label %129
129: ; preds = %125, %129
%130 = phi i64 [ %148, %129 ], [ %126, %125 ]
%131 = getelementptr inbounds i8, i8* %0, i64 %130
%132 = load i8, i8* %131
%133 = uitofp i8 %132 to float
%134 = getelementptr inbounds float, float* %2, i64 %130
%135 = load float, float* %134
%136 = fsub float %133, %135
%137 = fmul float %136, %136
%138 = getelementptr inbounds float, float* %3, i64 %130
store float %137, float* %138
%139 = add nuw nsw i64 %130, 1
%140 = getelementptr inbounds i8, i8* %0, i64 %139
%141 = load i8, i8* %140
%142 = uitofp i8 %141 to float
%143 = getelementptr inbounds float, float* %2, i64 %139
%144 = load float, float* %143
%145 = fsub float %142, %144
%146 = fmul float %145, %145
%147 = getelementptr inbounds float, float* %3, i64 %139
store float %146, float* %147
%148 = add nuw nsw i64 %130, 2
%149 = icmp eq i64 %148, %8
br i1 %149, label %150, label %129
150: ; preds = %125, %129, %108, %4
ret void
}