#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
double fabs(int);
double gauss_gradients(float *, int, double, double, double, int);
int /*<<< orphan*/ printf(char *, ...);
int gauss_fit(float *y, int n_points, float *mu_fit, float *sig_fit,
              float *scale_fit) {
  double x[3];
  double dx[] = {5.0, 1.0, .5};
  double smallest_grad[] = {1.0, 1.0, 1.0};
  double step, grad;
  double s;
  int old_direction, new_direction;
  int i, j;
  int count_down = 200;
  x[0] = (double)(*mu_fit);
  x[1] = (double)(*sig_fit);
  x[2] = (double)(*scale_fit);
  do {
    s = gauss_gradients(y, n_points, x[0], x[1], x[2], 3);
    if (s < -1.0e20) {
      return 0;
    }
    for (i = 0; i < 3; i++) {
      grad = gauss_gradients(y, n_points, x[0], x[1], x[2], i);
      if (grad < -1.0e20) {
        return 0;
      }
      if (grad == 0.0) {
        break;
      } else if (grad > 0.0) {
        new_direction = 1;
        step = -dx[i];
      } else {
        new_direction = -1;
        step = dx[i];
      }
      while (fabs(grad) > smallest_grad[i]) {
        old_direction = new_direction;
        while (new_direction == old_direction) {
          x[i] += step;
          grad = gauss_gradients(y, n_points, x[0], x[1], x[2], i);
          if (grad < -1.0e20) {
            return 0;
          }
          if (grad == 0.0) {
            break;
          } else if (grad > 0.0) {
            new_direction = 1;
          } else {
            new_direction = -1;
          }
        }
        step *= (-.5);
      }
    }
    if ((fabs(gauss_gradients(y, n_points, x[0], x[1], x[2], 0) <
              smallest_grad[0])) &&
        (fabs(gauss_gradients(y, n_points, x[0], x[1], x[2], 1) <
              smallest_grad[1])) &&
        (fabs(gauss_gradients(y, n_points, x[0], x[1], x[2], 2) <
              smallest_grad[2]))) {
      j = 1;
    } else {
      j = 0;
    }
    count_down--;
    if (count_down == 0) {
      printf("Fit taking too long.\n");
      return 0;
    }
  } while (j == 0);
  s = gauss_gradients(y, n_points, x[0], x[1], x[2], 3);
  printf("Final Params: mu=%e, sig=%e, scale=%e (S=%e)\n", x[0], x[1], x[2], s);
  (*mu_fit) = (float)x[0];
  (*sig_fit) = (float)x[1];
  (*scale_fit) = (float)x[2];
  return 1;
}


x86 assembly (clang, -O0):
<gauss_fit>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
mov    0xebb(%rip),%rax
mov    %rax,-0x70(%rbp)
mov    0xeb8(%rip),%rax
mov    %rax,-0x68(%rbp)
mov    0xeb5(%rip),%rax
mov    %rax,-0x60(%rbp)
mov    0xeba(%rip),%rax
mov    %rax,-0x90(%rbp)
mov    0xeb4(%rip),%rax
mov    %rax,-0x88(%rbp)
mov    0xeae(%rip),%rax
mov    %rax,-0x80(%rbp)
movl   $0xc8,-0xbc(%rbp)
mov    -0x20(%rbp),%rax
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x28(%rbp),%rax
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x30(%rbp),%rax
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
mov    $0x3,%edx
call   1040 <gauss_gradients@plt>
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  0xdfd(%rip),%xmm0
ucomisd -0xa8(%rbp),%xmm0
ff
jbe    121d <gauss_fit+0xed>
movl   $0x0,-0x4(%rbp)
jmp    162b <gauss_fit+0x4fb>
movl   $0x0,-0xb4(%rbp)
cmpl   $0x3,-0xb4(%rbp)
jge    144d <gauss_fit+0x31d>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
mov    -0xb4(%rbp),%edx
call   1040 <gauss_gradients@plt>
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  0xd9b(%rip),%xmm0
ucomisd -0xa0(%rbp),%xmm0
ff
jbe    127f <gauss_fit+0x14f>
movl   $0x0,-0x4(%rbp)
jmp    162b <gauss_fit+0x4fb>
movsd  -0xa0(%rbp),%xmm0
ff
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    129f <gauss_fit+0x16f>
jp     129f <gauss_fit+0x16f>
jmp    144d <gauss_fit+0x31d>
movsd  -0xa0(%rbp),%xmm0
ff
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    12ef <gauss_fit+0x1bf>
movl   $0x1,-0xb0(%rbp)
movslq -0xb4(%rbp),%rax
movsd  -0x70(%rbp,%rax,8),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
jmp    130e <gauss_fit+0x1de>
movl   $0xffffffff,-0xb0(%rbp)
ff ff ff
movslq -0xb4(%rbp),%rax
movsd  -0x70(%rbp,%rax,8),%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
jmp    1313 <gauss_fit+0x1e3>
jmp    1318 <gauss_fit+0x1e8>
cvttsd2si -0xa0(%rbp),%edi
ff
call   1050 <fabs@plt>
movslq -0xb4(%rbp),%rax
ucomisd -0x90(%rbp,%rax,8),%xmm0
ff ff
jbe    1434 <gauss_fit+0x304>
mov    -0xb0(%rbp),%eax
mov    %eax,-0xac(%rbp)
mov    -0xb0(%rbp),%eax
cmp    -0xac(%rbp),%eax
jne    1417 <gauss_fit+0x2e7>
movsd  -0x98(%rbp),%xmm0
ff
movslq -0xb4(%rbp),%rax
addsd  -0x50(%rbp,%rax,8),%xmm0
movsd  %xmm0,-0x50(%rbp,%rax,8)
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
mov    -0xb4(%rbp),%edx
call   1040 <gauss_gradients@plt>
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  0xc5b(%rip),%xmm0
ucomisd -0xa0(%rbp),%xmm0
ff
jbe    13bf <gauss_fit+0x28f>
movl   $0x0,-0x4(%rbp)
jmp    162b <gauss_fit+0x4fb>
movsd  -0xa0(%rbp),%xmm0
ff
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    13df <gauss_fit+0x2af>
jp     13df <gauss_fit+0x2af>
jmp    1417 <gauss_fit+0x2e7>
movsd  -0xa0(%rbp),%xmm0
ff
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1403 <gauss_fit+0x2d3>
movl   $0x1,-0xb0(%rbp)
jmp    140d <gauss_fit+0x2dd>
movl   $0xffffffff,-0xb0(%rbp)
ff ff ff
jmp    1412 <gauss_fit+0x2e2>
jmp    1347 <gauss_fit+0x217>
movsd  0xbe9(%rip),%xmm0
mulsd  -0x98(%rbp),%xmm0
ff
movsd  %xmm0,-0x98(%rbp)
ff
jmp    1318 <gauss_fit+0x1e8>
jmp    1439 <gauss_fit+0x309>
mov    -0xb4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb4(%rbp)
jmp    1227 <gauss_fit+0xf7>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
xor    %edx,%edx
call   1040 <gauss_gradients@plt>
movaps %xmm0,%xmm1
movsd  -0x90(%rbp),%xmm0
ff
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <fabs@plt>
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    149e <gauss_fit+0x36e>
jp     149e <gauss_fit+0x36e>
jmp    1552 <gauss_fit+0x422>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
mov    $0x1,%edx
call   1040 <gauss_gradients@plt>
movaps %xmm0,%xmm1
movsd  -0x88(%rbp),%xmm0
ff
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <fabs@plt>
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    14f2 <gauss_fit+0x3c2>
jp     14f2 <gauss_fit+0x3c2>
jmp    1552 <gauss_fit+0x422>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
mov    $0x2,%edx
call   1040 <gauss_gradients@plt>
movaps %xmm0,%xmm1
movsd  -0x80(%rbp),%xmm0
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <fabs@plt>
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1543 <gauss_fit+0x413>
jp     1543 <gauss_fit+0x413>
jmp    1552 <gauss_fit+0x422>
movl   $0x1,-0xb8(%rbp)
jmp    155c <gauss_fit+0x42c>
movl   $0x0,-0xb8(%rbp)
mov    -0xbc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xbc(%rbp)
cmpl   $0x0,-0xbc(%rbp)
jne    1592 <gauss_fit+0x462>
lea    0xac9(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movl   $0x0,-0x4(%rbp)
jmp    162b <gauss_fit+0x4fb>
jmp    1597 <gauss_fit+0x467>
cmpl   $0x0,-0xb8(%rbp)
je     11d3 <gauss_fit+0xa3>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
mov    $0x3,%edx
call   1040 <gauss_gradients@plt>
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
movsd  -0xa8(%rbp),%xmm3
ff
lea    0xa74(%rip),%rdi
mov    $0x4,%al
call   1030 <printf@plt>
movsd  -0x50(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x20(%rbp),%rax
movss  %xmm0,(%rax)
movsd  -0x48(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,(%rax)
movsd  -0x40(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x30(%rbp),%rax
movss  %xmm0,(%rax)
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gauss_fit>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x88,%rsp
mov    %esi,%ebp
mov    %rdi,%rbx
mov    %rdx,0x68(%rsp)
movss  (%rdx),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,0x30(%rsp)
mov    %rcx,0x70(%rsp)
movss  (%rcx),%xmm1
cvtss2sd %xmm1,%xmm1
movsd  %xmm1,0x38(%rsp)
mov    %r8,0x78(%rsp)
movss  (%r8),%xmm2
cvtss2sd %xmm2,%xmm2
movsd  %xmm2,0x40(%rsp)
mov    $0xc8,%r14d
xor    %r13d,%r13d
mov    %rbx,%rdi
mov    %ebp,%esi
movsd  %xmm0,0x18(%rsp)
movsd  %xmm1,0x10(%rsp)
movsd  %xmm2,0x8(%rsp)
mov    $0x3,%edx
call   1050 <gauss_gradients@plt>
movsd  0xe3e(%rip),%xmm1
ucomisd %xmm0,%xmm1
ja     1468 <gauss_fit+0x328>
mov    %r14d,0x24(%rsp)
xor    %r14d,%r14d
mov    %rbx,%rdi
mov    %ebp,%esi
movsd  0x18(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
mov    %r14d,%edx
call   1050 <gauss_gradients@plt>
movapd %xmm0,%xmm1
movsd  0xe01(%rip),%xmm0
ucomisd %xmm1,%xmm0
ja     1468 <gauss_fit+0x328>
ucomisd 0xe07(%rip),%xmm1
jne    1219 <gauss_fit+0xd9>
jnp    136e <gauss_fit+0x22e>
movsd  %xmm1,0x28(%rsp)
cvttsd2si %xmm1,%edi
call   1060 <fabs@plt>
lea    0xe21(%rip),%rax
movsd  (%rax,%r14,8),%xmm1
movsd  %xmm1,0x80(%rsp)
ucomisd %xmm1,%xmm0
jbe    1360 <gauss_fit+0x220>
lea    0xde1(%rip),%rax
movsd  (%rax,%r14,8),%xmm1
xor    %eax,%eax
xorpd  %xmm0,%xmm0
movsd  0x28(%rsp),%xmm2
ucomisd %xmm0,%xmm2
seta   %cl
jbe    1272 <gauss_fit+0x132>
xorpd  0xdae(%rip),%xmm1
mov    %cl,%al
lea    (%rax,%rax,1),%r12d
add    $0xffffffff,%r12d
movsd  0x30(%rsp,%r14,8),%xmm0
movsd  %xmm0,0x28(%rsp)
movapd %xmm1,0x50(%rsp)
nop
movsd  0x28(%rsp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x28(%rsp)
movsd  %xmm0,0x30(%rsp,%r14,8)
movsd  0x30(%rsp),%xmm0
movsd  0x38(%rsp),%xmm1
movsd  0x40(%rsp),%xmm2
mov    %rbx,%rdi
mov    %ebp,%esi
movsd  %xmm0,0x18(%rsp)
movsd  %xmm1,0x10(%rsp)
movsd  %xmm2,0x8(%rsp)
mov    %r14d,%edx
call   1050 <gauss_gradients@plt>
movsd  0xd20(%rip),%xmm1
ucomisd %xmm0,%xmm1
ja     1468 <gauss_fit+0x328>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    12f6 <gauss_fit+0x1b6>
jnp    1320 <gauss_fit+0x1e0>
seta   %al
movzbl %al,%eax
lea    (%rax,%rax,1),%r15d
add    $0xffffffff,%r15d
cmp    %r12d,%r15d
movapd 0x50(%rsp),%xmm1
je     1290 <gauss_fit+0x150>
jmp    1329 <gauss_fit+0x1e9>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %r12d,%r15d
movapd 0x50(%rsp),%xmm1
mulsd  0xcd7(%rip),%xmm1
movapd %xmm1,0x50(%rsp)
cvttsd2si %xmm0,%edi
call   1060 <fabs@plt>
movapd 0x50(%rsp),%xmm1
ucomisd 0x80(%rsp),%xmm0
mov    %r15d,%r12d
ja     1289 <gauss_fit+0x149>
nopl   0x0(%rax,%rax,1)
add    $0x1,%r14
cmp    $0x3,%r14
jne    11d4 <gauss_fit+0x94>
mov    %rbx,%rdi
mov    %ebp,%esi
movsd  0x18(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
xor    %edx,%edx
call   1050 <gauss_gradients@plt>
xor    %edi,%edi
movsd  0xc7a(%rip),%xmm1
ucomisd %xmm0,%xmm1
seta   %dil
call   1060 <fabs@plt>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    13b3 <gauss_fit+0x273>
jnp    143b <gauss_fit+0x2fb>
mov    %rbx,%rdi
mov    %ebp,%esi
movsd  0x18(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
mov    $0x1,%edx
call   1050 <gauss_gradients@plt>
xor    %edi,%edi
movsd  0xc32(%rip),%xmm1
ucomisd %xmm0,%xmm1
seta   %dil
call   1060 <fabs@plt>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    13f7 <gauss_fit+0x2b7>
jnp    143b <gauss_fit+0x2fb>
mov    %rbx,%rdi
mov    %ebp,%esi
movsd  0x18(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
mov    $0x2,%edx
call   1050 <gauss_gradients@plt>
xor    %edi,%edi
movsd  0xbee(%rip),%xmm1
ucomisd %xmm0,%xmm1
seta   %dil
call   1060 <fabs@plt>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    147d <gauss_fit+0x33d>
jp     147d <gauss_fit+0x33d>
mov    0x24(%rsp),%r14d
add    $0xffffffff,%r14d
movsd  0x18(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
jne    1199 <gauss_fit+0x59>
lea    0xc33(%rip),%rdi
call   1030 <puts@plt>
mov    %r13d,%eax
add    $0x88,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
cmpl   $0x1,0x24(%rsp)
movsd  0x18(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
je     145c <gauss_fit+0x31c>
mov    %rbx,%rdi
mov    %ebp,%esi
movsd  %xmm0,0x18(%rsp)
movsd  %xmm1,0x10(%rsp)
movsd  %xmm2,0x8(%rsp)
mov    $0x3,%edx
call   1050 <gauss_gradients@plt>
movaps %xmm0,%xmm3
lea    0xba7(%rip),%rdi
movsd  0x18(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
mov    $0x4,%al
call   1040 <printf@plt>
movsd  0x18(%rsp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    0x68(%rsp),%rax
movss  %xmm0,(%rax)
movsd  0x10(%rsp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    0x70(%rsp),%rax
movss  %xmm0,(%rax)
movsd  0x8(%rsp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    0x78(%rsp),%rax
movss  %xmm0,(%rax)
mov    $0x1,%r13d
jmp    1468 <gauss_fit+0x328>

LLVM IR (-O0):
@__const.gauss_fit.dx = [3 x double] [double 5.000000e+00, double 1.000000e+00, double 5.000000e-01]
@__const.gauss_fit.smallest_grad = [3 x double] [double 1.000000e+00, double 1.000000e+00, double 1.000000e+00]
@.str = [22 x i8] c"Fit taking too long.\0A\00"
@.str.1 = [46 x i8] c"Final Params: mu=%e, sig=%e, scale=%e (S=%e)\0A\00"
define i32 @gauss_fit(float* %0, i32 %1, float* %2, float* %3, float* %4) {
%6 = alloca i32
%7 = alloca float*
%8 = alloca i32
%9 = alloca float*
%10 = alloca float*
%11 = alloca float*
%12 = alloca [3 x double]
%13 = alloca [3 x double]
%14 = alloca [3 x double]
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca i32
%19 = alloca i32
%20 = alloca i32
%21 = alloca i32
%22 = alloca i32
store float* %0, float** %7
store i32 %1, i32* %8
store float* %2, float** %9
store float* %3, float** %10
store float* %4, float** %11
%23 = bitcast [3 x double]* %13 to i8*
%24 = bitcast [3 x double]* %14 to i8*
store i32 200, i32* %22
%25 = load float*, float** %9
%26 = load float, float* %25
%27 = fpext float %26 to double
%28 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
store double %27, double* %28
%29 = load float*, float** %10
%30 = load float, float* %29
%31 = fpext float %30 to double
%32 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
store double %31, double* %32
%33 = load float*, float** %11
%34 = load float, float* %33
%35 = fpext float %34 to double
%36 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
store double %35, double* %36
br label %37
37: ; preds = %199, %5
%38 = load float*, float** %7
%39 = load i32, i32* %8
%40 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%41 = load double, double* %40
%42 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%43 = load double, double* %42
%44 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%45 = load double, double* %44
%46 = call double @gauss_gradients(float* %38, i32 %39, double %41, double %43, double %45, i32 3)
store double %46, double* %17
%47 = load double, double* %17
%48 = fcmp olt double %47, -1.000000e+20
br i1 %48, label %49, label %50
49: ; preds = %37
store i32 0, i32* %6
br label %232
50: ; preds = %37
store i32 0, i32* %20
br label %51
51: ; preds = %138, %50
%52 = load i32, i32* %20
%53 = icmp slt i32 %52, 3
br i1 %53, label %54, label %141
54: ; preds = %51
%55 = load float*, float** %7
%56 = load i32, i32* %8
%57 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%58 = load double, double* %57
%59 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%60 = load double, double* %59
%61 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%62 = load double, double* %61
%63 = load i32, i32* %20
%64 = call double @gauss_gradients(float* %55, i32 %56, double %58, double %60, double %62, i32 %63)
store double %64, double* %16
%65 = load double, double* %16
%66 = fcmp olt double %65, -1.000000e+20
br i1 %66, label %67, label %68
67: ; preds = %54
store i32 0, i32* %6
br label %232
68: ; preds = %54
%69 = load double, double* %16
%70 = fcmp oeq double %69, 0.000000e+00
br i1 %70, label %71, label %72
71: ; preds = %68
br label %141
72: ; preds = %68
%73 = load double, double* %16
%74 = fcmp ogt double %73, 0.000000e+00
br i1 %74, label %75, label %81
75: ; preds = %72
store i32 1, i32* %19
%76 = load i32, i32* %20
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds [3 x double], [3 x double]* %13, i64 0, i64 %77
%79 = load double, double* %78
%80 = fneg double %79
store double %80, double* %15
br label %86
81: ; preds = %72
store i32 -1, i32* %19
%82 = load i32, i32* %20
%83 = sext i32 %82 to i64
%84 = getelementptr inbounds [3 x double], [3 x double]* %13, i64 0, i64 %83
%85 = load double, double* %84
store double %85, double* %15
br label %86
86: ; preds = %81, %75
br label %87
87: ; preds = %86
br label %88
88: ; preds = %134, %87
%89 = load double, double* %16
%90 = fptosi double %89 to i32
%91 = call double @fabs(i32 %90)
%92 = load i32, i32* %20
%93 = sext i32 %92 to i64
%94 = getelementptr inbounds [3 x double], [3 x double]* %14, i64 0, i64 %93
%95 = load double, double* %94
%96 = fcmp ogt double %91, %95
br i1 %96, label %97, label %137
97: ; preds = %88
%98 = load i32, i32* %19
store i32 %98, i32* %18
br label %99
99: ; preds = %133, %97
%100 = load i32, i32* %19
%101 = load i32, i32* %18
%102 = icmp eq i32 %100, %101
br i1 %102, label %103, label %134
103: ; preds = %99
%104 = load double, double* %15
%105 = load i32, i32* %20
%106 = sext i32 %105 to i64
%107 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 %106
%108 = load double, double* %107
%109 = fadd double %108, %104
store double %109, double* %107
%110 = load float*, float** %7
%111 = load i32, i32* %8
%112 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%113 = load double, double* %112
%114 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%115 = load double, double* %114
%116 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%117 = load double, double* %116
%118 = load i32, i32* %20
%119 = call double @gauss_gradients(float* %110, i32 %111, double %113, double %115, double %117, i32 %118)
store double %119, double* %16
%120 = load double, double* %16
%121 = fcmp olt double %120, -1.000000e+20
br i1 %121, label %122, label %123
122: ; preds = %103
store i32 0, i32* %6
br label %232
123: ; preds = %103
%124 = load double, double* %16
%125 = fcmp oeq double %124, 0.000000e+00
br i1 %125, label %126, label %127
126: ; preds = %123
br label %134
127: ; preds = %123
%128 = load double, double* %16
%129 = fcmp ogt double %128, 0.000000e+00
br i1 %129, label %130, label %131
130: ; preds = %127
store i32 1, i32* %19
br label %132
131: ; preds = %127
store i32 -1, i32* %19
br label %132
132: ; preds = %131, %130
br label %133
133: ; preds = %132
br label %99
134: ; preds = %126, %99
%135 = load double, double* %15
%136 = fmul double %135, -5.000000e-01
store double %136, double* %15
br label %88
137: ; preds = %88
br label %138
138: ; preds = %137
%139 = load i32, i32* %20
%140 = add nsw i32 %139, 1
store i32 %140, i32* %20
br label %51
141: ; preds = %71, %51
%142 = load float*, float** %7
%143 = load i32, i32* %8
%144 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%145 = load double, double* %144
%146 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%147 = load double, double* %146
%148 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%149 = load double, double* %148
%150 = call double @gauss_gradients(float* %142, i32 %143, double %145, double %147, double %149, i32 0)
%151 = getelementptr inbounds [3 x double], [3 x double]* %14, i64 0, i64 0
%152 = load double, double* %151
%153 = fcmp olt double %150, %152
%154 = zext i1 %153 to i32
%155 = call double @fabs(i32 %154)
%156 = fcmp une double %155, 0.000000e+00
br i1 %156, label %157, label %190
157: ; preds = %141
%158 = load float*, float** %7
%159 = load i32, i32* %8
%160 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%161 = load double, double* %160
%162 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%163 = load double, double* %162
%164 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%165 = load double, double* %164
%166 = call double @gauss_gradients(float* %158, i32 %159, double %161, double %163, double %165, i32 1)
%167 = getelementptr inbounds [3 x double], [3 x double]* %14, i64 0, i64 1
%168 = load double, double* %167
%169 = fcmp olt double %166, %168
%170 = zext i1 %169 to i32
%171 = call double @fabs(i32 %170)
%172 = fcmp une double %171, 0.000000e+00
br i1 %172, label %173, label %190
173: ; preds = %157
%174 = load float*, float** %7
%175 = load i32, i32* %8
%176 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%177 = load double, double* %176
%178 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%179 = load double, double* %178
%180 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%181 = load double, double* %180
%182 = call double @gauss_gradients(float* %174, i32 %175, double %177, double %179, double %181, i32 2)
%183 = getelementptr inbounds [3 x double], [3 x double]* %14, i64 0, i64 2
%184 = load double, double* %183
%185 = fcmp olt double %182, %184
%186 = zext i1 %185 to i32
%187 = call double @fabs(i32 %186)
%188 = fcmp une double %187, 0.000000e+00
br i1 %188, label %189, label %190
189: ; preds = %173
store i32 1, i32* %21
br label %191
190: ; preds = %173, %157, %141
store i32 0, i32* %21
br label %191
191: ; preds = %190, %189
%192 = load i32, i32* %22
%193 = add nsw i32 %192, -1
store i32 %193, i32* %22
%194 = load i32, i32* %22
%195 = icmp eq i32 %194, 0
br i1 %195, label %196, label %198
196: ; preds = %191
%197 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i64 0, i64 0))
store i32 0, i32* %6
br label %232
198: ; preds = %191
br label %199
199: ; preds = %198
%200 = load i32, i32* %21
%201 = icmp eq i32 %200, 0
br i1 %201, label %37, label %202
202: ; preds = %199
%203 = load float*, float** %7
%204 = load i32, i32* %8
%205 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%206 = load double, double* %205
%207 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%208 = load double, double* %207
%209 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%210 = load double, double* %209
%211 = call double @gauss_gradients(float* %203, i32 %204, double %206, double %208, double %210, i32 3)
store double %211, double* %17
%212 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%213 = load double, double* %212
%214 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%215 = load double, double* %214
%216 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%217 = load double, double* %216
%218 = load double, double* %17
%219 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([46 x i8], [46 x i8]* @.str.1, i64 0, i64 0), double %213, double %215, double %217, double %218)
%220 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%221 = load double, double* %220
%222 = fptrunc double %221 to float
%223 = load float*, float** %9
store float %222, float* %223
%224 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%225 = load double, double* %224
%226 = fptrunc double %225 to float
%227 = load float*, float** %10
store float %226, float* %227
%228 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
%229 = load double, double* %228
%230 = fptrunc double %229 to float
%231 = load float*, float** %11
store float %230, float* %231
store i32 1, i32* %6
br label %232
232: ; preds = %202, %196, %122, %67, %49
%233 = load i32, i32* %6
ret i32 %233
}

LLVM IR (-O2):
@__const.gauss_fit.dx = [3 x double] [double 5.000000e+00, double 1.000000e+00, double 5.000000e-01]
@__const.gauss_fit.smallest_grad = [3 x double] [double 1.000000e+00, double 1.000000e+00, double 1.000000e+00]
@.str.1 = [46 x i8] c"Final Params: mu=%e, sig=%e, scale=%e (S=%e)\0A\00"
@str = [21 x i8] c"Fit taking too long.\00"
define i32 @gauss_fit(float* %0, i32 %1, float* nocapture %2, float* nocapture %3, float* nocapture %4) {
%6 = alloca [3 x double]
%7 = bitcast [3 x double]* %6 to i8*
%8 = load float, float* %2
%9 = fpext float %8 to double
%10 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 0
store double %9, double* %10
%11 = load float, float* %3
%12 = fpext float %11 to double
%13 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 1
store double %12, double* %13
%14 = load float, float* %4
%15 = fpext float %14 to double
%16 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 2
store double %15, double* %16
br label %17
17: ; preds = %106, %5
%18 = phi double [ %15, %5 ], [ %86, %106 ]
%19 = phi double [ %12, %5 ], [ %87, %106 ]
%20 = phi double [ %9, %5 ], [ %88, %106 ]
%21 = phi i32 [ 200, %5 ], [ %107, %106 ]
%22 = tail call double @gauss_gradients(float* %0, i32 %1, double %20, double %19, double %18, i32 3)
%23 = fcmp olt double %22, -1.000000e+20
br i1 %23, label %119, label %24
24: ; preds = %17, %76
%25 = phi double [ %77, %76 ], [ %18, %17 ]
%26 = phi double [ %78, %76 ], [ %19, %17 ]
%27 = phi double [ %79, %76 ], [ %20, %17 ]
%28 = phi double [ %80, %76 ], [ %18, %17 ]
%29 = phi double [ %81, %76 ], [ %19, %17 ]
%30 = phi double [ %82, %76 ], [ %20, %17 ]
%31 = phi i64 [ %83, %76 ], [ 0, %17 ]
%32 = trunc i64 %31 to i32
%33 = tail call double @gauss_gradients(float* %0, i32 %1, double %30, double %29, double %28, i32 %32)
%34 = fcmp olt double %33, -1.000000e+20
br i1 %34, label %119, label %35
35: ; preds = %24
%36 = fcmp oeq double %33, 0.000000e+00
br i1 %36, label %85, label %37
37: ; preds = %35
%38 = fcmp ogt double %33, 0.000000e+00
%39 = getelementptr inbounds [3 x double], [3 x double]* @__const.gauss_fit.dx, i64 0, i64 %31
%40 = load double, double* %39
%41 = fptosi double %33 to i32
%42 = tail call double @fabs(i32 %41)
%43 = getelementptr inbounds [3 x double], [3 x double]* @__const.gauss_fit.smallest_grad, i64 0, i64 %31
%44 = load double, double* %43
%45 = fcmp ogt double %42, %44
br i1 %45, label %46, label %76
46: ; preds = %37
%47 = select i1 %38, i32 1, i32 -1
%48 = fneg double %40
%49 = select i1 %38, double %48, double %40
%50 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 %31
%51 = load double, double* %50
br label %52
52: ; preds = %46, %70
%53 = phi double [ %51, %46 ], [ %58, %70 ]
%54 = phi i32 [ %47, %46 ], [ %71, %70 ]
%55 = phi double [ %49, %46 ], [ %72, %70 ]
br label %56
56: ; preds = %52, %66
%57 = phi double [ %53, %52 ], [ %58, %66 ]
%58 = fadd double %55, %57
store double %58, double* %50
%59 = load double, double* %10
%60 = load double, double* %13
%61 = load double, double* %16
%62 = tail call double @gauss_gradients(float* %0, i32 %1, double %59, double %60, double %61, i32 %32)
%63 = fcmp olt double %62, -1.000000e+20
br i1 %63, label %119, label %64
64: ; preds = %56
%65 = fcmp oeq double %62, 0.000000e+00
br i1 %65, label %70, label %66
66: ; preds = %64
%67 = fcmp ogt double %62, 0.000000e+00
%68 = select i1 %67, i32 1, i32 -1
%69 = icmp eq i32 %68, %54
br i1 %69, label %56, label %70
70: ; preds = %64, %66
%71 = phi i32 [ %54, %64 ], [ %68, %66 ]
%72 = fmul double %55, -5.000000e-01
%73 = fptosi double %62 to i32
%74 = tail call double @fabs(i32 %73)
%75 = fcmp ogt double %74, %44
br i1 %75, label %52, label %76
76: ; preds = %70, %37
%77 = phi double [ %25, %37 ], [ %61, %70 ]
%78 = phi double [ %26, %37 ], [ %60, %70 ]
%79 = phi double [ %27, %37 ], [ %59, %70 ]
%80 = phi double [ %28, %37 ], [ %61, %70 ]
%81 = phi double [ %29, %37 ], [ %60, %70 ]
%82 = phi double [ %30, %37 ], [ %59, %70 ]
%83 = add nuw nsw i64 %31, 1
%84 = icmp eq i64 %83, 3
br i1 %84, label %85, label %24
85: ; preds = %35, %76
%86 = phi double [ %25, %35 ], [ %77, %76 ]
%87 = phi double [ %26, %35 ], [ %78, %76 ]
%88 = phi double [ %27, %35 ], [ %79, %76 ]
%89 = tail call double @gauss_gradients(float* %0, i32 %1, double %88, double %87, double %86, i32 0)
%90 = fcmp olt double %89, 1.000000e+00
%91 = zext i1 %90 to i32
%92 = tail call double @fabs(i32 %91)
%93 = fcmp une double %92, 0.000000e+00
br i1 %93, label %94, label %106
94: ; preds = %85
%95 = tail call double @gauss_gradients(float* %0, i32 %1, double %88, double %87, double %86, i32 1)
%96 = fcmp olt double %95, 1.000000e+00
%97 = zext i1 %96 to i32
%98 = tail call double @fabs(i32 %97)
%99 = fcmp une double %98, 0.000000e+00
br i1 %99, label %100, label %106
100: ; preds = %94
%101 = tail call double @gauss_gradients(float* %0, i32 %1, double %88, double %87, double %86, i32 2)
%102 = fcmp olt double %101, 1.000000e+00
%103 = zext i1 %102 to i32
%104 = tail call double @fabs(i32 %103)
%105 = fcmp une double %104, 0.000000e+00
br i1 %105, label %109, label %106
106: ; preds = %85, %94, %100
%107 = add nsw i32 %21, -1
%108 = icmp eq i32 %107, 0
br i1 %108, label %111, label %17
109: ; preds = %100
%110 = icmp eq i32 %21, 1
br i1 %110, label %111, label %113
111: ; preds = %106, %109
%112 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([21 x i8], [21 x i8]* @str, i64 0, i64 0))
br label %119
113: ; preds = %109
%114 = tail call double @gauss_gradients(float* %0, i32 %1, double %88, double %87, double %86, i32 3)
%115 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([46 x i8], [46 x i8]* @.str.1, i64 0, i64 0), double %88, double %87, double %86, double %114)
%116 = fptrunc double %88 to float
store float %116, float* %2
%117 = fptrunc double %87 to float
store float %117, float* %3
%118 = fptrunc double %86 to float
store float %118, float* %4
br label %119
119: ; preds = %17, %24, %56, %113, %111
%120 = phi i32 [ 0, %111 ], [ 1, %113 ], [ 0, %56 ], [ 0, %24 ], [ 0, %17 ]
ret i32 %120
}