#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 */
int /*<<< orphan*/ ComputeMrfProbability(double *, double *, unsigned char *,
                                         int, int, int, int *, int, double,
                                         double *);
scalar_t__ MaxArg(double *, int);
int /*<<< orphan*/ fflush(int /*<<< orphan*/);
int /*<<< orphan*/ printf(char *, ...);
int /*<<< orphan*/ stdout;
void ICM(unsigned char *prob, unsigned char *label, int n_classes, int *dims,
         double beta, int iterations, double *voxelsize) {
  int i, iter, x, y, z, z_area, y_dims, index, sum_voxel;
  long area, vol;
  double rel_changed, mrf_probability[6], voxelsize_squared[3];
  double exponent[6], sum_voxelsize = 0.0;
  unsigned char new_label;
  area = dims[0] * dims[1];
  vol = area * dims[2];
  for (i = 0; i < 3; i++)
    sum_voxelsize += voxelsize[i];
  for (i = 0; i < 3; i++)
    voxelsize_squared[i] = ((3.0 * voxelsize[i] / sum_voxelsize) *
                            (3.0 * voxelsize[i] / sum_voxelsize));
  for (iter = 0; iter < iterations; iter++) {
    sum_voxel = 0;
    rel_changed = 0.0;
    for (z = 1; z < dims[2] - 1; z++) {
      z_area = z * area;
      for (y = 1; y < dims[1] - 1; y++) {
        y_dims = y * dims[0];
        for (x = 1; x < dims[0] - 1; x++) {
          index = x + y_dims + z_area;
          if (label[index] == 0)
            continue;
          sum_voxel++;
          ComputeMrfProbability(mrf_probability, exponent, label, x, y, z, dims,
                                n_classes, beta, voxelsize_squared);
          for (i = 0; i < n_classes; i++)
            mrf_probability[i] *= (double)prob[index + i * vol];
          new_label = (unsigned char)MaxArg(mrf_probability, n_classes);
          if (new_label != label[index]) {
            rel_changed += 1.0;
            label[index] = new_label;
          }
        }
      }
    }
    rel_changed /= (double)sum_voxel;
    printf("ICM: %d relative change: "
           "%2."
           "4f\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
           "\b\b",
           iter + 1, 100.0 * rel_changed);
    fflush(stdout);
    if (rel_changed < 0.001)
      break;
  }
  printf("\n");
}


x86 assembly (clang, -O0):
<ICM>:
push   %rbp
mov    %rsp,%rbp
sub    $0x130,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %rcx,-0x20(%rbp)
movsd  %xmm0,-0x28(%rbp)
mov    %r8d,-0x2c(%rbp)
mov    %r9,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x108(%rbp)
ff
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
mov    -0x20(%rbp),%rcx
imul   0x4(%rcx),%eax
cltq
mov    %rax,-0x68(%rbp)
mov    -0x68(%rbp),%rax
mov    -0x20(%rbp),%rcx
movslq 0x8(%rcx),%rcx
imul   %rcx,%rax
mov    %rax,-0x70(%rbp)
movl   $0x0,-0x3c(%rbp)
cmpl   $0x3,-0x3c(%rbp)
jge    11d6 <ICM+0x96>
mov    -0x38(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x108(%rbp),%xmm0
ff
movsd  %xmm0,-0x108(%rbp)
ff
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    11a1 <ICM+0x61>
movl   $0x0,-0x3c(%rbp)
cmpl   $0x3,-0x3c(%rbp)
jge    1240 <ICM+0x100>
mov    -0x38(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  0xe21(%rip),%xmm0
mulsd  (%rax,%rcx,8),%xmm0
divsd  -0x108(%rbp),%xmm0
ff
mov    -0x38(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  0xe04(%rip),%xmm1
mulsd  (%rax,%rcx,8),%xmm1
divsd  -0x108(%rbp),%xmm1
ff
mulsd  %xmm1,%xmm0
movslq -0x3c(%rbp),%rax
movsd  %xmm0,-0xd0(%rbp,%rax,8)
ff ff
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    11dd <ICM+0x9d>
movl   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    1490 <ICM+0x350>
movl   $0x0,-0x5c(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x78(%rbp)
movl   $0x1,-0x4c(%rbp)
mov    -0x4c(%rbp),%eax
mov    -0x20(%rbp),%rcx
mov    0x8(%rcx),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1423 <ICM+0x2e3>
movslq -0x4c(%rbp),%rax
imul   -0x68(%rbp),%rax
mov    %eax,-0x50(%rbp)
movl   $0x1,-0x48(%rbp)
mov    -0x48(%rbp),%eax
mov    -0x20(%rbp),%rcx
mov    0x4(%rcx),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1410 <ICM+0x2d0>
mov    -0x48(%rbp),%eax
mov    -0x20(%rbp),%rcx
imul   (%rcx),%eax
mov    %eax,-0x54(%rbp)
movl   $0x1,-0x44(%rbp)
mov    -0x44(%rbp),%eax
mov    -0x20(%rbp),%rcx
mov    (%rcx),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    13fd <ICM+0x2bd>
mov    -0x44(%rbp),%eax
add    -0x54(%rbp),%eax
add    -0x50(%rbp),%eax
mov    %eax,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x58(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
jne    12f4 <ICM+0x1b4>
jmp    13ef <ICM+0x2af>
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
lea    -0xb0(%rbp),%rdi
lea    -0x100(%rbp),%rsi
mov    -0x10(%rbp),%rdx
mov    -0x44(%rbp),%ecx
mov    -0x48(%rbp),%r8d
mov    -0x4c(%rbp),%r9d
mov    -0x20(%rbp),%r11
mov    -0x14(%rbp),%r10d
movsd  -0x28(%rbp),%xmm0
lea    -0xd0(%rbp),%rax
mov    %r11,(%rsp)
mov    %r10d,0x8(%rsp)
mov    %rax,0x10(%rsp)
call   1030 <ComputeMrfProbability@plt>
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1397 <ICM+0x257>
mov    -0x8(%rbp),%rax
movslq -0x58(%rbp),%rcx
movslq -0x3c(%rbp),%rdx
mov    -0x70(%rbp),%rsi
imul   %rsi,%rdx
add    %rdx,%rcx
movzbl (%rax,%rcx,1),%eax
cvtsi2sd %eax,%xmm0
movslq -0x3c(%rbp),%rax
mulsd  -0xb0(%rbp,%rax,8),%xmm0
ff ff
movsd  %xmm0,-0xb0(%rbp,%rax,8)
ff ff
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1348 <ICM+0x208>
lea    -0xb0(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1040 <MaxArg@plt>
mov    %al,-0x109(%rbp)
movzbl -0x109(%rbp),%eax
mov    -0x10(%rbp),%rcx
movslq -0x58(%rbp),%rdx
movzbl (%rcx,%rdx,1),%ecx
cmp    %ecx,%eax
je     13ea <ICM+0x2aa>
movsd  0xc41(%rip),%xmm0
addsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x109(%rbp),%dl
mov    -0x10(%rbp),%rax
movslq -0x58(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    13ef <ICM+0x2af>
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    12ba <ICM+0x17a>
jmp    1402 <ICM+0x2c2>
mov    -0x48(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x48(%rbp)
jmp    1291 <ICM+0x151>
jmp    1415 <ICM+0x2d5>
mov    -0x4c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4c(%rbp)
jmp    1269 <ICM+0x129>
cvtsi2sdl -0x5c(%rbp),%xmm1
movsd  -0x78(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x40(%rbp),%esi
add    $0x1,%esi
movsd  0xbc4(%rip),%xmm0
mulsd  -0x78(%rbp),%xmm0
lea    0xbd0(%rip),%rdi
mov    $0x1,%al
call   1050 <printf@plt>
mov    0x2b82(%rip),%rax
mov    (%rax),%edi
call   1060 <fflush@plt>
movsd  0xb93(%rip),%xmm0
ucomisd -0x78(%rbp),%xmm0
jbe    147d <ICM+0x33d>
jmp    1490 <ICM+0x350>
jmp    1482 <ICM+0x342>
mov    -0x40(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x40(%rbp)
jmp    1247 <ICM+0x107>
lea    0xbca(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
add    $0x130,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ICM>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x108,%rsp
movsd  %xmm0,0x78(%rsp)
mov    %rcx,%r10
mov    %rsi,%r13
mov    %rdi,0x40(%rsp)
mov    0x4(%rcx),%eax
imul   (%rcx),%eax
movslq 0x8(%rcx),%rcx
movupd (%r9),%xmm0
xorpd  %xmm1,%xmm1
addsd  %xmm0,%xmm1
movapd %xmm0,%xmm2
unpckhpd %xmm0,%xmm2
addsd  %xmm1,%xmm2
movsd  0x10(%r9),%xmm1
addsd  %xmm1,%xmm2
mov    %eax,0x1c(%rsp)
cltq
mulpd  0xe53(%rip),%xmm0
mulsd  0xe5b(%rip),%xmm1
divsd  %xmm2,%xmm1
unpcklpd %xmm2,%xmm2
divpd  %xmm2,%xmm0
mulpd  %xmm0,%xmm0
movapd %xmm0,0xb0(%rsp)
mulsd  %xmm1,%xmm1
movsd  %xmm1,0xc0(%rsp)
imul   %rax,%rcx
xor    %esi,%esi
test   %r8d,%r8d
cmovle %esi,%r8d
mov    %r8d,0x30(%rsp)
mov    %rdx,0x70(%rsp)
mov    %edx,%r15d
mov    %r15,0x60(%rsp)
and    $0xfffffffe,%r15d
add    $0x1,%eax
mov    %rax,0x50(%rsp)
xor    %ebx,%ebx
mov    %rcx,0x38(%rsp)
lea    (%rcx,%rcx,1),%r12
mov    %r10,0x28(%rsp)
mov    %r13,0x68(%rsp)
jmp    1296 <ICM+0x146>
nopl   (%rax)
xorpd  %xmm0,%xmm0
movsd  %xmm0,0x10(%rsp)
movl   $0x0,0xc(%rsp)
xorps  %xmm0,%xmm0
cvtsi2sdl 0xc(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rsp)
mov    0x58(%rsp),%rbx
add    $0x1,%ebx
movapd %xmm1,%xmm0
mulsd  0xdc1(%rip),%xmm0
lea    0xdca(%rip),%rdi
mov    %ebx,%esi
mov    $0x1,%al
call   1060 <printf@plt>
mov    0x2d6a(%rip),%rax
mov    (%rax),%edi
call   1070 <fflush@plt>
mov    0x28(%rsp),%r10
movsd  0xd9e(%rip),%xmm0
ucomisd 0x10(%rsp),%xmm0
ja     14cd <ICM+0x37d>
cmp    0x30(%rsp),%ebx
je     14cd <ICM+0x37d>
mov    0x8(%r10),%ecx
cmp    $0x3,%ecx
mov    %rbx,0x58(%rsp)
jl     1220 <ICM+0xd0>
mov    0x4(%r10),%eax
movl   $0x1,0x4(%rsp)
movl   $0x0,0xc(%rsp)
xorpd  %xmm0,%xmm0
movsd  %xmm0,0x10(%rsp)
mov    0x50(%rsp),%rdx
mov    %rdx,0x20(%rsp)
jmp    1308 <ICM+0x1b8>
nopl   0x0(%rax)
mov    0x8(%r10),%ecx
mov    0x4(%rsp),%esi
add    $0x1,%esi
lea    -0x1(%rcx),%edx
mov    0x20(%rsp),%rdi
add    0x1c(%rsp),%edi
mov    %rdi,0x20(%rsp)
mov    %esi,0x4(%rsp)
cmp    %edx,%esi
jge    1232 <ICM+0xe2>
cmp    $0x3,%eax
jl     12e4 <ICM+0x194>
mov    0x4(%rsp),%ecx
imul   0x1c(%rsp),%ecx
mov    %ecx,0x34(%rsp)
mov    (%r10),%esi
movl   $0x1,0x8(%rsp)
jmp    1348 <ICM+0x1f8>
nopw   0x0(%rax,%rax,1)
mov    0x4(%r10),%eax
mov    %ecx,%esi
mov    0x8(%rsp),%edx
add    $0x1,%edx
lea    -0x1(%rax),%ecx
mov    %edx,0x8(%rsp)
cmp    %ecx,%edx
jge    12e0 <ICM+0x190>
cmp    $0x3,%esi
jl     1336 <ICM+0x1e6>
imul   0x8(%rsp),%esi
mov    0x20(%rsp),%rax
lea    (%rax,%rsi,1),%ebp
add    0x34(%rsp),%esi
mov    $0x1,%r14d
mov    %rsi,0x48(%rsp)
jmp    138d <ICM+0x23d>
nopl   0x0(%rax,%rax,1)
mov    0x28(%rsp),%r10
mov    0x48(%rsp),%rsi
add    $0x1,%r14
movslq (%r10),%rcx
lea    -0x1(%rcx),%rax
add    $0x1,%ebp
cmp    %rax,%r14
jge    1330 <ICM+0x1e0>
lea    (%rsi,%r14,1),%eax
movslq %eax,%rbx
cmpb   $0x0,0x0(%r13,%rbx,1)
je     137a <ICM+0x22a>
sub    $0x8,%rsp
lea    0x88(%rsp),%rdi
lea    0xd8(%rsp),%rsi
mov    %r13,%rdx
mov    %r14d,%ecx
mov    0x10(%rsp),%r8d
mov    0xc(%rsp),%r9d
movsd  0x80(%rsp),%xmm0
lea    0xb8(%rsp),%rax
push   %rax
mov    0x80(%rsp),%r13
push   %r13
push   %r10
call   1040 <ComputeMrfProbability@plt>
add    $0x20,%rsp
test   %r13d,%r13d
jle    148a <ICM+0x33a>
cmp    $0x1,%r13d
jne    13fa <ICM+0x2aa>
xor    %eax,%eax
jmp    1455 <ICM+0x305>
movslq %ebp,%rcx
add    0x40(%rsp),%rcx
xor    %eax,%eax
mov    0x38(%rsp),%rdi
nopl   0x0(%rax)
movzbl (%rcx),%edx
xorps  %xmm0,%xmm0
cvtsi2sd %edx,%xmm0
mulsd  0x80(%rsp,%rax,8),%xmm0
movsd  %xmm0,0x80(%rsp,%rax,8)
movzbl (%rcx,%rdi,1),%edx
xorps  %xmm0,%xmm0
cvtsi2sd %edx,%xmm0
mulsd  0x88(%rsp,%rax,8),%xmm0
movsd  %xmm0,0x88(%rsp,%rax,8)
add    $0x2,%rax
add    %r12,%rcx
cmp    %rax,%r15
jne    1410 <ICM+0x2c0>
testb  $0x1,0x60(%rsp)
je     148a <ICM+0x33a>
mov    0x38(%rsp),%rcx
imul   %rax,%rcx
add    %rbx,%rcx
mov    0x40(%rsp),%rdx
movzbl (%rdx,%rcx,1),%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
mulsd  0x80(%rsp,%rax,8),%xmm0
movsd  %xmm0,0x80(%rsp,%rax,8)
addl   $0x1,0xc(%rsp)
lea    0x80(%rsp),%rdi
mov    %r13d,%esi
call   1050 <MaxArg@plt>
mov    0x68(%rsp),%r13
cmp    %al,0x0(%r13,%rbx,1)
je     1370 <ICM+0x220>
movsd  0x10(%rsp),%xmm0
addsd  0xb5b(%rip),%xmm0
movsd  %xmm0,0x10(%rsp)
mov    %al,0x0(%r13,%rbx,1)
jmp    1370 <ICM+0x220>
mov    $0xa,%edi
call   1030 <putchar@plt>
add    $0x108,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
@.str = [65 x i8] c"ICM: %d relative change: %2.4f\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\00"
@stdout = global i32 0
define void @ICM(i8* nocapture %0, i8* %1, i32 %2, i32* %3, double %4, i32 %5, double* nocapture %6) {
%8 = alloca [6 x double]
%9 = alloca [3 x double]
%10 = alloca [6 x double]
%11 = bitcast [6 x double]* %8 to i8*
%12 = bitcast [3 x double]* %9 to i8*
%13 = bitcast [6 x double]* %10 to i8*
%14 = load i32, i32* %3
%15 = getelementptr inbounds i32, i32* %3, i64 1
%16 = load i32, i32* %15
%17 = mul nsw i32 %16, %14
%18 = getelementptr inbounds i32, i32* %3, i64 2
%19 = load i32, i32* %18
%20 = sext i32 %19 to i64
%21 = bitcast double* %6 to <2 x double>*
%22 = load <2 x double>, <2 x double>* %21
%23 = extractelement <2 x double> %22, i64 0
%24 = fadd double %23, 0.000000e+00
%25 = extractelement <2 x double> %22, i64 1
%26 = fadd double %24, %25
%27 = getelementptr inbounds double, double* %6, i64 2
%28 = load double, double* %27
%29 = fadd double %26, %28
%30 = sext i32 %17 to i64
%31 = getelementptr inbounds [3 x double], [3 x double]* %9, i64 0, i64 0
%32 = fmul <2 x double> %22, <double 3.000000e+00, double 3.000000e+00>
%33 = insertelement <2 x double> poison, double %29, i64 0
%34 = shufflevector <2 x double> %33, <2 x double> poison, <2 x i32> zeroinitializer
%35 = fdiv <2 x double> %32, %34
%36 = fmul <2 x double> %35, %35
%37 = bitcast [3 x double]* %9 to <2 x double>*
store <2 x double> %36, <2 x double>* %37
%38 = fmul double %28, 3.000000e+00
%39 = fdiv double %38, %29
%40 = fmul double %39, %39
%41 = getelementptr inbounds [3 x double], [3 x double]* %9, i64 0, i64 2
store double %40, double* %41
%42 = mul nsw i64 %30, %20
%43 = getelementptr inbounds [6 x double], [6 x double]* %8, i64 0, i64 0
%44 = getelementptr inbounds [6 x double], [6 x double]* %10, i64 0, i64 0
%45 = icmp sgt i32 %2, 0
%46 = call i32 @llvm.smax.i32(i32 %5, i32 0)
%47 = zext i32 %2 to i64
%48 = and i64 %47, 1
%49 = icmp eq i32 %2, 1
%50 = and i64 %47, 4294967294
%51 = icmp eq i64 %48, 0
br label %52
52: ; preds = %7, %165
%53 = phi i32 [ %170, %165 ], [ 0, %7 ]
%54 = icmp eq i32 %53, %46
br i1 %54, label %176, label %55
55: ; preds = %52
%56 = load i32, i32* %18
%57 = icmp sgt i32 %56, 2
br i1 %57, label %58, label %165
58: ; preds = %55
%59 = load i32, i32* %15
br label %60
60: ; preds = %58, %156
%61 = phi i32 [ %157, %156 ], [ %56, %58 ]
%62 = phi i32 [ %158, %156 ], [ %59, %58 ]
%63 = phi i32 [ %159, %156 ], [ %59, %58 ]
%64 = phi double [ %161, %156 ], [ 0.000000e+00, %58 ]
%65 = phi i32 [ %160, %156 ], [ 0, %58 ]
%66 = phi i32 [ %162, %156 ], [ 1, %58 ]
%67 = mul i32 %66, %17
%68 = icmp sgt i32 %63, 2
br i1 %68, label %69, label %156
69: ; preds = %60
%70 = load i32, i32* %3
br label %71
71: ; preds = %69, %146
%72 = phi i32 [ %147, %146 ], [ %62, %69 ]
%73 = phi i32 [ %148, %146 ], [ %70, %69 ]
%74 = phi double [ %150, %146 ], [ %64, %69 ]
%75 = phi i32 [ %149, %146 ], [ %65, %69 ]
%76 = phi i32 [ %151, %146 ], [ 1, %69 ]
%77 = icmp sgt i32 %73, 2
br i1 %77, label %78, label %146
78: ; preds = %71
%79 = mul nsw i32 %73, %76
%80 = add i32 %79, %67
br label %81
81: ; preds = %78, %136
%82 = phi i64 [ 1, %78 ], [ %139, %136 ]
%83 = phi double [ %74, %78 ], [ %138, %136 ]
%84 = phi i32 [ %75, %78 ], [ %137, %136 ]
%85 = trunc i64 %82 to i32
%86 = add i32 %80, %85
%87 = sext i32 %86 to i64
%88 = getelementptr inbounds i8, i8* %1, i64 %87
%89 = load i8, i8* %88
%90 = icmp eq i8 %89, 0
br i1 %90, label %136, label %91
91: ; preds = %81
%92 = add nsw i32 %84, 1
%93 = call i32 @ComputeMrfProbability(double* %43, double* %44, i8* %1, i32 %85, i32 %76, i32 %66, i32* %3, i32 %2, double %4, double* %31)
br i1 %45, label %94, label %129
94: ; preds = %91
br i1 %49, label %118, label %95
95: ; preds = %94, %95
%96 = phi i64 [ %115, %95 ], [ 0, %94 ]
%97 = phi i64 [ %116, %95 ], [ 0, %94 ]
%98 = mul nsw i64 %42, %96
%99 = add nsw i64 %98, %87
%100 = getelementptr inbounds i8, i8* %0, i64 %99
%101 = load i8, i8* %100
%102 = uitofp i8 %101 to double
%103 = getelementptr inbounds [6 x double], [6 x double]* %8, i64 0, i64 %96
%104 = load double, double* %103
%105 = fmul double %104, %102
store double %105, double* %103
%106 = or i64 %96, 1
%107 = mul nsw i64 %42, %106
%108 = add nsw i64 %107, %87
%109 = getelementptr inbounds i8, i8* %0, i64 %108
%110 = load i8, i8* %109
%111 = uitofp i8 %110 to double
%112 = getelementptr inbounds [6 x double], [6 x double]* %8, i64 0, i64 %106
%113 = load double, double* %112
%114 = fmul double %113, %111
store double %114, double* %112
%115 = add nuw nsw i64 %96, 2
%116 = add i64 %97, 2
%117 = icmp eq i64 %116, %50
br i1 %117, label %118, label %95
118: ; preds = %95, %94
%119 = phi i64 [ 0, %94 ], [ %115, %95 ]
br i1 %51, label %129, label %120
120: ; preds = %118
%121 = mul nsw i64 %42, %119
%122 = add nsw i64 %121, %87
%123 = getelementptr inbounds i8, i8* %0, i64 %122
%124 = load i8, i8* %123
%125 = uitofp i8 %124 to double
%126 = getelementptr inbounds [6 x double], [6 x double]* %8, i64 0, i64 %119
%127 = load double, double* %126
%128 = fmul double %127, %125
store double %128, double* %126
br label %129
129: ; preds = %120, %118, %91
%130 = call i64 @MaxArg(double* %43, i32 %2)
%131 = load i8, i8* %88
%132 = trunc i64 %130 to i8
%133 = icmp eq i8 %131, %132
br i1 %133, label %136, label %134
134: ; preds = %129
%135 = fadd double %83, 1.000000e+00
store i8 %132, i8* %88
br label %136
136: ; preds = %129, %134, %81
%137 = phi i32 [ %84, %81 ], [ %92, %134 ], [ %92, %129 ]
%138 = phi double [ %83, %81 ], [ %135, %134 ], [ %83, %129 ]
%139 = add nuw nsw i64 %82, 1
%140 = load i32, i32* %3
%141 = add nsw i32 %140, -1
%142 = sext i32 %141 to i64
%143 = icmp slt i64 %139, %142
br i1 %143, label %81, label %144
144: ; preds = %136
%145 = load i32, i32* %15
br label %146
146: ; preds = %144, %71
%147 = phi i32 [ %72, %71 ], [ %145, %144 ]
%148 = phi i32 [ %73, %71 ], [ %140, %144 ]
%149 = phi i32 [ %75, %71 ], [ %137, %144 ]
%150 = phi double [ %74, %71 ], [ %138, %144 ]
%151 = add nuw nsw i32 %76, 1
%152 = add nsw i32 %147, -1
%153 = icmp slt i32 %151, %152
br i1 %153, label %71, label %154
154: ; preds = %146
%155 = load i32, i32* %18
br label %156
156: ; preds = %154, %60
%157 = phi i32 [ %61, %60 ], [ %155, %154 ]
%158 = phi i32 [ %62, %60 ], [ %147, %154 ]
%159 = phi i32 [ %63, %60 ], [ %147, %154 ]
%160 = phi i32 [ %65, %60 ], [ %149, %154 ]
%161 = phi double [ %64, %60 ], [ %150, %154 ]
%162 = add nuw nsw i32 %66, 1
%163 = add nsw i32 %157, -1
%164 = icmp slt i32 %162, %163
br i1 %164, label %60, label %165
165: ; preds = %156, %55
%166 = phi i32 [ 0, %55 ], [ %160, %156 ]
%167 = phi double [ 0.000000e+00, %55 ], [ %161, %156 ]
%168 = sitofp i32 %166 to double
%169 = fdiv double %167, %168
%170 = add nuw i32 %53, 1
%171 = fmul double %169, 1.000000e+02
%172 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i64 0, i64 0), i32 %170, double %171)
%173 = load i32, i32* @stdout
%174 = call i32 @fflush(i32 %173)
%175 = fcmp olt double %169, 1.000000e-03
br i1 %175, label %176, label %52
176: ; preds = %165, %52
%177 = call i32 @putchar(i32 10)
ret void
}