float cr_mode(int *histgrm, int nbins, float hwidth, float hmin) {
  int i, bpeak;
  float mode, hpeak, dh1, dh2, denom;
  if (nbins == 1)
    return (hmin + 0.5 * hwidth);
  if (nbins == 2) {
    if (histgrm[0] > histgrm[1])
      mode = hmin + 0.5 * hwidth;
    else if (histgrm[1] > histgrm[0])
      mode = hmin + 1.5 * hwidth;
    else
      mode = hmin + hwidth;
    return (mode);
  }
  hpeak = histgrm[0];
  bpeak = 0;
  for (i = 1; i < nbins; ++i) {
    if (histgrm[i] > hpeak) {
      hpeak = histgrm[i];
      bpeak = i;
    }
  }
  if (bpeak == 0)
    return (hmin + 0.5 * hwidth);
  if (bpeak == (nbins - 1))
    return (hmin + (nbins - 0.5) * hwidth);
  dh1 = histgrm[bpeak] - histgrm[bpeak - 1];
  dh2 = histgrm[bpeak] - histgrm[bpeak + 1];
  denom = dh1 + dh2;
  if ((denom = (denom > 0.) ? denom : -denom) < 1.e-20) {
    mode = hmin + (bpeak + 0.5) * hwidth;
  } else {
    mode = bpeak + 1 + 0.5 * (dh1 - dh2) / denom;
    mode = hmin + (mode - 0.5) * hwidth;
  }
  dh1 = histgrm[bpeak - 1] * (hmin + (bpeak - 0.5) * hwidth) +
        histgrm[bpeak] * (hmin + (bpeak + 0.5) * hwidth) +
        histgrm[bpeak + 1] * (hmin + (bpeak + 1.5) * hwidth);
  dh2 = histgrm[bpeak - 1] + histgrm[bpeak] + histgrm[bpeak + 1];
  return (mode);
}


x86 assembly (clang, -O0):
<cr_mode>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
movss  %xmm0,-0x18(%rbp)
movss  %xmm1,-0x1c(%rbp)
cmpl   $0x1,-0x14(%rbp)
jne    114f <cr_mode+0x4f>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xecf(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    155e <cr_mode+0x45e>
cmpl   $0x2,-0x14(%rbp)
jne    1202 <cr_mode+0x102>
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
mov    -0x10(%rbp),%rcx
cmp    0x4(%rcx),%eax
jle    119c <cr_mode+0x9c>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe82(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x28(%rbp)
jmp    11f3 <cr_mode+0xf3>
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%eax
mov    -0x10(%rbp),%rcx
cmp    (%rcx),%eax
jle    11df <cr_mode+0xdf>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe47(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x28(%rbp)
jmp    11ee <cr_mode+0xee>
movss  -0x1c(%rbp),%xmm0
addss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
jmp    11f3 <cr_mode+0xf3>
movss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    155e <cr_mode+0x45e>
mov    -0x10(%rbp),%rax
cvtsi2ssl (%rax),%xmm0
movss  %xmm0,-0x2c(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x1,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    126b <cr_mode+0x16b>
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
cvtsi2ssl (%rax,%rcx,4),%xmm0
ucomiss -0x2c(%rbp),%xmm0
jbe    1258 <cr_mode+0x158>
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
cvtsi2ssl (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    125d <cr_mode+0x15d>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    121d <cr_mode+0x11d>
cmpl   $0x0,-0x24(%rbp)
jne    12a5 <cr_mode+0x1a5>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd79(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    155e <cr_mode+0x45e>
mov    -0x24(%rbp),%eax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    12ef <cr_mode+0x1ef>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
cvtsi2sdl -0x14(%rbp),%xmm0
movsd  0xd3c(%rip),%xmm2
subsd  %xmm2,%xmm0
movss  -0x18(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    155e <cr_mode+0x45e>
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    -0x10(%rbp),%rcx
mov    -0x24(%rbp),%edx
sub    $0x1,%edx
movslq %edx,%rdx
sub    (%rcx,%rdx,4),%eax
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    -0x10(%rbp),%rcx
mov    -0x24(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
sub    (%rcx,%rdx,4),%eax
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x34(%rbp)
movss  -0x30(%rbp),%xmm0
addss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x38(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    136b <cr_mode+0x26b>
movss  -0x38(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
jmp    1382 <cr_mode+0x282>
movss  -0x38(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
cvtss2sd %xmm0,%xmm1
movsd  0xc68(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    13db <cr_mode+0x2db>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
cvtsi2sdl -0x24(%rbp),%xmm0
movsd  0xc50(%rip),%xmm2
addsd  %xmm2,%xmm0
movss  -0x18(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x28(%rbp)
jmp    1451 <cr_mode+0x351>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %eax,%xmm0
movss  -0x30(%rbp),%xmm1
subss  -0x34(%rbp),%xmm1
cvtss2sd %xmm1,%xmm2
movsd  0xc0d(%rip),%xmm1
mulsd  %xmm2,%xmm1
movss  -0x38(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0x28(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xbd5(%rip),%xmm2
subsd  %xmm2,%xmm0
movss  -0x18(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x24(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
cvtsi2sdl (%rax,%rcx,4),%xmm1
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
cvtsi2sdl -0x24(%rbp),%xmm2
movsd  0xb8f(%rip),%xmm3
subsd  %xmm3,%xmm2
movss  -0x18(%rbp),%xmm3
cvtss2sd %xmm3,%xmm3
mulsd  %xmm3,%xmm2
addsd  %xmm0,%xmm2
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
cvtsi2sdl (%rax,%rcx,4),%xmm0
movss  -0x1c(%rbp),%xmm3
cvtss2sd %xmm3,%xmm4
cvtsi2sdl -0x24(%rbp),%xmm3
movsd  0xb57(%rip),%xmm5
addsd  %xmm5,%xmm3
movss  -0x18(%rbp),%xmm5
cvtss2sd %xmm5,%xmm5
mulsd  %xmm5,%xmm3
addsd  %xmm4,%xmm3
mulsd  %xmm3,%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
cvtsi2sdl (%rax,%rcx,4),%xmm0
movss  -0x1c(%rbp),%xmm2
cvtss2sd %xmm2,%xmm3
cvtsi2sdl -0x24(%rbp),%xmm2
movsd  0xb16(%rip),%xmm4
addsd  %xmm4,%xmm2
movss  -0x18(%rbp),%xmm4
cvtss2sd %xmm4,%xmm4
mulsd  %xmm4,%xmm2
addsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x24(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%eax
mov    -0x10(%rbp),%rcx
movslq -0x24(%rbp),%rdx
add    (%rcx,%rdx,4),%eax
mov    -0x10(%rbp),%rcx
mov    -0x24(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
add    (%rcx,%rdx,4),%eax
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x34(%rbp)
movss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<cr_mode>:
cmp    $0x2,%esi
je     113b <cr_mode+0x3b>
cmp    $0x1,%esi
je     1222 <cr_mode+0x122>
jle    1222 <cr_mode+0x122>
cvtsi2ssl (%rdi),%xmm2
mov    %esi,%eax
lea    -0x1(%rax),%r8
add    $0xfffffffffffffffe,%rax
mov    %r8d,%r9d
and    $0x3,%r9d
cmp    $0x3,%rax
jae    115f <cr_mode+0x5f>
xor    %eax,%eax
mov    $0x1,%edx
jmp    11d4 <cr_mode+0xd4>
mov    (%rdi),%eax
mov    0x4(%rdi),%ecx
cmp    %ecx,%eax
jg     1222 <cr_mode+0x122>
jge    123b <cr_mode+0x13b>
cvtss2sd %xmm0,%xmm0
mulsd  0xea6(%rip),%xmm0
jmp    122e <cr_mode+0x12e>
and    $0xfffffffffffffffc,%r8
xor    %eax,%eax
mov    $0x1,%edx
xor    %r10d,%r10d
nopl   (%rax)
xorps  %xmm3,%xmm3
cvtsi2ssl (%rdi,%rdx,4),%xmm3
ucomiss %xmm2,%xmm3
cmova  %edx,%eax
xorps  %xmm4,%xmm4
cvtsi2ssl 0x4(%rdi,%rdx,4),%xmm4
maxss  %xmm2,%xmm3
ucomiss %xmm3,%xmm4
lea    0x1(%rdx),%ecx
cmovbe %eax,%ecx
xorps  %xmm5,%xmm5
cvtsi2ssl 0x8(%rdi,%rdx,4),%xmm5
maxss  %xmm3,%xmm4
ucomiss %xmm4,%xmm5
lea    0x2(%rdx),%r11d
cmovbe %ecx,%r11d
xorps  %xmm2,%xmm2
cvtsi2ssl 0xc(%rdi,%rdx,4),%xmm2
maxss  %xmm4,%xmm5
ucomiss %xmm5,%xmm2
lea    0x3(%rdx),%eax
cmovbe %r11d,%eax
maxss  %xmm5,%xmm2
add    $0x4,%rdx
add    $0x4,%r10
cmp    %r8,%r10
jne    1170 <cr_mode+0x70>
test   %r9,%r9
je     11ff <cr_mode+0xff>
nopl   0x0(%rax)
xorps  %xmm3,%xmm3
cvtsi2ssl (%rdi,%rdx,4),%xmm3
ucomiss %xmm2,%xmm3
cmova  %edx,%eax
maxss  %xmm2,%xmm3
add    $0x1,%rdx
movaps %xmm3,%xmm2
add    $0xffffffffffffffff,%r9
jne    11e0 <cr_mode+0xe0>
test   %eax,%eax
je     1222 <cr_mode+0x122>
lea    -0x1(%rsi),%ecx
cmp    %ecx,%eax
jne    1240 <cr_mode+0x140>
xorps  %xmm2,%xmm2
cvtsi2sd %esi,%xmm2
cvtss2sd %xmm1,%xmm1
addsd  0xdfb(%rip),%xmm2
jmp    12dc <cr_mode+0x1dc>
cvtss2sd %xmm0,%xmm0
mulsd  0xdda(%rip),%xmm0
cvtss2sd %xmm1,%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
ret
addss  %xmm1,%xmm0
ret
movslq %eax,%rcx
mov    (%rdi,%rcx,4),%edx
mov    %edx,%esi
sub    -0x4(%rdi,%rcx,4),%esi
xorps  %xmm2,%xmm2
cvtsi2ss %esi,%xmm2
sub    0x4(%rdi,%rcx,4),%edx
xorps  %xmm3,%xmm3
cvtsi2ss %edx,%xmm3
movaps %xmm2,%xmm4
addss  %xmm3,%xmm4
movaps 0xdb4(%rip),%xmm5
xorps  %xmm4,%xmm5
xorps  %xmm6,%xmm6
cmpltss %xmm4,%xmm6
andps  %xmm6,%xmm4
andnps %xmm5,%xmm6
orps   %xmm4,%xmm6
xorps  %xmm4,%xmm4
cvtss2sd %xmm6,%xmm4
movsd  0xd81(%rip),%xmm5
ucomisd %xmm4,%xmm5
jbe    12a6 <cr_mode+0x1a6>
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
addsd  0xd64(%rip),%xmm2
jmp    12d8 <cr_mode+0x1d8>
add    $0x1,%eax
xorps  %xmm5,%xmm5
cvtsi2sd %eax,%xmm5
subss  %xmm3,%xmm2
cvtss2sd %xmm2,%xmm2
mulsd  0xd48(%rip),%xmm2
divsd  %xmm4,%xmm2
addsd  %xmm5,%xmm2
cvtsd2ss %xmm2,%xmm2
cvtss2sd %xmm2,%xmm2
addsd  0xd40(%rip),%xmm2
cvtss2sd %xmm1,%xmm1
cvtss2sd %xmm0,%xmm0
mulsd  %xmm2,%xmm0
jmp    1232 <cr_mode+0x132>

LLVM IR (-O0):
define float @cr_mode(i32* %0, i32 %1, float %2, float %3) {
%5 = alloca float
%6 = alloca i32*
%7 = alloca i32
%8 = alloca float
%9 = alloca float
%10 = alloca i32
%11 = alloca i32
%12 = alloca float
%13 = alloca float
%14 = alloca float
%15 = alloca float
%16 = alloca float
store i32* %0, i32** %6
store i32 %1, i32* %7
store float %2, float* %8
store float %3, float* %9
%17 = load i32, i32* %7
%18 = icmp eq i32 %17, 1
br i1 %18, label %19, label %26
19: ; preds = %4
%20 = load float, float* %9
%21 = fpext float %20 to double
%22 = load float, float* %8
%23 = fpext float %22 to double
%24 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %23, double %21)
%25 = fptrunc double %24 to float
store float %25, float* %5
br label %266
26: ; preds = %4
%27 = load i32, i32* %7
%28 = icmp eq i32 %27, 2
br i1 %28, label %29, label %66
29: ; preds = %26
%30 = load i32*, i32** %6
%31 = getelementptr inbounds i32, i32* %30, i64 0
%32 = load i32, i32* %31
%33 = load i32*, i32** %6
%34 = getelementptr inbounds i32, i32* %33, i64 1
%35 = load i32, i32* %34
%36 = icmp sgt i32 %32, %35
br i1 %36, label %37, label %44
37: ; preds = %29
%38 = load float, float* %9
%39 = fpext float %38 to double
%40 = load float, float* %8
%41 = fpext float %40 to double
%42 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %41, double %39)
%43 = fptrunc double %42 to float
store float %43, float* %12
br label %64
44: ; preds = %29
%45 = load i32*, i32** %6
%46 = getelementptr inbounds i32, i32* %45, i64 1
%47 = load i32, i32* %46
%48 = load i32*, i32** %6
%49 = getelementptr inbounds i32, i32* %48, i64 0
%50 = load i32, i32* %49
%51 = icmp sgt i32 %47, %50
br i1 %51, label %52, label %59
52: ; preds = %44
%53 = load float, float* %9
%54 = fpext float %53 to double
%55 = load float, float* %8
%56 = fpext float %55 to double
%57 = call double @llvm.fmuladd.f64(double 1.500000e+00, double %56, double %54)
%58 = fptrunc double %57 to float
store float %58, float* %12
br label %63
59: ; preds = %44
%60 = load float, float* %9
%61 = load float, float* %8
%62 = fadd float %60, %61
store float %62, float* %12
br label %63
63: ; preds = %59, %52
br label %64
64: ; preds = %63, %37
%65 = load float, float* %12
store float %65, float* %5
br label %266
66: ; preds = %26
%67 = load i32*, i32** %6
%68 = getelementptr inbounds i32, i32* %67, i64 0
%69 = load i32, i32* %68
%70 = sitofp i32 %69 to float
store float %70, float* %13
store i32 0, i32* %11
store i32 1, i32* %10
br label %71
71: ; preds = %93, %66
%72 = load i32, i32* %10
%73 = load i32, i32* %7
%74 = icmp slt i32 %72, %73
br i1 %74, label %75, label %96
75: ; preds = %71
%76 = load i32*, i32** %6
%77 = load i32, i32* %10
%78 = sext i32 %77 to i64
%79 = getelementptr inbounds i32, i32* %76, i64 %78
%80 = load i32, i32* %79
%81 = sitofp i32 %80 to float
%82 = load float, float* %13
%83 = fcmp ogt float %81, %82
br i1 %83, label %84, label %92
84: ; preds = %75
%85 = load i32*, i32** %6
%86 = load i32, i32* %10
%87 = sext i32 %86 to i64
%88 = getelementptr inbounds i32, i32* %85, i64 %87
%89 = load i32, i32* %88
%90 = sitofp i32 %89 to float
store float %90, float* %13
%91 = load i32, i32* %10
store i32 %91, i32* %11
br label %92
92: ; preds = %84, %75
br label %93
93: ; preds = %92
%94 = load i32, i32* %10
%95 = add nsw i32 %94, 1
store i32 %95, i32* %10
br label %71
96: ; preds = %71
%97 = load i32, i32* %11
%98 = icmp eq i32 %97, 0
br i1 %98, label %99, label %106
99: ; preds = %96
%100 = load float, float* %9
%101 = fpext float %100 to double
%102 = load float, float* %8
%103 = fpext float %102 to double
%104 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %103, double %101)
%105 = fptrunc double %104 to float
store float %105, float* %5
br label %266
106: ; preds = %96
%107 = load i32, i32* %11
%108 = load i32, i32* %7
%109 = sub nsw i32 %108, 1
%110 = icmp eq i32 %107, %109
br i1 %110, label %111, label %121
111: ; preds = %106
%112 = load float, float* %9
%113 = fpext float %112 to double
%114 = load i32, i32* %7
%115 = sitofp i32 %114 to double
%116 = fsub double %115, 5.000000e-01
%117 = load float, float* %8
%118 = fpext float %117 to double
%119 = call double @llvm.fmuladd.f64(double %116, double %118, double %113)
%120 = fptrunc double %119 to float
store float %120, float* %5
br label %266
121: ; preds = %106
%122 = load i32*, i32** %6
%123 = load i32, i32* %11
%124 = sext i32 %123 to i64
%125 = getelementptr inbounds i32, i32* %122, i64 %124
%126 = load i32, i32* %125
%127 = load i32*, i32** %6
%128 = load i32, i32* %11
%129 = sub nsw i32 %128, 1
%130 = sext i32 %129 to i64
%131 = getelementptr inbounds i32, i32* %127, i64 %130
%132 = load i32, i32* %131
%133 = sub nsw i32 %126, %132
%134 = sitofp i32 %133 to float
store float %134, float* %14
%135 = load i32*, i32** %6
%136 = load i32, i32* %11
%137 = sext i32 %136 to i64
%138 = getelementptr inbounds i32, i32* %135, i64 %137
%139 = load i32, i32* %138
%140 = load i32*, i32** %6
%141 = load i32, i32* %11
%142 = add nsw i32 %141, 1
%143 = sext i32 %142 to i64
%144 = getelementptr inbounds i32, i32* %140, i64 %143
%145 = load i32, i32* %144
%146 = sub nsw i32 %139, %145
%147 = sitofp i32 %146 to float
store float %147, float* %15
%148 = load float, float* %14
%149 = load float, float* %15
%150 = fadd float %148, %149
store float %150, float* %16
%151 = load float, float* %16
%152 = fpext float %151 to double
%153 = fcmp ogt double %152, 0.000000e+00
br i1 %153, label %154, label %156
154: ; preds = %121
%155 = load float, float* %16
br label %159
156: ; preds = %121
%157 = load float, float* %16
%158 = fneg float %157
br label %159
159: ; preds = %156, %154
%160 = phi float [ %155, %154 ], [ %158, %156 ]
store float %160, float* %16
%161 = fpext float %160 to double
%162 = fcmp olt double %161, 0x3BC79CA10C924223
br i1 %162, label %163, label %173
163: ; preds = %159
%164 = load float, float* %9
%165 = fpext float %164 to double
%166 = load i32, i32* %11
%167 = sitofp i32 %166 to double
%168 = fadd double %167, 5.000000e-01
%169 = load float, float* %8
%170 = fpext float %169 to double
%171 = call double @llvm.fmuladd.f64(double %168, double %170, double %165)
%172 = fptrunc double %171 to float
store float %172, float* %12
br label %196
173: ; preds = %159
%174 = load i32, i32* %11
%175 = add nsw i32 %174, 1
%176 = sitofp i32 %175 to double
%177 = load float, float* %14
%178 = load float, float* %15
%179 = fsub float %177, %178
%180 = fpext float %179 to double
%181 = fmul double 5.000000e-01, %180
%182 = load float, float* %16
%183 = fpext float %182 to double
%184 = fdiv double %181, %183
%185 = fadd double %176, %184
%186 = fptrunc double %185 to float
store float %186, float* %12
%187 = load float, float* %9
%188 = fpext float %187 to double
%189 = load float, float* %12
%190 = fpext float %189 to double
%191 = fsub double %190, 5.000000e-01
%192 = load float, float* %8
%193 = fpext float %192 to double
%194 = call double @llvm.fmuladd.f64(double %191, double %193, double %188)
%195 = fptrunc double %194 to float
store float %195, float* %12
br label %196
196: ; preds = %173, %163
%197 = load i32*, i32** %6
%198 = load i32, i32* %11
%199 = sub nsw i32 %198, 1
%200 = sext i32 %199 to i64
%201 = getelementptr inbounds i32, i32* %197, i64 %200
%202 = load i32, i32* %201
%203 = sitofp i32 %202 to double
%204 = load float, float* %9
%205 = fpext float %204 to double
%206 = load i32, i32* %11
%207 = sitofp i32 %206 to double
%208 = fsub double %207, 5.000000e-01
%209 = load float, float* %8
%210 = fpext float %209 to double
%211 = call double @llvm.fmuladd.f64(double %208, double %210, double %205)
%212 = load i32*, i32** %6
%213 = load i32, i32* %11
%214 = sext i32 %213 to i64
%215 = getelementptr inbounds i32, i32* %212, i64 %214
%216 = load i32, i32* %215
%217 = sitofp i32 %216 to double
%218 = load float, float* %9
%219 = fpext float %218 to double
%220 = load i32, i32* %11
%221 = sitofp i32 %220 to double
%222 = fadd double %221, 5.000000e-01
%223 = load float, float* %8
%224 = fpext float %223 to double
%225 = call double @llvm.fmuladd.f64(double %222, double %224, double %219)
%226 = fmul double %217, %225
%227 = call double @llvm.fmuladd.f64(double %203, double %211, double %226)
%228 = load i32*, i32** %6
%229 = load i32, i32* %11
%230 = add nsw i32 %229, 1
%231 = sext i32 %230 to i64
%232 = getelementptr inbounds i32, i32* %228, i64 %231
%233 = load i32, i32* %232
%234 = sitofp i32 %233 to double
%235 = load float, float* %9
%236 = fpext float %235 to double
%237 = load i32, i32* %11
%238 = sitofp i32 %237 to double
%239 = fadd double %238, 1.500000e+00
%240 = load float, float* %8
%241 = fpext float %240 to double
%242 = call double @llvm.fmuladd.f64(double %239, double %241, double %236)
%243 = call double @llvm.fmuladd.f64(double %234, double %242, double %227)
%244 = fptrunc double %243 to float
store float %244, float* %14
%245 = load i32*, i32** %6
%246 = load i32, i32* %11
%247 = sub nsw i32 %246, 1
%248 = sext i32 %247 to i64
%249 = getelementptr inbounds i32, i32* %245, i64 %248
%250 = load i32, i32* %249
%251 = load i32*, i32** %6
%252 = load i32, i32* %11
%253 = sext i32 %252 to i64
%254 = getelementptr inbounds i32, i32* %251, i64 %253
%255 = load i32, i32* %254
%256 = add nsw i32 %250, %255
%257 = load i32*, i32** %6
%258 = load i32, i32* %11
%259 = add nsw i32 %258, 1
%260 = sext i32 %259 to i64
%261 = getelementptr inbounds i32, i32* %257, i64 %260
%262 = load i32, i32* %261
%263 = add nsw i32 %256, %262
%264 = sitofp i32 %263 to float
store float %264, float* %15
%265 = load float, float* %12
store float %265, float* %5
br label %266
266: ; preds = %196, %111, %99, %64, %19
%267 = load float, float* %5
ret float %267
}

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