void residual(double *param, double *fixed, int *lev, int *fact, int *sumlev,
              double *observed, int *dimdata, double *deltaweights, int *numfix,
              double *valfix, double *RSS) {
  int i, j;
  int lentot = (dimdata[0]) * (dimdata[1]);
  double resid;
  double parameters[sumlev[2]];
  double estimated[dimdata[1]];
  for (i = 0; i < sumlev[2]; i++) {
    if (!isnan(fixed[i]))
      parameters[i] = fixed[i];
    else
      parameters[i] = param[i];
  }
  averaging(parameters, lev, fact, sumlev, estimated);
  j = 0;
  for (i = 0; i < lentot; i++) {
    if (!isnan(observed[i])) {
      resid = estimated[j] - observed[i];
      *RSS += resid * resid;
    }
    if (i == ((dimdata[0]) * (j + 1) - 1))
      j++;
  }
}


x86 assembly (clang, -O0):
<residual>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    0x30(%rbp),%rax
mov    0x28(%rbp),%rax
mov    0x20(%rbp),%rax
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    0x10(%rbp),%rcx
mov    (%rcx),%eax
mov    0x4(%rcx),%ecx
imul   %ecx,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x28(%rbp),%rax
mov    0x8(%rax),%eax
mov    %rsp,%rcx
mov    %rcx,-0x50(%rbp)
lea    0xf(,%rax,8),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x70(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x58(%rbp)
mov    0x10(%rbp),%rax
mov    0x4(%rax),%eax
lea    0xf(,%rax,8),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x68(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x60(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
mov    -0x28(%rbp),%rcx
cmp    0x8(%rcx),%eax
jge    1232 <residual+0x112>
mov    -0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    $0x1,%al
call   1030 <isnan@plt>
cmp    $0x0,%eax
jne    1205 <residual+0xe5>
mov    -0x70(%rbp),%rax
mov    -0x10(%rbp),%rcx
movslq -0x34(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm0
movslq -0x34(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    121f <residual+0xff>
mov    -0x70(%rbp),%rax
mov    -0x8(%rbp),%rcx
movslq -0x34(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm0
movslq -0x34(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    1224 <residual+0x104>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    11b9 <residual+0x99>
mov    -0x68(%rbp),%r8
mov    -0x70(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x20(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    $0x0,%al
call   1040 <averaging@plt>
movl   $0x0,-0x38(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x3c(%rbp),%eax
jge    12fa <residual+0x1da>
mov    -0x30(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    $0x1,%al
call   1030 <isnan@plt>
cmp    $0x0,%eax
jne    12c1 <residual+0x1a1>
mov    -0x68(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x34(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm2
mov    0x30(%rbp),%rax
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
mov    -0x34(%rbp),%eax
mov    0x10(%rbp),%rcx
mov    (%rcx),%ecx
mov    -0x38(%rbp),%edx
add    $0x1,%edx
imul   %edx,%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    12e7 <residual+0x1c7>
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    12ec <residual+0x1cc>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    125b <residual+0x13b>
mov    -0x50(%rbp),%rax
mov    %rax,%rsp
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<residual>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %r9,-0x50(%rbp)
mov    %r8,%r15
mov    %rcx,-0x48(%rbp)
mov    %rdx,-0x40(%rbp)
mov    0x10(%rbp),%rcx
mov    0x4(%rcx),%eax
mov    (%rcx),%ecx
imul   %eax,%ecx
mov    %ecx,-0x2c(%rbp)
mov    0x8(%r8),%ecx
mov    %rsp,%r14
lea    0xf(,%rcx,8),%rdx
and    $0xfffffffffffffff0,%rdx
sub    %rdx,%r14
mov    %r14,%rsp
mov    %rsp,%rdx
lea    0xf(,%rax,8),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%rdx
mov    %rdx,-0x38(%rbp)
mov    %rdx,%rsp
test   %ecx,%ecx
jle    11c8 <residual+0xa8>
mov    %rsi,%r12
mov    %rdi,%r13
xor    %ebx,%ebx
jmp    11af <residual+0x8f>
nop
movsd  (%rcx),%xmm0
movsd  %xmm0,(%r14,%rbx,8)
add    $0x1,%rbx
movslq 0x8(%r15),%rax
add    $0x8,%r13
add    $0x8,%r12
cmp    %rax,%rbx
jge    11c8 <residual+0xa8>
movsd  (%r12),%xmm0
mov    $0x1,%al
call   1030 <isnan@plt>
mov    %r12,%rcx
test   %eax,%eax
je     1190 <residual+0x70>
mov    %r13,%rcx
jmp    1190 <residual+0x70>
xor    %r12d,%r12d
mov    %r14,%rdi
mov    -0x40(%rbp),%rsi
mov    -0x48(%rbp),%rdx
mov    %r15,%rcx
mov    -0x38(%rbp),%r8
xor    %eax,%eax
call   1040 <averaging@plt>
mov    -0x2c(%rbp),%eax
test   %eax,%eax
mov    -0x50(%rbp),%r13
jle    125a <residual+0x13a>
mov    0x30(%rbp),%r14
mov    %eax,%r15d
xor    %ebx,%ebx
jmp    120c <residual+0xec>
nopw   0x0(%rax,%rax,1)
add    $0x1,%rbx
mov    %eax,%r12d
cmp    %rbx,%r15
je     125a <residual+0x13a>
movsd  0x0(%r13,%rbx,8),%xmm0
mov    $0x1,%al
call   1030 <isnan@plt>
test   %eax,%eax
jne    123f <residual+0x11f>
movslq %r12d,%rax
mov    -0x38(%rbp),%rcx
movsd  (%rcx,%rax,8),%xmm0
subsd  0x0(%r13,%rbx,8),%xmm0
mulsd  %xmm0,%xmm0
addsd  (%r14),%xmm0
movsd  %xmm0,(%r14)
lea    0x1(%r12),%eax
mov    0x10(%rbp),%rcx
mov    (%rcx),%ecx
imul   %eax,%ecx
add    $0xffffffff,%ecx
cmp    %rcx,%rbx
je     1200 <residual+0xe0>
mov    %r12d,%eax
jmp    1200 <residual+0xe0>
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @residual(double* %0, double* %1, i32* %2, i32* %3, i32* %4, double* %5, i32* %6, double* %7, i32* %8, double* %9, double* %10) {
%12 = alloca double*
%13 = alloca double*
%14 = alloca i32*
%15 = alloca i32*
%16 = alloca i32*
%17 = alloca double*
%18 = alloca i32*
%19 = alloca double*
%20 = alloca i32*
%21 = alloca double*
%22 = alloca double*
%23 = alloca i32
%24 = alloca i32
%25 = alloca i32
%26 = alloca double
%27 = alloca i8*
%28 = alloca i64
%29 = alloca i64
store double* %0, double** %12
store double* %1, double** %13
store i32* %2, i32** %14
store i32* %3, i32** %15
store i32* %4, i32** %16
store double* %5, double** %17
store i32* %6, i32** %18
store double* %7, double** %19
store i32* %8, i32** %20
store double* %9, double** %21
store double* %10, double** %22
%30 = load i32*, i32** %18
%31 = getelementptr inbounds i32, i32* %30, i64 0
%32 = load i32, i32* %31
%33 = load i32*, i32** %18
%34 = getelementptr inbounds i32, i32* %33, i64 1
%35 = load i32, i32* %34
%36 = mul nsw i32 %32, %35
store i32 %36, i32* %25
%37 = load i32*, i32** %16
%38 = getelementptr inbounds i32, i32* %37, i64 2
%39 = load i32, i32* %38
%40 = zext i32 %39 to i64
%41 = call i8* @llvm.stacksave()
store i8* %41, i8** %27
%42 = alloca double, i64 %40
store i64 %40, i64* %28
%43 = load i32*, i32** %18
%44 = getelementptr inbounds i32, i32* %43, i64 1
%45 = load i32, i32* %44
%46 = zext i32 %45 to i64
%47 = alloca double, i64 %46
store i64 %46, i64* %29
store i32 0, i32* %23
br label %48
48: ; preds = %81, %11
%49 = load i32, i32* %23
%50 = load i32*, i32** %16
%51 = getelementptr inbounds i32, i32* %50, i64 2
%52 = load i32, i32* %51
%53 = icmp slt i32 %49, %52
br i1 %53, label %54, label %84
54: ; preds = %48
%55 = load double*, double** %13
%56 = load i32, i32* %23
%57 = sext i32 %56 to i64
%58 = getelementptr inbounds double, double* %55, i64 %57
%59 = load double, double* %58
%60 = call i32 (double, ...) bitcast (i32 (...)* @isnan to i32 (double, ...)*)(double %59)
%61 = icmp ne i32 %60, 0
br i1 %61, label %71, label %62
62: ; preds = %54
%63 = load double*, double** %13
%64 = load i32, i32* %23
%65 = sext i32 %64 to i64
%66 = getelementptr inbounds double, double* %63, i64 %65
%67 = load double, double* %66
%68 = load i32, i32* %23
%69 = sext i32 %68 to i64
%70 = getelementptr inbounds double, double* %42, i64 %69
store double %67, double* %70
br label %80
71: ; preds = %54
%72 = load double*, double** %12
%73 = load i32, i32* %23
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds double, double* %72, i64 %74
%76 = load double, double* %75
%77 = load i32, i32* %23
%78 = sext i32 %77 to i64
%79 = getelementptr inbounds double, double* %42, i64 %78
store double %76, double* %79
br label %80
80: ; preds = %71, %62
br label %81
81: ; preds = %80
%82 = load i32, i32* %23
%83 = add nsw i32 %82, 1
store i32 %83, i32* %23
br label %48
84: ; preds = %48
%85 = load i32*, i32** %14
%86 = load i32*, i32** %15
%87 = load i32*, i32** %16
%88 = call i32 (double*, i32*, i32*, i32*, double*, ...) bitcast (i32 (...)* @averaging to i32 (double*, i32*, i32*, i32*, double*, ...)*)(double* %42, i32* %85, i32* %86, i32* %87, double* %47)
store i32 0, i32* %24
store i32 0, i32* %23
br label %89
89: ; preds = %131, %84
%90 = load i32, i32* %23
%91 = load i32, i32* %25
%92 = icmp slt i32 %90, %91
br i1 %92, label %93, label %134
93: ; preds = %89
%94 = load double*, double** %17
%95 = load i32, i32* %23
%96 = sext i32 %95 to i64
%97 = getelementptr inbounds double, double* %94, i64 %96
%98 = load double, double* %97
%99 = call i32 (double, ...) bitcast (i32 (...)* @isnan to i32 (double, ...)*)(double %98)
%100 = icmp ne i32 %99, 0
br i1 %100, label %117, label %101
101: ; preds = %93
%102 = load i32, i32* %24
%103 = sext i32 %102 to i64
%104 = getelementptr inbounds double, double* %47, i64 %103
%105 = load double, double* %104
%106 = load double*, double** %17
%107 = load i32, i32* %23
%108 = sext i32 %107 to i64
%109 = getelementptr inbounds double, double* %106, i64 %108
%110 = load double, double* %109
%111 = fsub double %105, %110
store double %111, double* %26
%112 = load double, double* %26
%113 = load double, double* %26
%114 = load double*, double** %22
%115 = load double, double* %114
%116 = call double @llvm.fmuladd.f64(double %112, double %113, double %115)
store double %116, double* %114
br label %117
117: ; preds = %101, %93
%118 = load i32, i32* %23
%119 = load i32*, i32** %18
%120 = getelementptr inbounds i32, i32* %119, i64 0
%121 = load i32, i32* %120
%122 = load i32, i32* %24
%123 = add nsw i32 %122, 1
%124 = mul nsw i32 %121, %123
%125 = sub nsw i32 %124, 1
%126 = icmp eq i32 %118, %125
br i1 %126, label %127, label %130
127: ; preds = %117
%128 = load i32, i32* %24
%129 = add nsw i32 %128, 1
store i32 %129, i32* %24
br label %130
130: ; preds = %127, %117
br label %131
131: ; preds = %130
%132 = load i32, i32* %23
%133 = add nsw i32 %132, 1
store i32 %133, i32* %23
br label %89
134: ; preds = %89
%135 = load i8*, i8** %27
ret void
}

LLVM IR (-O2):
define void @residual(double* nocapture %0, double* nocapture %1, i32* %2, i32* %3, i32* %4, double* nocapture %5, i32* nocapture %6, double* nocapture readnone %7, i32* nocapture readnone %8, double* nocapture readnone %9, double* nocapture %10) {
%12 = load i32, i32* %6
%13 = getelementptr inbounds i32, i32* %6, i64 1
%14 = load i32, i32* %13
%15 = mul i32 %14, %12
%16 = getelementptr inbounds i32, i32* %4, i64 2
%17 = load i32, i32* %16
%18 = zext i32 %17 to i64
%19 = alloca double, i64 %18
%20 = zext i32 %14 to i64
%21 = alloca double, i64 %20
%22 = icmp sgt i32 %17, 0
br i1 %22, label %23, label %37
23: ; preds = %11, %23
%24 = phi i64 [ %33, %23 ], [ 0, %11 ]
%25 = getelementptr inbounds double, double* %1, i64 %24
%26 = load double, double* %25
%27 = tail call i32 (double, ...) bitcast (i32 (...)* @isnan to i32 (double, ...)*)(double %26)
%28 = icmp eq i32 %27, 0
%29 = getelementptr inbounds double, double* %0, i64 %24
%30 = select i1 %28, double* %25, double* %29
%31 = load double, double* %30
%32 = getelementptr inbounds double, double* %19, i64 %24
store double %31, double* %32
%33 = add nuw nsw i64 %24, 1
%34 = load i32, i32* %16
%35 = sext i32 %34 to i64
%36 = icmp slt i64 %33, %35
br i1 %36, label %23, label %37
37: ; preds = %23, %11
%38 = call i32 (double*, i32*, i32*, i32*, double*, ...) bitcast (i32 (...)* @averaging to i32 (double*, i32*, i32*, i32*, double*, ...)*)(double* %19, i32* %2, i32* %3, i32* %4, double* %21)
%39 = icmp sgt i32 %15, 0
br i1 %39, label %40, label %67
40: ; preds = %37
%41 = zext i32 %15 to i64
br label %42
42: ; preds = %40, %57
%43 = phi i64 [ 0, %40 ], [ %65, %57 ]
%44 = phi i32 [ 0, %40 ], [ %64, %57 ]
%45 = getelementptr inbounds double, double* %5, i64 %43
%46 = load double, double* %45
%47 = call i32 (double, ...) bitcast (i32 (...)* @isnan to i32 (double, ...)*)(double %46)
%48 = icmp eq i32 %47, 0
br i1 %48, label %49, label %57
49: ; preds = %42
%50 = sext i32 %44 to i64
%51 = getelementptr inbounds double, double* %21, i64 %50
%52 = load double, double* %51
%53 = load double, double* %45
%54 = fsub double %52, %53
%55 = load double, double* %10
%56 = call double @llvm.fmuladd.f64(double %54, double %54, double %55)
store double %56, double* %10
br label %57
57: ; preds = %49, %42
%58 = load i32, i32* %6
%59 = add nsw i32 %44, 1
%60 = mul nsw i32 %58, %59
%61 = add nsw i32 %60, -1
%62 = zext i32 %61 to i64
%63 = icmp eq i64 %43, %62
%64 = select i1 %63, i32 %59, i32 %44
%65 = add nuw nsw i64 %43, 1
%66 = icmp eq i64 %65, %41
br i1 %66, label %67, label %42
67: ; preds = %57, %37
ret void
}