double tvsqspec_diffpoint(long pos, long chan, double diff, const int nchan,
                          const long imsize, const double *image) {
  double temp = 0.0;
  if (chan == nchan) {
    temp =
        (image[chan * imsize + pos] + diff - image[(chan - 1) * imsize + pos]) *
        (image[chan * imsize + pos] + diff - image[(chan - 1) * imsize + pos]);
    return temp;
  }
  if (chan == 0) {
    temp = (image[imsize + pos] - image[pos] - diff) *
           (image[imsize + pos] - image[pos] - diff);
    return temp;
  }
  temp =
      (image[chan * imsize + pos] + diff - image[(chan - 1) * imsize + pos]) *
          (image[chan * imsize + pos] + diff -
           image[(chan - 1) * imsize + pos]) +
      (image[(chan + 1) * imsize + pos] - image[chan * imsize + pos] - diff) *
          (image[(chan + 1) * imsize + pos] - image[chan * imsize + pos] -
           diff);
  return temp;
}


x86 assembly (clang, -O0):
<tvsqspec_diffpoint>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movsd  %xmm0,-0x20(%rbp)
mov    %edx,-0x24(%rbp)
mov    %rcx,-0x30(%rbp)
mov    %r8,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
cmp    %rcx,%rax
jne    11b7 <tvsqspec_diffpoint+0xb7>
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x20(%rbp),%xmm0
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
addsd  -0x20(%rbp),%xmm1
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    130f <tvsqspec_diffpoint+0x20f>
cmpq   $0x0,-0x18(%rbp)
jne    1220 <tvsqspec_diffpoint+0x120>
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x38(%rbp),%rax
mov    -0x10(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
subsd  -0x20(%rbp),%xmm0
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x38(%rbp),%rax
mov    -0x10(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm1
subsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    130f <tvsqspec_diffpoint+0x20f>
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x20(%rbp),%xmm0
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
addsd  -0x20(%rbp),%xmm2
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm2
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
add    $0x1,%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm1
subsd  -0x20(%rbp),%xmm1
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
add    $0x1,%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm3
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
imul   -0x30(%rbp),%rcx
add    -0x10(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm3
subsd  -0x20(%rbp),%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<tvsqspec_diffpoint>:
movslq %edx,%rax
cmp    %rsi,%rax
jne    112e <tvsqspec_diffpoint+0x2e>
mov    %rcx,%rax
imul   %rsi,%rax
add    %rdi,%rax
addsd  (%r8,%rax,8),%xmm0
add    $0xffffffffffffffff,%rsi
imul   %rcx,%rsi
add    %rdi,%rsi
subsd  (%r8,%rsi,8),%xmm0
mulsd  %xmm0,%xmm0
ret
test   %rsi,%rsi
je     1182 <tvsqspec_diffpoint+0x82>
mov    %rcx,%rax
imul   %rsi,%rax
add    %rdi,%rax
movsd  (%r8,%rax,8),%xmm1
lea    -0x1(%rsi),%rax
add    $0x1,%rsi
imul   %rcx,%rsi
add    %rdi,%rsi
movsd  (%r8,%rsi,8),%xmm2
subsd  %xmm1,%xmm2
addsd  %xmm0,%xmm1
imul   %rcx,%rax
add    %rdi,%rax
subsd  (%r8,%rax,8),%xmm1
subsd  %xmm0,%xmm2
mulsd  %xmm2,%xmm2
mulsd  %xmm1,%xmm1
addsd  %xmm2,%xmm1
movapd %xmm1,%xmm0
ret
add    %rdi,%rcx
movsd  (%r8,%rcx,8),%xmm1
subsd  (%r8,%rdi,8),%xmm1
subsd  %xmm0,%xmm1
mulsd  %xmm1,%xmm1
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @tvsqspec_diffpoint(i64 %0, i64 %1, double %2, i32 %3, i64 %4, double* %5) {
%7 = alloca double
%8 = alloca i64
%9 = alloca i64
%10 = alloca double
%11 = alloca i32
%12 = alloca i64
%13 = alloca double*
%14 = alloca double
store i64 %0, i64* %8
store i64 %1, i64* %9
store double %2, double* %10
store i32 %3, i32* %11
store i64 %4, i64* %12
store double* %5, double** %13
store double 0.000000e+00, double* %14
%15 = load i64, i64* %9
%16 = load i32, i32* %11
%17 = sext i32 %16 to i64
%18 = icmp eq i64 %15, %17
br i1 %18, label %19, label %62
19: ; preds = %6
%20 = load double*, double** %13
%21 = load i64, i64* %9
%22 = load i64, i64* %12
%23 = mul nsw i64 %21, %22
%24 = load i64, i64* %8
%25 = add nsw i64 %23, %24
%26 = getelementptr inbounds double, double* %20, i64 %25
%27 = load double, double* %26
%28 = load double, double* %10
%29 = fadd double %27, %28
%30 = load double*, double** %13
%31 = load i64, i64* %9
%32 = sub nsw i64 %31, 1
%33 = load i64, i64* %12
%34 = mul nsw i64 %32, %33
%35 = load i64, i64* %8
%36 = add nsw i64 %34, %35
%37 = getelementptr inbounds double, double* %30, i64 %36
%38 = load double, double* %37
%39 = fsub double %29, %38
%40 = load double*, double** %13
%41 = load i64, i64* %9
%42 = load i64, i64* %12
%43 = mul nsw i64 %41, %42
%44 = load i64, i64* %8
%45 = add nsw i64 %43, %44
%46 = getelementptr inbounds double, double* %40, i64 %45
%47 = load double, double* %46
%48 = load double, double* %10
%49 = fadd double %47, %48
%50 = load double*, double** %13
%51 = load i64, i64* %9
%52 = sub nsw i64 %51, 1
%53 = load i64, i64* %12
%54 = mul nsw i64 %52, %53
%55 = load i64, i64* %8
%56 = add nsw i64 %54, %55
%57 = getelementptr inbounds double, double* %50, i64 %56
%58 = load double, double* %57
%59 = fsub double %49, %58
%60 = fmul double %39, %59
store double %60, double* %14
%61 = load double, double* %14
store double %61, double* %7
br label %178
62: ; preds = %6
%63 = load i64, i64* %9
%64 = icmp eq i64 %63, 0
br i1 %64, label %65, label %94
65: ; preds = %62
%66 = load double*, double** %13
%67 = load i64, i64* %12
%68 = load i64, i64* %8
%69 = add nsw i64 %67, %68
%70 = getelementptr inbounds double, double* %66, i64 %69
%71 = load double, double* %70
%72 = load double*, double** %13
%73 = load i64, i64* %8
%74 = getelementptr inbounds double, double* %72, i64 %73
%75 = load double, double* %74
%76 = fsub double %71, %75
%77 = load double, double* %10
%78 = fsub double %76, %77
%79 = load double*, double** %13
%80 = load i64, i64* %12
%81 = load i64, i64* %8
%82 = add nsw i64 %80, %81
%83 = getelementptr inbounds double, double* %79, i64 %82
%84 = load double, double* %83
%85 = load double*, double** %13
%86 = load i64, i64* %8
%87 = getelementptr inbounds double, double* %85, i64 %86
%88 = load double, double* %87
%89 = fsub double %84, %88
%90 = load double, double* %10
%91 = fsub double %89, %90
%92 = fmul double %78, %91
store double %92, double* %14
%93 = load double, double* %14
store double %93, double* %7
br label %178
94: ; preds = %62
%95 = load double*, double** %13
%96 = load i64, i64* %9
%97 = load i64, i64* %12
%98 = mul nsw i64 %96, %97
%99 = load i64, i64* %8
%100 = add nsw i64 %98, %99
%101 = getelementptr inbounds double, double* %95, i64 %100
%102 = load double, double* %101
%103 = load double, double* %10
%104 = fadd double %102, %103
%105 = load double*, double** %13
%106 = load i64, i64* %9
%107 = sub nsw i64 %106, 1
%108 = load i64, i64* %12
%109 = mul nsw i64 %107, %108
%110 = load i64, i64* %8
%111 = add nsw i64 %109, %110
%112 = getelementptr inbounds double, double* %105, i64 %111
%113 = load double, double* %112
%114 = fsub double %104, %113
%115 = load double*, double** %13
%116 = load i64, i64* %9
%117 = load i64, i64* %12
%118 = mul nsw i64 %116, %117
%119 = load i64, i64* %8
%120 = add nsw i64 %118, %119
%121 = getelementptr inbounds double, double* %115, i64 %120
%122 = load double, double* %121
%123 = load double, double* %10
%124 = fadd double %122, %123
%125 = load double*, double** %13
%126 = load i64, i64* %9
%127 = sub nsw i64 %126, 1
%128 = load i64, i64* %12
%129 = mul nsw i64 %127, %128
%130 = load i64, i64* %8
%131 = add nsw i64 %129, %130
%132 = getelementptr inbounds double, double* %125, i64 %131
%133 = load double, double* %132
%134 = fsub double %124, %133
%135 = load double*, double** %13
%136 = load i64, i64* %9
%137 = add nsw i64 %136, 1
%138 = load i64, i64* %12
%139 = mul nsw i64 %137, %138
%140 = load i64, i64* %8
%141 = add nsw i64 %139, %140
%142 = getelementptr inbounds double, double* %135, i64 %141
%143 = load double, double* %142
%144 = load double*, double** %13
%145 = load i64, i64* %9
%146 = load i64, i64* %12
%147 = mul nsw i64 %145, %146
%148 = load i64, i64* %8
%149 = add nsw i64 %147, %148
%150 = getelementptr inbounds double, double* %144, i64 %149
%151 = load double, double* %150
%152 = fsub double %143, %151
%153 = load double, double* %10
%154 = fsub double %152, %153
%155 = load double*, double** %13
%156 = load i64, i64* %9
%157 = add nsw i64 %156, 1
%158 = load i64, i64* %12
%159 = mul nsw i64 %157, %158
%160 = load i64, i64* %8
%161 = add nsw i64 %159, %160
%162 = getelementptr inbounds double, double* %155, i64 %161
%163 = load double, double* %162
%164 = load double*, double** %13
%165 = load i64, i64* %9
%166 = load i64, i64* %12
%167 = mul nsw i64 %165, %166
%168 = load i64, i64* %8
%169 = add nsw i64 %167, %168
%170 = getelementptr inbounds double, double* %164, i64 %169
%171 = load double, double* %170
%172 = fsub double %163, %171
%173 = load double, double* %10
%174 = fsub double %172, %173
%175 = fmul double %154, %174
%176 = call double @llvm.fmuladd.f64(double %114, double %134, double %175)
store double %176, double* %14
%177 = load double, double* %14
store double %177, double* %7
br label %178
178: ; preds = %94, %65, %19
%179 = load double, double* %7
ret double %179
}

LLVM IR (-O2):
define double @tvsqspec_diffpoint(i64 %0, i64 %1, double %2, i32 %3, i64 %4, double* nocapture %5) {
%7 = sext i32 %3 to i64
%8 = icmp eq i64 %7, %1
br i1 %8, label %9, label %22
9: ; preds = %6
%10 = mul nsw i64 %4, %1
%11 = add nsw i64 %10, %0
%12 = getelementptr inbounds double, double* %5, i64 %11
%13 = load double, double* %12
%14 = fadd double %13, %2
%15 = add nsw i64 %1, -1
%16 = mul nsw i64 %15, %4
%17 = add nsw i64 %16, %0
%18 = getelementptr inbounds double, double* %5, i64 %17
%19 = load double, double* %18
%20 = fsub double %14, %19
%21 = fmul double %20, %20
br label %54
22: ; preds = %6
%23 = icmp eq i64 %1, 0
br i1 %23, label %24, label %33
24: ; preds = %22
%25 = add nsw i64 %4, %0
%26 = getelementptr inbounds double, double* %5, i64 %25
%27 = load double, double* %26
%28 = getelementptr inbounds double, double* %5, i64 %0
%29 = load double, double* %28
%30 = fsub double %27, %29
%31 = fsub double %30, %2
%32 = fmul double %31, %31
br label %54
33: ; preds = %22
%34 = mul nsw i64 %4, %1
%35 = add nsw i64 %34, %0
%36 = getelementptr inbounds double, double* %5, i64 %35
%37 = load double, double* %36
%38 = fadd double %37, %2
%39 = add nsw i64 %1, -1
%40 = mul nsw i64 %39, %4
%41 = add nsw i64 %40, %0
%42 = getelementptr inbounds double, double* %5, i64 %41
%43 = load double, double* %42
%44 = fsub double %38, %43
%45 = add nsw i64 %1, 1
%46 = mul nsw i64 %45, %4
%47 = add nsw i64 %46, %0
%48 = getelementptr inbounds double, double* %5, i64 %47
%49 = load double, double* %48
%50 = fsub double %49, %37
%51 = fsub double %50, %2
%52 = fmul double %51, %51
%53 = tail call double @llvm.fmuladd.f64(double %44, double %44, double %52)
br label %54
54: ; preds = %33, %24, %9
%55 = phi double [ %21, %9 ], [ %32, %24 ], [ %53, %33 ]
ret double %55
}