#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 *calloc(size_t, int);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *);
int /*<<< orphan*/ free(double *);
double *malloc(size_t);
scalar_t__ rref(double *, size_t, size_t);
int /*<<< orphan*/ stderr;
int fit(double *x, double *y, double *e, int n, double *params,
        size_t numParams,
        void (*evaluate_basis)(double x, double *basis, size_t n, void *user),
        void *user) {
  size_t rows = numParams;
  size_t cols = numParams + 1;
  double *A = calloc(rows * cols, sizeof(double));
  if (A == NULL) {
    fprintf(stderr, "Error allocating memory for fit matrix\n");
    return 1;
  }
  double *basis = malloc(rows * sizeof(double));
  for (size_t i = 0; i < n; i++) {
    evaluate_basis(x[i], basis, rows, user);
    double var = e ? e[i] * e[i] : 1.0;
    for (size_t j = 0; j < rows; j++) {
      for (size_t k = 0; k < rows; k++)
        A[j * cols + k] += basis[j] * basis[k] / var;
      A[j * cols + rows] += y[i] * basis[j] / var;
    }
  }
  if (rref(A, rows, cols)) {
    free(A);
    fprintf(stderr, "Fit failed\n");
    return 1;
  }
  for (size_t i = 0; i < rows; i++)
    params[i] = A[i * cols + rows];
  free(A);
  return 0;
}


x86 assembly (clang, -O0):
<fit>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rax
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %ecx,-0x24(%rbp)
mov    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x48(%rbp)
mov    -0x40(%rbp),%rdi
imul   -0x48(%rbp),%rdi
mov    $0x8,%esi
call   1040 <calloc@plt>
mov    %rax,-0x50(%rbp)
cmpq   $0x0,-0x50(%rbp)
jne    11d1 <fit+0x81>
mov    0x2e29(%rip),%rax
mov    (%rax),%edi
lea    0xe48(%rip),%rsi
call   1050 <fprintf@plt>
movl   $0x1,-0x4(%rbp)
jmp    13e5 <fit+0x295>
mov    -0x40(%rbp),%rdi
shl    $0x3,%rdi
call   1060 <malloc@plt>
mov    %rax,-0x58(%rbp)
movq   $0x0,-0x60(%rbp)
mov    -0x60(%rbp),%rax
movslq -0x24(%rbp),%rcx
cmp    %rcx,%rax
jae    1346 <fit+0x1f6>
mov    0x10(%rbp),%rax
mov    -0x10(%rbp),%rcx
mov    -0x60(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm0
mov    -0x58(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    0x18(%rbp),%rdx
call   *%rax
cmpq   $0x0,-0x20(%rbp)
je     124c <fit+0xfc>
mov    -0x20(%rbp),%rax
mov    -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x60(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
jmp    1261 <fit+0x111>
movsd  0xdac(%rip),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
jmp    1261 <fit+0x111>
movsd  -0x88(%rbp),%xmm0
ff
movsd  %xmm0,-0x68(%rbp)
movq   $0x0,-0x70(%rbp)
mov    -0x70(%rbp),%rax
cmp    -0x40(%rbp),%rax
jae    1330 <fit+0x1e0>
movq   $0x0,-0x78(%rbp)
mov    -0x78(%rbp),%rax
cmp    -0x40(%rbp),%rax
jae    12e5 <fit+0x195>
mov    -0x58(%rbp),%rax
mov    -0x70(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x58(%rbp),%rax
mov    -0x78(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
divsd  -0x68(%rbp),%xmm0
mov    -0x50(%rbp),%rax
mov    -0x70(%rbp),%rcx
imul   -0x48(%rbp),%rcx
add    -0x78(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x78(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x78(%rbp)
jmp    128c <fit+0x13c>
mov    -0x18(%rbp),%rax
mov    -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x58(%rbp),%rax
mov    -0x70(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
divsd  -0x68(%rbp),%xmm0
mov    -0x50(%rbp),%rax
mov    -0x70(%rbp),%rcx
imul   -0x48(%rbp),%rcx
add    -0x40(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x70(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x70(%rbp)
jmp    1276 <fit+0x126>
jmp    1335 <fit+0x1e5>
mov    -0x60(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x60(%rbp)
jmp    11ea <fit+0x9a>
mov    -0x50(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    -0x48(%rbp),%rdx
call   1070 <rref@plt>
cmp    $0x0,%rax
je     138b <fit+0x23b>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
mov    0x2c6f(%rip),%rax
mov    (%rax),%edi
lea    0xcb6(%rip),%rsi
call   1050 <fprintf@plt>
movl   $0x1,-0x4(%rbp)
jmp    13e5 <fit+0x295>
movq   $0x0,-0x80(%rbp)
mov    -0x80(%rbp),%rax
cmp    -0x40(%rbp),%rax
jae    13d5 <fit+0x285>
mov    -0x50(%rbp),%rax
mov    -0x80(%rbp),%rcx
imul   -0x48(%rbp),%rcx
add    -0x40(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
mov    -0x80(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x80(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x80(%rbp)
jmp    1393 <fit+0x243>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fit>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x78,%rsp
mov    %r9,%rbx
mov    %r8,%rbp
mov    %ecx,%r15d
mov    %rdx,0x30(%rsp)
mov    %rsi,0x70(%rsp)
mov    %rdi,0x28(%rsp)
lea    0x1(%r9),%rdi
mov    %rdi,(%rsp)
imul   %r9,%rdi
mov    $0x8,%esi
call   1040 <calloc@plt>
test   %rax,%rax
je     14b3 <fit+0x363>
mov    %rax,%r14
mov    %rbp,0x10(%rsp)
lea    0x0(,%rbx,8),%rdi
mov    %rdi,0x8(%rsp)
call   1060 <malloc@plt>
test   %r15d,%r15d
je     1485 <fit+0x335>
mov    %rax,%r12
movslq %r15d,%rax
mov    %rax,0x20(%rsp)
lea    0x8(,%rbx,8),%r15
lea    (%r14,%rbx,8),%rax
mov    %rax,0x60(%rsp)
lea    (%r12,%rbx,8),%rax
mov    %rax,0x58(%rsp)
lea    -0x2(%rbx),%rax
mov    %rax,0x50(%rsp)
mov    %rax,%rcx
shr    %rcx
add    $0x1,%rcx
mov    %rbx,%rax
and    $0xfffffffffffffffe,%rax
mov    %rax,0x40(%rsp)
mov    %rcx,%rax
mov    %rcx,0x48(%rsp)
and    $0xfffffffffffffffe,%rcx
mov    %rcx,0x38(%rsp)
mov    %rbx,%rax
neg    %rax
mov    %rax,0x68(%rsp)
lea    0x10(%r14),%rax
mov    %rax,0x18(%rsp)
xor    %r13d,%r13d
jmp    123f <fit+0xef>
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%r13
cmp    0x20(%rsp),%r13
je     1485 <fit+0x335>
mov    0x28(%rsp),%rax
movsd  (%rax,%r13,8),%xmm0
mov    %r12,%rdi
mov    %rbx,%rsi
mov    0xb8(%rsp),%rdx
call   *0xb0(%rsp)
movsd  0xd99(%rip),%xmm0
mov    0x30(%rsp),%rax
test   %rax,%rax
je     127b <fit+0x12b>
movsd  (%rax,%r13,8),%xmm0
mulsd  %xmm0,%xmm0
test   %rbx,%rbx
mov    (%rsp),%r8
je     1230 <fit+0xe0>
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
mov    %r14,%rax
mov    0x18(%rsp),%rcx
xor    %edx,%edx
jmp    12d7 <fit+0x187>
nopl   0x0(%rax,%rax,1)
mov    0x70(%rsp),%rdi
movsd  (%rdi,%r13,8),%xmm2
mulsd  (%r12,%rdx,8),%xmm2
divsd  %xmm0,%xmm2
add    %rbx,%rsi
addsd  (%r14,%rsi,8),%xmm2
movsd  %xmm2,(%r14,%rsi,8)
add    $0x1,%rdx
add    %r15,%rcx
add    %r15,%rax
cmp    %rbx,%rdx
je     1230 <fit+0xe0>
mov    %rdx,%rsi
imul   %r8,%rsi
cmp    $0x2,%rbx
jae    12f0 <fit+0x1a0>
xor    %ebp,%ebp
jmp    1400 <fit+0x2b0>
nopl   0x0(%rax,%rax,1)
mov    %r15,%rbp
imul   %rdx,%rbp
lea    (%r14,%rbp,1),%rdi
add    0x60(%rsp),%rbp
lea    (%r12,%rdx,8),%r8
add    $0x8,%r8
lea    (%r12,%rdx,8),%r9
cmp    0x58(%rsp),%rdi
setb   %r10b
cmp    %r12,%rbp
seta   %r11b
cmp    %r8,%rdi
setb   %dil
cmp    %r9,%rbp
seta   %r8b
test   %r11b,%r10b
jne    134d <fit+0x1fd>
mov    $0x0,%ebp
and    %r8b,%dil
mov    (%rsp),%r8
jne    1400 <fit+0x2b0>
cmpq   $0x2,0x50(%rsp)
jae    1358 <fit+0x208>
xor    %edi,%edi
jmp    13b5 <fit+0x265>
xor    %ebp,%ebp
mov    (%rsp),%r8
jmp    1400 <fit+0x2b0>
movsd  (%r12,%rdx,8),%xmm2
unpcklpd %xmm2,%xmm2
mov    0x38(%rsp),%rbp
xor    %edi,%edi
nopl   0x0(%rax)
movupd (%r12,%rdi,8),%xmm3
mulpd  %xmm2,%xmm3
divpd  %xmm1,%xmm3
movupd -0x10(%rcx,%rdi,8),%xmm4
addpd  %xmm3,%xmm4
movupd (%rcx,%rdi,8),%xmm3
movupd %xmm4,-0x10(%rcx,%rdi,8)
movupd 0x10(%r12,%rdi,8),%xmm4
mulpd  %xmm2,%xmm4
divpd  %xmm1,%xmm4
addpd  %xmm3,%xmm4
movupd %xmm4,(%rcx,%rdi,8)
add    $0x4,%rdi
add    $0xfffffffffffffffe,%rbp
jne    1370 <fit+0x220>
testb  $0x1,0x48(%rsp)
je     13e7 <fit+0x297>
movsd  (%r12,%rdx,8),%xmm2
unpcklpd %xmm2,%xmm2
movupd (%r12,%rdi,8),%xmm3
mulpd  %xmm2,%xmm3
divpd  %xmm1,%xmm3
add    %rsi,%rdi
movupd (%r14,%rdi,8),%xmm2
addpd  %xmm3,%xmm2
movupd %xmm2,(%r14,%rdi,8)
mov    0x40(%rsp),%rdi
mov    %rdi,%rbp
cmp    %rbx,%rdi
je     12a0 <fit+0x150>
nopl   0x0(%rax,%rax,1)
mov    %rbp,%rdi
test   $0x1,%bl
je     142f <fit+0x2df>
movsd  (%r12,%rdx,8),%xmm2
mulsd  (%r12,%rbp,8),%xmm2
divsd  %xmm0,%xmm2
lea    (%rsi,%rbp,1),%rdi
addsd  (%r14,%rdi,8),%xmm2
movsd  %xmm2,(%r14,%rdi,8)
mov    %rbp,%rdi
or     $0x1,%rdi
not    %rbp
cmp    0x68(%rsp),%rbp
je     12a0 <fit+0x150>
nopl   (%rax)
movsd  (%r12,%rdx,8),%xmm2
mulsd  (%r12,%rdi,8),%xmm2
divsd  %xmm0,%xmm2
addsd  (%rax,%rdi,8),%xmm2
movsd  %xmm2,(%rax,%rdi,8)
movsd  (%r12,%rdx,8),%xmm2
mulsd  0x8(%r12,%rdi,8),%xmm2
divsd  %xmm0,%xmm2
addsd  0x8(%rax,%rdi,8),%xmm2
movsd  %xmm2,0x8(%rax,%rdi,8)
add    $0x2,%rdi
cmp    %rdi,%rbx
jne    1440 <fit+0x2f0>
jmp    12a0 <fit+0x150>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    (%rsp),%rdx
call   1070 <rref@plt>
test   %rax,%rax
je     14d2 <fit+0x382>
mov    %r14,%rdi
call   1030 <free@plt>
mov    0x2b38(%rip),%rax
mov    (%rax),%edi
lea    0xb7f(%rip),%rsi
jmp    14c3 <fit+0x373>
mov    0x2b26(%rip),%rax
mov    (%rax),%edi
lea    0xb45(%rip),%rsi
call   1050 <fprintf@plt>
mov    $0x1,%eax
jmp    159f <fit+0x44f>
test   %rbx,%rbx
mov    0x10(%rsp),%rdx
je     1595 <fit+0x445>
lea    -0x1(%rbx),%rax
mov    %ebx,%r8d
and    $0x3,%r8d
cmp    $0x3,%rax
jae    14f5 <fit+0x3a5>
xor    %ecx,%ecx
jmp    155b <fit+0x40b>
mov    %rbx,%r10
and    $0xfffffffffffffffc,%r10
mov    0x8(%rsp),%rax
lea    (%rax,%rax,2),%r9
mov    %rbx,%rdi
shl    $0x5,%rdi
lea    0x20(%rdi),%rbp
mov    %rbx,%rax
shl    $0x4,%rax
xor    %ecx,%ecx
mov    %r14,%rsi
nopl   0x0(%rax)
movsd  (%rsi,%rbx,8),%xmm0
movsd  %xmm0,(%rdx,%rcx,8)
movsd  0x8(%rsi,%rax,1),%xmm0
movsd  %xmm0,0x8(%rdx,%rcx,8)
movsd  0x10(%rsi,%r9,1),%xmm0
movsd  %xmm0,0x10(%rdx,%rcx,8)
movsd  0x18(%rsi,%rdi,1),%xmm0
movsd  %xmm0,0x18(%rdx,%rcx,8)
add    $0x4,%rcx
add    %rbp,%rsi
cmp    %rcx,%r10
jne    1520 <fit+0x3d0>
test   %r8,%r8
je     1595 <fit+0x445>
lea    (%rdx,%rcx,8),%rax
mov    (%rsp),%rdx
imul   %rcx,%rdx
add    %rbx,%rdx
lea    (%r14,%rdx,8),%rcx
lea    0x8(,%rbx,8),%rdx
xor    %esi,%esi
nopl   (%rax)
movsd  (%rcx),%xmm0
movsd  %xmm0,(%rax,%rsi,8)
add    $0x1,%rsi
add    %rdx,%rcx
cmp    %rsi,%r8
jne    1580 <fit+0x430>
mov    %r14,%rdi
call   1030 <free@plt>
xor    %eax,%eax
add    $0x78,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
@stderr = global i32 0
@.str = [40 x i8] c"Error allocating memory for fit matrix\0A\00"
@.str.1 = [12 x i8] c"Fit failed\0A\00"
define i32 @fit(double* nocapture %0, double* nocapture %1, double* %2, i32 %3, double* nocapture writeonly %4, i64 %5, void (double, double*, i64, i8*)* nocapture %6, i8* %7) {
%9 = add i64 %5, 1
%10 = mul i64 %9, %5
%11 = tail call double* @calloc(i64 %10, i32 8)
%12 = bitcast double* %11 to i8*
%13 = icmp eq double* %11, null
br i1 %13, label %14, label %17
14: ; preds = %8
%15 = load i32, i32* @stderr
%16 = tail call i32 @fprintf(i32 %15, i8* getelementptr inbounds ([40 x i8], [40 x i8]* @.str, i64 0, i64 0))
br label %248
17: ; preds = %8
%18 = shl i64 %5, 3
%19 = tail call double* @malloc(i64 %18)
%20 = bitcast double* %19 to i8*
%21 = icmp eq i32 %3, 0
br i1 %21, label %45, label %22
22: ; preds = %17
%23 = icmp eq double* %2, null
%24 = icmp eq i64 %5, 0
%25 = sext i32 %3 to i64
%26 = shl i64 %5, 3
%27 = add i64 %26, 8
%28 = getelementptr double, double* %11, i64 %5
%29 = bitcast double* %28 to i8*
%30 = getelementptr double, double* %19, i64 %5
%31 = bitcast double* %30 to i8*
%32 = add i64 %5, -2
%33 = lshr i64 %32, 1
%34 = add nuw i64 %33, 1
%35 = icmp ult i64 %5, 2
%36 = and i64 %5, -2
%37 = and i64 %34, 1
%38 = icmp ult i64 %32, 2
%39 = and i64 %34, -2
%40 = icmp eq i64 %37, 0
%41 = icmp eq i64 %36, %5
%42 = and i64 %5, 1
%43 = icmp eq i64 %42, 0
%44 = sub i64 0, %5
br label %56
45: ; preds = %162, %17
%46 = tail call i64 @rref(double* %11, i64 %5, i64 %9)
%47 = icmp eq i64 %46, 0
br i1 %47, label %48, label %199
48: ; preds = %45
%49 = icmp eq i64 %5, 0
br i1 %49, label %217, label %50
50: ; preds = %48
%51 = add i64 %5, -1
%52 = and i64 %5, 3
%53 = icmp ult i64 %51, 3
br i1 %53, label %203, label %54
54: ; preds = %50
%55 = and i64 %5, -4
br label %219
56: ; preds = %22, %162
%57 = phi i64 [ 0, %22 ], [ %163, %162 ]
%58 = getelementptr inbounds double, double* %0, i64 %57
%59 = load double, double* %58
tail call void %6(double %59, double* %19, i64 %5, i8* %7)
br i1 %23, label %64, label %60
60: ; preds = %56
%61 = getelementptr inbounds double, double* %2, i64 %57
%62 = load double, double* %61
%63 = fmul double %62, %62
br label %64
64: ; preds = %56, %60
%65 = phi double [ %63, %60 ], [ 1.000000e+00, %56 ]
br i1 %24, label %162, label %66
66: ; preds = %64
%67 = getelementptr inbounds double, double* %1, i64 %57
%68 = insertelement <2 x double> poison, double %65, i64 0
%69 = shufflevector <2 x double> %68, <2 x double> poison, <2 x i32> zeroinitializer
br label %70
70: ; preds = %66, %165
%71 = phi i64 [ 0, %66 ], [ %174, %165 ]
%72 = mul i64 %27, %71
%73 = getelementptr i8, i8* %12, i64 %72
%74 = getelementptr i8, i8* %29, i64 %72
%75 = getelementptr inbounds double, double* %19, i64 %71
%76 = mul i64 %71, %9
br i1 %35, label %145, label %77
77: ; preds = %70
%78 = add i64 %71, 1
%79 = getelementptr double, double* %19, i64 %78
%80 = bitcast double* %79 to i8*
%81 = getelementptr double, double* %19, i64 %71
%82 = bitcast double* %81 to i8*
%83 = icmp ult i8* %73, %31
%84 = icmp ugt i8* %74, %20
%85 = and i1 %83, %84
%86 = icmp ult i8* %73, %80
%87 = icmp ugt i8* %74, %82
%88 = and i1 %86, %87
%89 = or i1 %85, %88
br i1 %89, label %145, label %90
90: ; preds = %77
br i1 %38, label %127, label %91
91: ; preds = %90
%92 = load double, double* %75
%93 = insertelement <2 x double> poison, double %92, i64 0
%94 = shufflevector <2 x double> %93, <2 x double> poison, <2 x i32> zeroinitializer
%95 = load double, double* %75
%96 = insertelement <2 x double> poison, double %95, i64 0
%97 = shufflevector <2 x double> %96, <2 x double> poison, <2 x i32> zeroinitializer
br label %98
98: ; preds = %98, %91
%99 = phi i64 [ 0, %91 ], [ %124, %98 ]
%100 = phi i64 [ 0, %91 ], [ %125, %98 ]
%101 = getelementptr inbounds double, double* %19, i64 %99
%102 = bitcast double* %101 to <2 x double>*
%103 = load <2 x double>, <2 x double>* %102
%104 = fmul <2 x double> %94, %103
%105 = fdiv <2 x double> %104, %69
%106 = add i64 %99, %76
%107 = getelementptr inbounds double, double* %11, i64 %106
%108 = bitcast double* %107 to <2 x double>*
%109 = load <2 x double>, <2 x double>* %108
%110 = fadd <2 x double> %109, %105
%111 = bitcast double* %107 to <2 x double>*
store <2 x double> %110, <2 x double>* %111
%112 = or i64 %99, 2
%113 = getelementptr inbounds double, double* %19, i64 %112
%114 = bitcast double* %113 to <2 x double>*
%115 = load <2 x double>, <2 x double>* %114
%116 = fmul <2 x double> %97, %115
%117 = fdiv <2 x double> %116, %69
%118 = add i64 %112, %76
%119 = getelementptr inbounds double, double* %11, i64 %118
%120 = bitcast double* %119 to <2 x double>*
%121 = load <2 x double>, <2 x double>* %120
%122 = fadd <2 x double> %121, %117
%123 = bitcast double* %119 to <2 x double>*
store <2 x double> %122, <2 x double>* %123
%124 = add nuw i64 %99, 4
%125 = add nuw i64 %100, 2
%126 = icmp eq i64 %125, %39
br i1 %126, label %127, label %98
127: ; preds = %98, %90
%128 = phi i64 [ 0, %90 ], [ %124, %98 ]
br i1 %40, label %144, label %129
129: ; preds = %127
%130 = load double, double* %75
%131 = insertelement <2 x double> poison, double %130, i64 0
%132 = shufflevector <2 x double> %131, <2 x double> poison, <2 x i32> zeroinitializer
%133 = getelementptr inbounds double, double* %19, i64 %128
%134 = bitcast double* %133 to <2 x double>*
%135 = load <2 x double>, <2 x double>* %134
%136 = fmul <2 x double> %132, %135
%137 = fdiv <2 x double> %136, %69
%138 = add i64 %128, %76
%139 = getelementptr inbounds double, double* %11, i64 %138
%140 = bitcast double* %139 to <2 x double>*
%141 = load <2 x double>, <2 x double>* %140
%142 = fadd <2 x double> %141, %137
%143 = bitcast double* %139 to <2 x double>*
store <2 x double> %142, <2 x double>* %143
br label %144
144: ; preds = %127, %129
br i1 %41, label %165, label %145
145: ; preds = %77, %70, %144
%146 = phi i64 [ 0, %77 ], [ 0, %70 ], [ %36, %144 ]
%147 = xor i64 %146, -1
br i1 %43, label %159, label %148
148: ; preds = %145
%149 = load double, double* %75
%150 = getelementptr inbounds double, double* %19, i64 %146
%151 = load double, double* %150
%152 = fmul double %149, %151
%153 = fdiv double %152, %65
%154 = add i64 %146, %76
%155 = getelementptr inbounds double, double* %11, i64 %154
%156 = load double, double* %155
%157 = fadd double %156, %153
store double %157, double* %155
%158 = or i64 %146, 1
br label %159
159: ; preds = %148, %145
%160 = phi i64 [ %146, %145 ], [ %158, %148 ]
%161 = icmp eq i64 %147, %44
br i1 %161, label %165, label %176
162: ; preds = %165, %64
%163 = add nuw i64 %57, 1
%164 = icmp eq i64 %163, %25
br i1 %164, label %45, label %56
165: ; preds = %159, %176, %144
%166 = load double, double* %67
%167 = load double, double* %75
%168 = fmul double %166, %167
%169 = fdiv double %168, %65
%170 = add i64 %76, %5
%171 = getelementptr inbounds double, double* %11, i64 %170
%172 = load double, double* %171
%173 = fadd double %172, %169
store double %173, double* %171
%174 = add nuw i64 %71, 1
%175 = icmp eq i64 %174, %5
br i1 %175, label %162, label %70
176: ; preds = %159, %176
%177 = phi i64 [ %197, %176 ], [ %160, %159 ]
%178 = load double, double* %75
%179 = getelementptr inbounds double, double* %19, i64 %177
%180 = load double, double* %179
%181 = fmul double %178, %180
%182 = fdiv double %181, %65
%183 = add i64 %177, %76
%184 = getelementptr inbounds double, double* %11, i64 %183
%185 = load double, double* %184
%186 = fadd double %185, %182
store double %186, double* %184
%187 = add nuw i64 %177, 1
%188 = load double, double* %75
%189 = getelementptr inbounds double, double* %19, i64 %187
%190 = load double, double* %189
%191 = fmul double %188, %190
%192 = fdiv double %191, %65
%193 = add i64 %187, %76
%194 = getelementptr inbounds double, double* %11, i64 %193
%195 = load double, double* %194
%196 = fadd double %195, %192
store double %196, double* %194
%197 = add nuw i64 %177, 2
%198 = icmp eq i64 %197, %5
br i1 %198, label %165, label %176
199: ; preds = %45
%200 = tail call i32 @free(double* %11)
%201 = load i32, i32* @stderr
%202 = tail call i32 @fprintf(i32 %201, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0))
br label %248
203: ; preds = %219, %50
%204 = phi i64 [ 0, %50 ], [ %245, %219 ]
%205 = icmp eq i64 %52, 0
br i1 %205, label %217, label %206
206: ; preds = %203, %206
%207 = phi i64 [ %214, %206 ], [ %204, %203 ]
%208 = phi i64 [ %215, %206 ], [ 0, %203 ]
%209 = mul i64 %207, %9
%210 = add i64 %209, %5
%211 = getelementptr inbounds double, double* %11, i64 %210
%212 = load double, double* %211
%213 = getelementptr inbounds double, double* %4, i64 %207
store double %212, double* %213
%214 = add nuw i64 %207, 1
%215 = add i64 %208, 1
%216 = icmp eq i64 %215, %52
br i1 %216, label %217, label %206
217: ; preds = %203, %206, %48
%218 = tail call i32 @free(double* %11)
br label %248
219: ; preds = %219, %54
%220 = phi i64 [ 0, %54 ], [ %245, %219 ]
%221 = phi i64 [ 0, %54 ], [ %246, %219 ]
%222 = mul i64 %220, %9
%223 = add i64 %222, %5
%224 = getelementptr inbounds double, double* %11, i64 %223
%225 = load double, double* %224
%226 = getelementptr inbounds double, double* %4, i64 %220
store double %225, double* %226
%227 = or i64 %220, 1
%228 = mul i64 %227, %9
%229 = add i64 %228, %5
%230 = getelementptr inbounds double, double* %11, i64 %229
%231 = load double, double* %230
%232 = getelementptr inbounds double, double* %4, i64 %227
store double %231, double* %232
%233 = or i64 %220, 2
%234 = mul i64 %233, %9
%235 = add i64 %234, %5
%236 = getelementptr inbounds double, double* %11, i64 %235
%237 = load double, double* %236
%238 = getelementptr inbounds double, double* %4, i64 %233
store double %237, double* %238
%239 = or i64 %220, 3
%240 = mul i64 %239, %9
%241 = add i64 %240, %5
%242 = getelementptr inbounds double, double* %11, i64 %241
%243 = load double, double* %242
%244 = getelementptr inbounds double, double* %4, i64 %239
store double %243, double* %244
%245 = add nuw i64 %220, 4
%246 = add i64 %221, 4
%247 = icmp eq i64 %246, %55
br i1 %247, label %203, label %219
248: ; preds = %199, %217, %14
%249 = phi i32 [ 1, %14 ], [ 1, %199 ], [ 0, %217 ]
ret i32 %249
}