#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*/ e_step(size_t, size_t, double const *, double *, double *,
                          double *, double *);
double const fabs(double);
int /*<<< orphan*/ free(double *);
int /*<<< orphan*/ m_step(size_t, size_t, double const *, double *, double *,
                          double *, double *);
double *malloc(size_t);
int /*<<< orphan*/ memcpy(double *, double *, size_t);
int /*<<< orphan*/ print_progress(size_t, double *, double *, double *);
scalar_t__ sq(double const);
void fit_gaussian_mixture(const double *xs, size_t n, size_t k, double *ps,
                          double *mus, double *sds) {
  double *zs = malloc(k * n * sizeof(double));
  size_t i;
  double init_p = 1.0 / (double)k;
  for (i = 0; i < k; ++i)
    ps[i] = init_p;
  double mu = 0.0;
  for (i = 0; i < n; ++i)
    mu += xs[i];
  mu /= (double)n;
  double sd = 0.0;
  for (i = 0; i < n; ++i)
    sd += sq(xs[i] - mu);
  sd /= (double)(n - 1);
  for (i = 0; i < k; ++i)
    sds[i] = sd;
  for (i = 0; i < k; ++i) {
    mus[i] = mu + 3.0 * sd * (2.0 * ((double)i / (double)k) - 1.0);
  }
  const double eps = 1e-8;
  bool converged;
  double *mus0 = malloc(k * sizeof(double));
  double *sds0 = malloc(k * sizeof(double));
  do {
    print_progress(k, ps, mus, sds);
    memcpy(mus0, mus, k * sizeof(double));
    memcpy(sds0, sds, k * sizeof(double));
    e_step(n, k, xs, zs, ps, mus, sds);
    m_step(n, k, xs, zs, ps, mus, sds);
    converged = true;
    for (i = 0; i < k; ++i) {
      if (fabs(mus[i] - mus0[i]) > eps || fabs(sds[i] - sds0[i]) > eps) {
        converged = false;
        break;
      }
    }
  } while (!converged);
  free(zs);
  free(mus0);
  free(sds0);
}


x86 assembly (clang, -O0):
<fit_gaussian_mixture>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
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    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rax
imul   %rax,%rdi
shl    $0x3,%rdi
call   1090 <malloc@plt>
mov    %rax,-0x38(%rbp)
movaps 0xe5d(%rip),%xmm0
movq   -0x18(%rbp),%xmm1
punpckldq %xmm0,%xmm1
movapd 0xe5c(%rip),%xmm0
subpd  %xmm0,%xmm1
movaps %xmm1,%xmm0
unpckhpd %xmm1,%xmm1
addsd  %xmm0,%xmm1
movsd  0xe15(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    122d <fit_gaussian_mixture+0xad>
movsd  -0x48(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    11fc <fit_gaussian_mixture+0x7c>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    1273 <fit_gaussian_mixture+0xf3>
mov    -0x8(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    123d <fit_gaussian_mixture+0xbd>
movaps 0xda6(%rip),%xmm0
movq   -0x10(%rbp),%xmm1
punpckldq %xmm0,%xmm1
movapd 0xda5(%rip),%xmm0
subpd  %xmm0,%xmm1
movaps %xmm1,%xmm0
unpckhpd %xmm1,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    12fd <fit_gaussian_mixture+0x17d>
mov    -0x8(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x50(%rbp),%xmm0
call   10a0 <sq@plt>
cvtsi2sd %rax,%xmm0
addsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    12b8 <fit_gaussian_mixture+0x138>
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffff,%rax
movq   %rax,%xmm1
movaps 0xd0f(%rip),%xmm0
punpckldq %xmm0,%xmm1
movapd 0xd13(%rip),%xmm0
subpd  %xmm0,%xmm1
movaps %xmm1,%xmm0
unpckhpd %xmm1,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x58(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1373 <fit_gaussian_mixture+0x1f3>
movsd  -0x58(%rbp),%xmm0
mov    -0x30(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    1342 <fit_gaussian_mixture+0x1c2>
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1418 <fit_gaussian_mixture+0x298>
movsd  -0x50(%rbp),%xmm1
movsd  -0x58(%rbp),%xmm0
movsd  0xc7d(%rip),%xmm2
mulsd  %xmm2,%xmm0
movq   -0x40(%rbp),%xmm2
movaps 0xc75(%rip),%xmm5
punpckldq %xmm5,%xmm2
movapd 0xc79(%rip),%xmm4
subpd  %xmm4,%xmm2
movaps %xmm2,%xmm3
unpckhpd %xmm2,%xmm2
addsd  %xmm3,%xmm2
movq   -0x18(%rbp),%xmm3
punpckldq %xmm5,%xmm3
subpd  %xmm4,%xmm3
movaps %xmm3,%xmm4
unpckhpd %xmm3,%xmm3
addsd  %xmm4,%xmm3
divsd  %xmm3,%xmm2
addsd  %xmm2,%xmm2
movsd  0xc22(%rip),%xmm3
addsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    137b <fit_gaussian_mixture+0x1fb>
movsd  0xbe8(%rip),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x18(%rbp),%rdi
shl    $0x3,%rdi
call   1090 <malloc@plt>
mov    %rax,-0x70(%rbp)
mov    -0x18(%rbp),%rdi
shl    $0x3,%rdi
call   1090 <malloc@plt>
mov    %rax,-0x78(%rbp)
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rdx
mov    -0x30(%rbp),%rcx
call   1080 <print_progress@plt>
mov    -0x70(%rbp),%rdi
mov    -0x28(%rbp),%rsi
mov    -0x18(%rbp),%rdx
shl    $0x3,%rdx
call   1070 <memcpy@plt>
mov    -0x78(%rbp),%rdi
mov    -0x30(%rbp),%rsi
mov    -0x18(%rbp),%rdx
shl    $0x3,%rdx
call   1070 <memcpy@plt>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x8(%rbp),%rdx
mov    -0x38(%rbp),%rcx
mov    -0x20(%rbp),%r8
mov    -0x28(%rbp),%r9
mov    -0x30(%rbp),%rax
mov    %rax,(%rsp)
call   1050 <e_step@plt>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x8(%rbp),%rdx
mov    -0x38(%rbp),%rcx
mov    -0x20(%rbp),%r8
mov    -0x28(%rbp),%r9
mov    -0x30(%rbp),%rax
mov    %rax,(%rsp)
call   1030 <m_step@plt>
movl   $0x1,-0x64(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1571 <fit_gaussian_mixture+0x3f1>
mov    -0x28(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x70(%rbp),%rax
mov    -0x40(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
call   1060 <fabs@plt>
movsd  0xaf4(%rip),%xmm1
ucomisd %xmm1,%xmm0
ja     154f <fit_gaussian_mixture+0x3cf>
mov    -0x30(%rbp),%rax
mov    -0x40(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x78(%rbp),%rax
mov    -0x40(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
call   1060 <fabs@plt>
movsd  0xac3(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    155b <fit_gaussian_mixture+0x3db>
movl   $0x0,-0x64(%rbp)
jmp    1571 <fit_gaussian_mixture+0x3f1>
jmp    1560 <fit_gaussian_mixture+0x3e0>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    14df <fit_gaussian_mixture+0x35f>
jmp    1576 <fit_gaussian_mixture+0x3f6>
cmpl   $0x0,-0x64(%rbp)
setne  %al
xor    $0xff,%al
test   $0x1,%al
jne    1447 <fit_gaussian_mixture+0x2c7>
mov    -0x38(%rbp),%rdi
call   1040 <free@plt>
mov    -0x70(%rbp),%rdi
call   1040 <free@plt>
mov    -0x78(%rbp),%rdi
call   1040 <free@plt>
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fit_gaussian_mixture>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x68,%rsp
mov    %r9,%rbx
mov    %r8,0x10(%rsp)
mov    %rcx,%r15
mov    %rdx,%r14
mov    %rsi,%r13
mov    %rdi,%r12
mov    %rsi,%rdi
imul   %rdx,%rdi
shl    $0x3,%rdi
call   1080 <malloc@plt>
movq   %r14,%xmm0
punpckldq 0xe51(%rip),%xmm0
subpd  0xe59(%rip),%xmm0
mov    %rax,0x40(%rsp)
movapd %xmm0,%xmm15
unpckhpd %xmm0,%xmm15
addsd  %xmm0,%xmm15
test   %r14,%r14
je     130f <fit_gaussian_mixture+0x19f>
movsd  0xed4(%rip),%xmm0
divsd  %xmm15,%xmm0
cmp    $0x4,%r14
jae    11ee <fit_gaussian_mixture+0x7e>
xor    %eax,%eax
jmp    1300 <fit_gaussian_mixture+0x190>
mov    %r14,%rax
and    $0xfffffffffffffffc,%rax
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
lea    -0x4(%rax),%rsi
mov    %rsi,%rdx
shr    $0x2,%rdx
add    $0x1,%rdx
mov    %edx,%ecx
and    $0x7,%ecx
cmp    $0x1c,%rsi
jae    121e <fit_gaussian_mixture+0xae>
xor    %esi,%esi
jmp    12c5 <fit_gaussian_mixture+0x155>
and    $0xfffffffffffffff8,%rdx
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movupd %xmm1,(%r15,%rsi,8)
movupd %xmm1,0x10(%r15,%rsi,8)
movupd %xmm1,0x20(%r15,%rsi,8)
movupd %xmm1,0x30(%r15,%rsi,8)
movupd %xmm1,0x40(%r15,%rsi,8)
movupd %xmm1,0x50(%r15,%rsi,8)
movupd %xmm1,0x60(%r15,%rsi,8)
movupd %xmm1,0x70(%r15,%rsi,8)
movupd %xmm1,0x80(%r15,%rsi,8)
movupd %xmm1,0x90(%r15,%rsi,8)
movupd %xmm1,0xa0(%r15,%rsi,8)
movupd %xmm1,0xb0(%r15,%rsi,8)
movupd %xmm1,0xc0(%r15,%rsi,8)
movupd %xmm1,0xd0(%r15,%rsi,8)
movupd %xmm1,0xe0(%r15,%rsi,8)
movupd %xmm1,0xf0(%r15,%rsi,8)
add    $0x20,%rsi
add    $0xfffffffffffffff8,%rdx
jne    1230 <fit_gaussian_mixture+0xc0>
test   %rcx,%rcx
je     12f4 <fit_gaussian_mixture+0x184>
lea    (%r15,%rsi,8),%rdx
add    $0x10,%rdx
shl    $0x5,%rcx
xor    %esi,%esi
nopl   0x0(%rax,%rax,1)
movupd %xmm1,-0x10(%rdx,%rsi,1)
movupd %xmm1,(%rdx,%rsi,1)
add    $0x20,%rsi
cmp    %rsi,%rcx
jne    12e0 <fit_gaussian_mixture+0x170>
cmp    %r14,%rax
je     130f <fit_gaussian_mixture+0x19f>
nopl   0x0(%rax)
movsd  %xmm0,(%r15,%rax,8)
add    $0x1,%rax
cmp    %rax,%r14
jne    1300 <fit_gaussian_mixture+0x190>
movq   %r13,%xmm0
test   %r13,%r13
mov    %r14,0x18(%rsp)
je     1339 <fit_gaussian_mixture+0x1c9>
lea    -0x1(%r13),%rcx
mov    %r13d,%eax
and    $0x7,%eax
cmp    $0x7,%rcx
jae    136f <fit_gaussian_mixture+0x1ff>
xorpd  %xmm5,%xmm5
xor    %ecx,%ecx
jmp    13c0 <fit_gaussian_mixture+0x250>
punpckldq 0xcbf(%rip),%xmm0
subpd  0xcc7(%rip),%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
addsd  %xmm0,%xmm1
xorpd  %xmm6,%xmm6
xorpd  %xmm5,%xmm5
divsd  %xmm1,%xmm5
test   %r14,%r14
jne    1479 <fit_gaussian_mixture+0x309>
jmp    17dc <fit_gaussian_mixture+0x66c>
mov    %r13,%rdx
and    $0xfffffffffffffff8,%rdx
xorpd  %xmm5,%xmm5
xor    %ecx,%ecx
nopl   0x0(%rax)
addsd  (%r12,%rcx,8),%xmm5
addsd  0x8(%r12,%rcx,8),%xmm5
addsd  0x10(%r12,%rcx,8),%xmm5
addsd  0x18(%r12,%rcx,8),%xmm5
addsd  0x20(%r12,%rcx,8),%xmm5
addsd  0x28(%r12,%rcx,8),%xmm5
addsd  0x30(%r12,%rcx,8),%xmm5
addsd  0x38(%r12,%rcx,8),%xmm5
add    $0x8,%rcx
cmp    %rcx,%rdx
jne    1380 <fit_gaussian_mixture+0x210>
test   %rax,%rax
je     13de <fit_gaussian_mixture+0x26e>
lea    (%r12,%rcx,8),%rcx
xor    %edx,%edx
nopl   0x0(%rax,%rax,1)
addsd  (%rcx,%rdx,8),%xmm5
add    $0x1,%rdx
cmp    %rdx,%rax
jne    13d0 <fit_gaussian_mixture+0x260>
punpckldq 0xc1a(%rip),%xmm0
subpd  0xc22(%rip),%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
addsd  %xmm0,%xmm1
divsd  %xmm1,%xmm5
test   %r13,%r13
je     146c <fit_gaussian_mixture+0x2fc>
movapd %xmm15,0x50(%rsp)
xorpd  %xmm6,%xmm6
xor    %ebp,%ebp
movapd %xmm5,0x20(%rsp)
cs nopw 0x0(%rax,%rax,1)
movapd %xmm6,0x30(%rsp)
movsd  (%r12,%rbp,8),%xmm0
subsd  %xmm5,%xmm0
call   1090 <sq@plt>
movapd 0x30(%rsp),%xmm6
movapd 0x20(%rsp),%xmm5
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  %xmm0,%xmm6
add    $0x1,%rbp
cmp    %rbp,%r13
jne    1420 <fit_gaussian_mixture+0x2b0>
mov    0x18(%rsp),%r14
movapd 0x50(%rsp),%xmm15
test   %r14,%r14
jne    1479 <fit_gaussian_mixture+0x309>
jmp    17dc <fit_gaussian_mixture+0x66c>
xorpd  %xmm6,%xmm6
test   %r14,%r14
je     17dc <fit_gaussian_mixture+0x66c>
lea    -0x1(%r13),%rax
movq   %rax,%xmm0
punpckldq 0xb76(%rip),%xmm0
subpd  0xb7e(%rip),%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
addsd  %xmm0,%xmm1
divsd  %xmm1,%xmm6
cmp    $0x4,%r14
jae    14af <fit_gaussian_mixture+0x33f>
xor    %eax,%eax
jmp    15b0 <fit_gaussian_mixture+0x440>
mov    %r14,%rax
and    $0xfffffffffffffffc,%rax
movapd %xmm6,%xmm0
unpcklpd %xmm6,%xmm0
lea    -0x4(%rax),%rsi
mov    %rsi,%rdx
shr    $0x2,%rdx
add    $0x1,%rdx
mov    %edx,%ecx
and    $0x7,%ecx
cmp    $0x1c,%rsi
jae    14df <fit_gaussian_mixture+0x36f>
xor    %esi,%esi
jmp    1575 <fit_gaussian_mixture+0x405>
and    $0xfffffffffffffff8,%rdx
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nop
movupd %xmm0,(%rbx,%rsi,8)
movupd %xmm0,0x10(%rbx,%rsi,8)
movupd %xmm0,0x20(%rbx,%rsi,8)
movupd %xmm0,0x30(%rbx,%rsi,8)
movupd %xmm0,0x40(%rbx,%rsi,8)
movupd %xmm0,0x50(%rbx,%rsi,8)
movupd %xmm0,0x60(%rbx,%rsi,8)
movupd %xmm0,0x70(%rbx,%rsi,8)
movupd %xmm0,0x80(%rbx,%rsi,8)
movupd %xmm0,0x90(%rbx,%rsi,8)
movupd %xmm0,0xa0(%rbx,%rsi,8)
movupd %xmm0,0xb0(%rbx,%rsi,8)
movupd %xmm0,0xc0(%rbx,%rsi,8)
movupd %xmm0,0xd0(%rbx,%rsi,8)
movupd %xmm0,0xe0(%rbx,%rsi,8)
movupd %xmm0,0xf0(%rbx,%rsi,8)
add    $0x20,%rsi
add    $0xfffffffffffffff8,%rdx
jne    14f0 <fit_gaussian_mixture+0x380>
test   %rcx,%rcx
je     15a4 <fit_gaussian_mixture+0x434>
lea    (%rbx,%rsi,8),%rdx
add    $0x10,%rdx
shl    $0x5,%rcx
xor    %esi,%esi
nopl   0x0(%rax,%rax,1)
movupd %xmm0,-0x10(%rdx,%rsi,1)
movupd %xmm0,(%rdx,%rsi,1)
add    $0x20,%rsi
cmp    %rsi,%rcx
jne    1590 <fit_gaussian_mixture+0x420>
cmp    %r14,%rax
je     15be <fit_gaussian_mixture+0x44e>
nopl   0x0(%rax)
movsd  %xmm6,(%rbx,%rax,8)
add    $0x1,%rax
cmp    %rax,%r14
jne    15b0 <fit_gaussian_mixture+0x440>
test   %r14,%r14
je     17dc <fit_gaussian_mixture+0x66c>
mulsd  0xae9(%rip),%xmm6
cmp    $0x1,%r14
jne    15dc <fit_gaussian_mixture+0x46c>
xor    %eax,%eax
jmp    177d <fit_gaussian_mixture+0x60d>
mov    %r14,%rax
and    $0xfffffffffffffffe,%rax
movapd %xmm15,%xmm2
unpcklpd %xmm15,%xmm2
movapd %xmm6,%xmm0
unpcklpd %xmm6,%xmm0
movapd %xmm5,%xmm1
unpcklpd %xmm5,%xmm1
lea    -0x2(%rax),%rdx
mov    %rdx,%rcx
shr    %rcx
add    $0x1,%rcx
test   %rdx,%rdx
je     1929 <fit_gaussian_mixture+0x7b9>
movapd %xmm6,0x30(%rsp)
movapd %xmm5,0x20(%rsp)
mov    %rcx,%rsi
and    $0xfffffffffffffffe,%rsi
movdqa 0x9f1(%rip),%xmm7
xor    %edx,%edx
movdqa 0x9f6(%rip),%xmm8
movdqa 0x9fd(%rip),%xmm11
movdqa 0xa04(%rip),%xmm12
movapd 0xa0b(%rip),%xmm13
movapd 0xa12(%rip),%xmm14
movdqa 0xa19(%rip),%xmm9
movdqa 0xa20(%rip),%xmm10
mov    0x10(%rsp),%rbp
cs nopw 0x0(%rax,%rax,1)
nop
movdqa %xmm7,%xmm5
pand   %xmm8,%xmm5
por    %xmm11,%xmm5
movdqa %xmm7,%xmm3
psrlq  $0x20,%xmm3
por    %xmm12,%xmm3
subpd  %xmm13,%xmm3
movdqa %xmm7,%xmm6
paddq  %xmm9,%xmm6
movdqa %xmm6,%xmm4
pand   %xmm8,%xmm4
por    %xmm11,%xmm4
psrlq  $0x20,%xmm6
por    %xmm12,%xmm6
subpd  %xmm13,%xmm6
addpd  %xmm5,%xmm3
addpd  %xmm4,%xmm6
divpd  %xmm2,%xmm3
addpd  %xmm3,%xmm3
addpd  %xmm14,%xmm3
mulpd  %xmm0,%xmm3
divpd  %xmm2,%xmm6
addpd  %xmm6,%xmm6
addpd  %xmm1,%xmm3
addpd  %xmm14,%xmm6
mulpd  %xmm0,%xmm6
addpd  %xmm1,%xmm6
movupd %xmm3,0x0(%rbp,%rdx,8)
movupd %xmm6,0x10(%rbp,%rdx,8)
add    $0x4,%rdx
paddq  %xmm10,%xmm7
add    $0xfffffffffffffffe,%rsi
jne    1680 <fit_gaussian_mixture+0x510>
movdqa 0x910(%rip),%xmm3
pand   %xmm7,%xmm3
por    0x914(%rip),%xmm3
psrlq  $0x20,%xmm7
por    0x917(%rip),%xmm7
subpd  0x91f(%rip),%xmm7
addpd  %xmm3,%xmm7
movapd 0x20(%rsp),%xmm5
movapd 0x30(%rsp),%xmm6
test   $0x1,%cl
je     1778 <fit_gaussian_mixture+0x608>
divpd  %xmm2,%xmm7
addpd  %xmm7,%xmm7
addpd  0x90a(%rip),%xmm7
mulpd  %xmm7,%xmm0
addpd  %xmm1,%xmm0
mov    0x10(%rsp),%rcx
movupd %xmm0,(%rcx,%rdx,8)
cmp    %r14,%rax
je     17dc <fit_gaussian_mixture+0x66c>
movdqa 0x87b(%rip),%xmm0
movapd 0x883(%rip),%xmm1
movsd  0x92b(%rip),%xmm2
mov    0x10(%rsp),%rcx
nopw   0x0(%rax,%rax,1)
movq   %rax,%xmm3
punpckldq %xmm0,%xmm3
subpd  %xmm1,%xmm3
movapd %xmm3,%xmm4
unpckhpd %xmm3,%xmm4
addsd  %xmm3,%xmm4
divsd  %xmm15,%xmm4
addsd  %xmm4,%xmm4
addsd  %xmm2,%xmm4
mulsd  %xmm6,%xmm4
addsd  %xmm5,%xmm4
movsd  %xmm4,(%rcx,%rax,8)
add    $0x1,%rax
cmp    %rax,%r14
jne    17a0 <fit_gaussian_mixture+0x630>
mov    %r13,0x30(%rsp)
lea    0x0(,%r14,8),%rbp
mov    %rbp,%rdi
call   1080 <malloc@plt>
mov    %rax,%r13
mov    %rbp,0x20(%rsp)
mov    %rbp,%rdi
call   1080 <malloc@plt>
mov    %rax,%r14
mov    %rbx,0x48(%rsp)
mov    0x10(%rsp),%rbp
mov    0x18(%rsp),%rdi
mov    %r15,%rsi
mov    %rbp,%rdx
mov    %rbx,%rcx
call   1070 <print_progress@plt>
mov    %r13,%rdi
mov    %rbp,%rsi
mov    0x20(%rsp),%rbp
mov    %rbp,%rdx
call   1060 <memcpy@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    %rbp,%rdx
call   1060 <memcpy@plt>
mov    %rbx,(%rsp)
mov    0x30(%rsp),%rbp
mov    %rbp,%rdi
mov    0x18(%rsp),%rsi
mov    %r12,%rdx
mov    %r15,%rbx
mov    %r12,%r15
mov    0x40(%rsp),%r12
mov    %r12,%rcx
mov    %rbx,%r8
mov    0x10(%rsp),%r9
call   1050 <e_step@plt>
mov    0x48(%rsp),%rax
mov    %rax,(%rsp)
mov    %rbp,%rdi
mov    0x18(%rsp),%rsi
mov    %r15,%rdx
mov    %r12,%rcx
mov    %r15,%r12
mov    %rbx,%r15
mov    0x48(%rsp),%rbx
mov    %r15,%r8
mov    0x10(%rsp),%r9
call   1030 <m_step@plt>
movsd  0x820(%rip),%xmm2
movapd 0x7f0(%rip),%xmm1
mov    0x18(%rsp),%rcx
test   %rcx,%rcx
je     1901 <fit_gaussian_mixture+0x791>
xor    %eax,%eax
nopl   0x0(%rax)
mov    0x10(%rsp),%rdx
movsd  (%rdx,%rax,8),%xmm0
subsd  0x0(%r13,%rax,8),%xmm0
andpd  %xmm1,%xmm0
ucomisd %xmm2,%xmm0
ja     1809 <fit_gaussian_mixture+0x699>
movsd  (%rbx,%rax,8),%xmm0
subsd  (%r14,%rax,8),%xmm0
andpd  %xmm1,%xmm0
add    $0x1,%rax
ucomisd %xmm2,%xmm0
ja     1809 <fit_gaussian_mixture+0x699>
cmp    %rax,%rcx
jne    18c0 <fit_gaussian_mixture+0x750>
mov    0x40(%rsp),%rdi
call   1040 <free@plt>
mov    %r13,%rdi
call   1040 <free@plt>
mov    %r14,%rdi
add    $0x68,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1040 <free@plt>
xorpd  %xmm7,%xmm7
movhpd 0x77b(%rip),%xmm7
xor    %edx,%edx
test   $0x1,%cl
jne    1756 <fit_gaussian_mixture+0x5e6>
jmp    1778 <fit_gaussian_mixture+0x608>

LLVM IR (-O0):
define void @fit_gaussian_mixture(double* %0, i64 %1, i64 %2, double* %3, double* %4, double* %5) {
%7 = alloca double*
%8 = alloca i64
%9 = alloca i64
%10 = alloca double*
%11 = alloca double*
%12 = alloca double*
%13 = alloca double*
%14 = alloca i64
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca i32
%20 = alloca double*
%21 = alloca double*
store double* %0, double** %7
store i64 %1, i64* %8
store i64 %2, i64* %9
store double* %3, double** %10
store double* %4, double** %11
store double* %5, double** %12
%22 = load i64, i64* %9
%23 = load i64, i64* %8
%24 = mul i64 %22, %23
%25 = mul i64 %24, 8
%26 = call double* @malloc(i64 %25)
store double* %26, double** %13
%27 = load i64, i64* %9
%28 = uitofp i64 %27 to double
%29 = fdiv double 1.000000e+00, %28
store double %29, double* %15
store i64 0, i64* %14
br label %30
30: ; preds = %39, %6
%31 = load i64, i64* %14
%32 = load i64, i64* %9
%33 = icmp ult i64 %31, %32
br i1 %33, label %34, label %42
34: ; preds = %30
%35 = load double, double* %15
%36 = load double*, double** %10
%37 = load i64, i64* %14
%38 = getelementptr inbounds double, double* %36, i64 %37
store double %35, double* %38
br label %39
39: ; preds = %34
%40 = load i64, i64* %14
%41 = add i64 %40, 1
store i64 %41, i64* %14
br label %30
42: ; preds = %30
store double 0.000000e+00, double* %16
store i64 0, i64* %14
br label %43
43: ; preds = %54, %42
%44 = load i64, i64* %14
%45 = load i64, i64* %8
%46 = icmp ult i64 %44, %45
br i1 %46, label %47, label %57
47: ; preds = %43
%48 = load double*, double** %7
%49 = load i64, i64* %14
%50 = getelementptr inbounds double, double* %48, i64 %49
%51 = load double, double* %50
%52 = load double, double* %16
%53 = fadd double %52, %51
store double %53, double* %16
br label %54
54: ; preds = %47
%55 = load i64, i64* %14
%56 = add i64 %55, 1
store i64 %56, i64* %14
br label %43
57: ; preds = %43
%58 = load i64, i64* %8
%59 = uitofp i64 %58 to double
%60 = load double, double* %16
%61 = fdiv double %60, %59
store double %61, double* %16
store double 0.000000e+00, double* %17
store i64 0, i64* %14
br label %62
62: ; preds = %77, %57
%63 = load i64, i64* %14
%64 = load i64, i64* %8
%65 = icmp ult i64 %63, %64
br i1 %65, label %66, label %80
66: ; preds = %62
%67 = load double*, double** %7
%68 = load i64, i64* %14
%69 = getelementptr inbounds double, double* %67, i64 %68
%70 = load double, double* %69
%71 = load double, double* %16
%72 = fsub double %70, %71
%73 = call i64 @sq(double %72)
%74 = sitofp i64 %73 to double
%75 = load double, double* %17
%76 = fadd double %75, %74
store double %76, double* %17
br label %77
77: ; preds = %66
%78 = load i64, i64* %14
%79 = add i64 %78, 1
store i64 %79, i64* %14
br label %62
80: ; preds = %62
%81 = load i64, i64* %8
%82 = sub i64 %81, 1
%83 = uitofp i64 %82 to double
%84 = load double, double* %17
%85 = fdiv double %84, %83
store double %85, double* %17
store i64 0, i64* %14
br label %86
86: ; preds = %95, %80
%87 = load i64, i64* %14
%88 = load i64, i64* %9
%89 = icmp ult i64 %87, %88
br i1 %89, label %90, label %98
90: ; preds = %86
%91 = load double, double* %17
%92 = load double*, double** %12
%93 = load i64, i64* %14
%94 = getelementptr inbounds double, double* %92, i64 %93
store double %91, double* %94
br label %95
95: ; preds = %90
%96 = load i64, i64* %14
%97 = add i64 %96, 1
store i64 %97, i64* %14
br label %86
98: ; preds = %86
store i64 0, i64* %14
br label %99
99: ; preds = %117, %98
%100 = load i64, i64* %14
%101 = load i64, i64* %9
%102 = icmp ult i64 %100, %101
br i1 %102, label %103, label %120
103: ; preds = %99
%104 = load double, double* %16
%105 = load double, double* %17
%106 = fmul double 3.000000e+00, %105
%107 = load i64, i64* %14
%108 = uitofp i64 %107 to double
%109 = load i64, i64* %9
%110 = uitofp i64 %109 to double
%111 = fdiv double %108, %110
%112 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %111, double -1.000000e+00)
%113 = call double @llvm.fmuladd.f64(double %106, double %112, double %104)
%114 = load double*, double** %11
%115 = load i64, i64* %14
%116 = getelementptr inbounds double, double* %114, i64 %115
store double %113, double* %116
br label %117
117: ; preds = %103
%118 = load i64, i64* %14
%119 = add i64 %118, 1
store i64 %119, i64* %14
br label %99
120: ; preds = %99
store double 1.000000e-08, double* %18
%121 = load i64, i64* %9
%122 = mul i64 %121, 8
%123 = call double* @malloc(i64 %122)
store double* %123, double** %20
%124 = load i64, i64* %9
%125 = mul i64 %124, 8
%126 = call double* @malloc(i64 %125)
store double* %126, double** %21
br label %127
127: ; preds = %193, %120
%128 = load i64, i64* %9
%129 = load double*, double** %10
%130 = load double*, double** %11
%131 = load double*, double** %12
%132 = call i32 @print_progress(i64 %128, double* %129, double* %130, double* %131)
%133 = load double*, double** %20
%134 = load double*, double** %11
%135 = load i64, i64* %9
%136 = mul i64 %135, 8
%137 = call i32 @memcpy(double* %133, double* %134, i64 %136)
%138 = load double*, double** %21
%139 = load double*, double** %12
%140 = load i64, i64* %9
%141 = mul i64 %140, 8
%142 = call i32 @memcpy(double* %138, double* %139, i64 %141)
%143 = load i64, i64* %8
%144 = load i64, i64* %9
%145 = load double*, double** %7
%146 = load double*, double** %13
%147 = load double*, double** %10
%148 = load double*, double** %11
%149 = load double*, double** %12
%150 = call i32 @e_step(i64 %143, i64 %144, double* %145, double* %146, double* %147, double* %148, double* %149)
%151 = load i64, i64* %8
%152 = load i64, i64* %9
%153 = load double*, double** %7
%154 = load double*, double** %13
%155 = load double*, double** %10
%156 = load double*, double** %11
%157 = load double*, double** %12
%158 = call i32 @m_step(i64 %151, i64 %152, double* %153, double* %154, double* %155, double* %156, double* %157)
store i32 1, i32* %19
store i64 0, i64* %14
br label %159
159: ; preds = %189, %127
%160 = load i64, i64* %14
%161 = load i64, i64* %9
%162 = icmp ult i64 %160, %161
br i1 %162, label %163, label %192
163: ; preds = %159
%164 = load double*, double** %11
%165 = load i64, i64* %14
%166 = getelementptr inbounds double, double* %164, i64 %165
%167 = load double, double* %166
%168 = load double*, double** %20
%169 = load i64, i64* %14
%170 = getelementptr inbounds double, double* %168, i64 %169
%171 = load double, double* %170
%172 = fsub double %167, %171
%173 = call double @fabs(double %172)
%174 = fcmp ogt double %173, 1.000000e-08
br i1 %174, label %187, label %175
175: ; preds = %163
%176 = load double*, double** %12
%177 = load i64, i64* %14
%178 = getelementptr inbounds double, double* %176, i64 %177
%179 = load double, double* %178
%180 = load double*, double** %21
%181 = load i64, i64* %14
%182 = getelementptr inbounds double, double* %180, i64 %181
%183 = load double, double* %182
%184 = fsub double %179, %183
%185 = call double @fabs(double %184)
%186 = fcmp ogt double %185, 1.000000e-08
br i1 %186, label %187, label %188
187: ; preds = %175, %163
store i32 0, i32* %19
br label %192
188: ; preds = %175
br label %189
189: ; preds = %188
%190 = load i64, i64* %14
%191 = add i64 %190, 1
store i64 %191, i64* %14
br label %159
192: ; preds = %187, %159
br label %193
193: ; preds = %192
%194 = load i32, i32* %19
%195 = icmp ne i32 %194, 0
%196 = xor i1 %195, true
br i1 %196, label %127, label %197
197: ; preds = %193
%198 = load double*, double** %13
%199 = call i32 @free(double* %198)
%200 = load double*, double** %20
%201 = call i32 @free(double* %200)
%202 = load double*, double** %21
%203 = call i32 @free(double* %202)
ret void
}

LLVM IR (-O2):
define void @fit_gaussian_mixture(double* %0, i64 %1, i64 %2, double* %3, double* %4, double* %5) {
%7 = shl i64 %1, 3
%8 = mul i64 %7, %2
%9 = tail call double* @malloc(i64 %8)
%10 = uitofp i64 %2 to double
%11 = fdiv double 1.000000e+00, %10
%12 = icmp eq i64 %2, 0
br i1 %12, label %90, label %13
13: ; preds = %6
%14 = icmp ult i64 %2, 4
br i1 %14, label %88, label %15
15: ; preds = %13
%16 = and i64 %2, -4
%17 = insertelement <2 x double> poison, double %11, i64 0
%18 = shufflevector <2 x double> %17, <2 x double> poison, <2 x i32> zeroinitializer
%19 = insertelement <2 x double> poison, double %11, i64 0
%20 = shufflevector <2 x double> %19, <2 x double> poison, <2 x i32> zeroinitializer
%21 = add i64 %16, -4
%22 = lshr exact i64 %21, 2
%23 = add nuw nsw i64 %22, 1
%24 = and i64 %23, 7
%25 = icmp ult i64 %21, 28
br i1 %25, label %73, label %26
26: ; preds = %15
%27 = and i64 %23, 9223372036854775800
br label %28
28: ; preds = %28, %26
%29 = phi i64 [ 0, %26 ], [ %70, %28 ]
%30 = phi i64 [ 0, %26 ], [ %71, %28 ]
%31 = getelementptr inbounds double, double* %3, i64 %29
%32 = bitcast double* %31 to <2 x double>*
store <2 x double> %18, <2 x double>* %32
%33 = getelementptr inbounds double, double* %31, i64 2
%34 = bitcast double* %33 to <2 x double>*
store <2 x double> %20, <2 x double>* %34
%35 = or i64 %29, 4
%36 = getelementptr inbounds double, double* %3, i64 %35
%37 = bitcast double* %36 to <2 x double>*
store <2 x double> %18, <2 x double>* %37
%38 = getelementptr inbounds double, double* %36, i64 2
%39 = bitcast double* %38 to <2 x double>*
store <2 x double> %20, <2 x double>* %39
%40 = or i64 %29, 8
%41 = getelementptr inbounds double, double* %3, i64 %40
%42 = bitcast double* %41 to <2 x double>*
store <2 x double> %18, <2 x double>* %42
%43 = getelementptr inbounds double, double* %41, i64 2
%44 = bitcast double* %43 to <2 x double>*
store <2 x double> %20, <2 x double>* %44
%45 = or i64 %29, 12
%46 = getelementptr inbounds double, double* %3, i64 %45
%47 = bitcast double* %46 to <2 x double>*
store <2 x double> %18, <2 x double>* %47
%48 = getelementptr inbounds double, double* %46, i64 2
%49 = bitcast double* %48 to <2 x double>*
store <2 x double> %20, <2 x double>* %49
%50 = or i64 %29, 16
%51 = getelementptr inbounds double, double* %3, i64 %50
%52 = bitcast double* %51 to <2 x double>*
store <2 x double> %18, <2 x double>* %52
%53 = getelementptr inbounds double, double* %51, i64 2
%54 = bitcast double* %53 to <2 x double>*
store <2 x double> %20, <2 x double>* %54
%55 = or i64 %29, 20
%56 = getelementptr inbounds double, double* %3, i64 %55
%57 = bitcast double* %56 to <2 x double>*
store <2 x double> %18, <2 x double>* %57
%58 = getelementptr inbounds double, double* %56, i64 2
%59 = bitcast double* %58 to <2 x double>*
store <2 x double> %20, <2 x double>* %59
%60 = or i64 %29, 24
%61 = getelementptr inbounds double, double* %3, i64 %60
%62 = bitcast double* %61 to <2 x double>*
store <2 x double> %18, <2 x double>* %62
%63 = getelementptr inbounds double, double* %61, i64 2
%64 = bitcast double* %63 to <2 x double>*
store <2 x double> %20, <2 x double>* %64
%65 = or i64 %29, 28
%66 = getelementptr inbounds double, double* %3, i64 %65
%67 = bitcast double* %66 to <2 x double>*
store <2 x double> %18, <2 x double>* %67
%68 = getelementptr inbounds double, double* %66, i64 2
%69 = bitcast double* %68 to <2 x double>*
store <2 x double> %20, <2 x double>* %69
%70 = add nuw i64 %29, 32
%71 = add i64 %30, 8
%72 = icmp eq i64 %71, %27
br i1 %72, label %73, label %28
73: ; preds = %28, %15
%74 = phi i64 [ 0, %15 ], [ %70, %28 ]
%75 = icmp eq i64 %24, 0
br i1 %75, label %86, label %76
76: ; preds = %73, %76
%77 = phi i64 [ %83, %76 ], [ %74, %73 ]
%78 = phi i64 [ %84, %76 ], [ 0, %73 ]
%79 = getelementptr inbounds double, double* %3, i64 %77
%80 = bitcast double* %79 to <2 x double>*
store <2 x double> %18, <2 x double>* %80
%81 = getelementptr inbounds double, double* %79, i64 2
%82 = bitcast double* %81 to <2 x double>*
store <2 x double> %20, <2 x double>* %82
%83 = add nuw i64 %77, 4
%84 = add i64 %78, 1
%85 = icmp eq i64 %84, %24
br i1 %85, label %86, label %76
86: ; preds = %76, %73
%87 = icmp eq i64 %16, %2
br i1 %87, label %90, label %88
88: ; preds = %13, %86
%89 = phi i64 [ 0, %13 ], [ %16, %86 ]
br label %101
90: ; preds = %101, %86, %6
%91 = icmp eq i64 %1, 0
br i1 %91, label %98, label %92
92: ; preds = %90
%93 = add i64 %1, -1
%94 = and i64 %1, 7
%95 = icmp ult i64 %93, 7
br i1 %95, label %144, label %96
96: ; preds = %92
%97 = and i64 %1, -8
br label %106
98: ; preds = %90
%99 = uitofp i64 %1 to double
%100 = fdiv double 0.000000e+00, %99
br label %174
101: ; preds = %88, %101
%102 = phi i64 [ %104, %101 ], [ %89, %88 ]
%103 = getelementptr inbounds double, double* %3, i64 %102
store double %11, double* %103
%104 = add nuw i64 %102, 1
%105 = icmp eq i64 %104, %2
br i1 %105, label %90, label %101
106: ; preds = %106, %96
%107 = phi i64 [ 0, %96 ], [ %141, %106 ]
%108 = phi double [ 0.000000e+00, %96 ], [ %140, %106 ]
%109 = phi i64 [ 0, %96 ], [ %142, %106 ]
%110 = getelementptr inbounds double, double* %0, i64 %107
%111 = load double, double* %110
%112 = fadd double %108, %111
%113 = or i64 %107, 1
%114 = getelementptr inbounds double, double* %0, i64 %113
%115 = load double, double* %114
%116 = fadd double %112, %115
%117 = or i64 %107, 2
%118 = getelementptr inbounds double, double* %0, i64 %117
%119 = load double, double* %118
%120 = fadd double %116, %119
%121 = or i64 %107, 3
%122 = getelementptr inbounds double, double* %0, i64 %121
%123 = load double, double* %122
%124 = fadd double %120, %123
%125 = or i64 %107, 4
%126 = getelementptr inbounds double, double* %0, i64 %125
%127 = load double, double* %126
%128 = fadd double %124, %127
%129 = or i64 %107, 5
%130 = getelementptr inbounds double, double* %0, i64 %129
%131 = load double, double* %130
%132 = fadd double %128, %131
%133 = or i64 %107, 6
%134 = getelementptr inbounds double, double* %0, i64 %133
%135 = load double, double* %134
%136 = fadd double %132, %135
%137 = or i64 %107, 7
%138 = getelementptr inbounds double, double* %0, i64 %137
%139 = load double, double* %138
%140 = fadd double %136, %139
%141 = add nuw i64 %107, 8
%142 = add i64 %109, 8
%143 = icmp eq i64 %142, %97
br i1 %143, label %144, label %106
144: ; preds = %106, %92
%145 = phi double [ undef, %92 ], [ %140, %106 ]
%146 = phi i64 [ 0, %92 ], [ %141, %106 ]
%147 = phi double [ 0.000000e+00, %92 ], [ %140, %106 ]
%148 = icmp eq i64 %94, 0
br i1 %148, label %159, label %149
149: ; preds = %144, %149
%150 = phi i64 [ %156, %149 ], [ %146, %144 ]
%151 = phi double [ %155, %149 ], [ %147, %144 ]
%152 = phi i64 [ %157, %149 ], [ 0, %144 ]
%153 = getelementptr inbounds double, double* %0, i64 %150
%154 = load double, double* %153
%155 = fadd double %151, %154
%156 = add nuw i64 %150, 1
%157 = add i64 %152, 1
%158 = icmp eq i64 %157, %94
br i1 %158, label %159, label %149
159: ; preds = %149, %144
%160 = phi double [ %145, %144 ], [ %155, %149 ]
%161 = uitofp i64 %1 to double
%162 = fdiv double %160, %161
br i1 %91, label %174, label %163
163: ; preds = %159, %163
%164 = phi i64 [ %172, %163 ], [ 0, %159 ]
%165 = phi double [ %171, %163 ], [ 0.000000e+00, %159 ]
%166 = getelementptr inbounds double, double* %0, i64 %164
%167 = load double, double* %166
%168 = fsub double %167, %162
%169 = tail call i64 @sq(double %168)
%170 = sitofp i64 %169 to double
%171 = fadd double %165, %170
%172 = add nuw i64 %164, 1
%173 = icmp eq i64 %172, %1
br i1 %173, label %174, label %163
174: ; preds = %163, %98, %159
%175 = phi double [ %162, %159 ], [ %100, %98 ], [ %162, %163 ]
%176 = phi double [ 0.000000e+00, %159 ], [ 0.000000e+00, %98 ], [ %171, %163 ]
%177 = add i64 %1, -1
%178 = uitofp i64 %177 to double
%179 = fdiv double %176, %178
br i1 %12, label %328, label %180
180: ; preds = %174
%181 = icmp ult i64 %2, 4
br i1 %181, label %255, label %182
182: ; preds = %180
%183 = and i64 %2, -4
%184 = insertelement <2 x double> poison, double %179, i64 0
%185 = shufflevector <2 x double> %184, <2 x double> poison, <2 x i32> zeroinitializer
%186 = insertelement <2 x double> poison, double %179, i64 0
%187 = shufflevector <2 x double> %186, <2 x double> poison, <2 x i32> zeroinitializer
%188 = add i64 %183, -4
%189 = lshr exact i64 %188, 2
%190 = add nuw nsw i64 %189, 1
%191 = and i64 %190, 7
%192 = icmp ult i64 %188, 28
br i1 %192, label %240, label %193
193: ; preds = %182
%194 = and i64 %190, 9223372036854775800
br label %195
195: ; preds = %195, %193
%196 = phi i64 [ 0, %193 ], [ %237, %195 ]
%197 = phi i64 [ 0, %193 ], [ %238, %195 ]
%198 = getelementptr inbounds double, double* %5, i64 %196
%199 = bitcast double* %198 to <2 x double>*
store <2 x double> %185, <2 x double>* %199
%200 = getelementptr inbounds double, double* %198, i64 2
%201 = bitcast double* %200 to <2 x double>*
store <2 x double> %187, <2 x double>* %201
%202 = or i64 %196, 4
%203 = getelementptr inbounds double, double* %5, i64 %202
%204 = bitcast double* %203 to <2 x double>*
store <2 x double> %185, <2 x double>* %204
%205 = getelementptr inbounds double, double* %203, i64 2
%206 = bitcast double* %205 to <2 x double>*
store <2 x double> %187, <2 x double>* %206
%207 = or i64 %196, 8
%208 = getelementptr inbounds double, double* %5, i64 %207
%209 = bitcast double* %208 to <2 x double>*
store <2 x double> %185, <2 x double>* %209
%210 = getelementptr inbounds double, double* %208, i64 2
%211 = bitcast double* %210 to <2 x double>*
store <2 x double> %187, <2 x double>* %211
%212 = or i64 %196, 12
%213 = getelementptr inbounds double, double* %5, i64 %212
%214 = bitcast double* %213 to <2 x double>*
store <2 x double> %185, <2 x double>* %214
%215 = getelementptr inbounds double, double* %213, i64 2
%216 = bitcast double* %215 to <2 x double>*
store <2 x double> %187, <2 x double>* %216
%217 = or i64 %196, 16
%218 = getelementptr inbounds double, double* %5, i64 %217
%219 = bitcast double* %218 to <2 x double>*
store <2 x double> %185, <2 x double>* %219
%220 = getelementptr inbounds double, double* %218, i64 2
%221 = bitcast double* %220 to <2 x double>*
store <2 x double> %187, <2 x double>* %221
%222 = or i64 %196, 20
%223 = getelementptr inbounds double, double* %5, i64 %222
%224 = bitcast double* %223 to <2 x double>*
store <2 x double> %185, <2 x double>* %224
%225 = getelementptr inbounds double, double* %223, i64 2
%226 = bitcast double* %225 to <2 x double>*
store <2 x double> %187, <2 x double>* %226
%227 = or i64 %196, 24
%228 = getelementptr inbounds double, double* %5, i64 %227
%229 = bitcast double* %228 to <2 x double>*
store <2 x double> %185, <2 x double>* %229
%230 = getelementptr inbounds double, double* %228, i64 2
%231 = bitcast double* %230 to <2 x double>*
store <2 x double> %187, <2 x double>* %231
%232 = or i64 %196, 28
%233 = getelementptr inbounds double, double* %5, i64 %232
%234 = bitcast double* %233 to <2 x double>*
store <2 x double> %185, <2 x double>* %234
%235 = getelementptr inbounds double, double* %233, i64 2
%236 = bitcast double* %235 to <2 x double>*
store <2 x double> %187, <2 x double>* %236
%237 = add nuw i64 %196, 32
%238 = add i64 %197, 8
%239 = icmp eq i64 %238, %194
br i1 %239, label %240, label %195
240: ; preds = %195, %182
%241 = phi i64 [ 0, %182 ], [ %237, %195 ]
%242 = icmp eq i64 %191, 0
br i1 %242, label %253, label %243
243: ; preds = %240, %243
%244 = phi i64 [ %250, %243 ], [ %241, %240 ]
%245 = phi i64 [ %251, %243 ], [ 0, %240 ]
%246 = getelementptr inbounds double, double* %5, i64 %244
%247 = bitcast double* %246 to <2 x double>*
store <2 x double> %185, <2 x double>* %247
%248 = getelementptr inbounds double, double* %246, i64 2
%249 = bitcast double* %248 to <2 x double>*
store <2 x double> %187, <2 x double>* %249
%250 = add nuw i64 %244, 4
%251 = add i64 %245, 1
%252 = icmp eq i64 %251, %191
br i1 %252, label %253, label %243
253: ; preds = %243, %240
%254 = icmp eq i64 %183, %2
br i1 %254, label %257, label %255
255: ; preds = %180, %253
%256 = phi i64 [ 0, %180 ], [ %183, %253 ]
br label %314
257: ; preds = %314, %253
br i1 %12, label %328, label %258
258: ; preds = %257
%259 = fmul double %179, 3.000000e+00
%260 = icmp eq i64 %2, 1
br i1 %260, label %312, label %261
261: ; preds = %258
%262 = and i64 %2, -2
%263 = insertelement <2 x double> poison, double %10, i64 0
%264 = shufflevector <2 x double> %263, <2 x double> poison, <2 x i32> zeroinitializer
%265 = insertelement <2 x double> poison, double %259, i64 0
%266 = shufflevector <2 x double> %265, <2 x double> poison, <2 x i32> zeroinitializer
%267 = insertelement <2 x double> poison, double %175, i64 0
%268 = shufflevector <2 x double> %267, <2 x double> poison, <2 x i32> zeroinitializer
%269 = add i64 %262, -2
%270 = lshr exact i64 %269, 1
%271 = add nuw i64 %270, 1
%272 = and i64 %271, 1
%273 = icmp eq i64 %269, 0
br i1 %273, label %300, label %274
274: ; preds = %261
%275 = and i64 %271, -2
br label %276
276: ; preds = %276, %274
%277 = phi i64 [ 0, %274 ], [ %294, %276 ]
%278 = phi <2 x i64> [ <i64 0, i64 1>, %274 ], [ %295, %276 ]
%279 = phi i64 [ 0, %274 ], [ %296, %276 ]
%280 = uitofp <2 x i64> %278 to <2 x double>
%281 = fdiv <2 x double> %280, %264
%282 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %281, <2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> <double -1.000000e+00, double -1.000000e+00>)
%283 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %266, <2 x double> %282, <2 x double> %268)
%284 = getelementptr inbounds double, double* %4, i64 %277
%285 = bitcast double* %284 to <2 x double>*
store <2 x double> %283, <2 x double>* %285
%286 = or i64 %277, 2
%287 = add <2 x i64> %278, <i64 2, i64 2>
%288 = uitofp <2 x i64> %287 to <2 x double>
%289 = fdiv <2 x double> %288, %264
%290 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %289, <2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> <double -1.000000e+00, double -1.000000e+00>)
%291 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %266, <2 x double> %290, <2 x double> %268)
%292 = getelementptr inbounds double, double* %4, i64 %286
%293 = bitcast double* %292 to <2 x double>*
store <2 x double> %291, <2 x double>* %293
%294 = add nuw i64 %277, 4
%295 = add <2 x i64> %278, <i64 4, i64 4>
%296 = add nuw i64 %279, 2
%297 = icmp eq i64 %296, %275
br i1 %297, label %298, label %276
298: ; preds = %276
%299 = uitofp <2 x i64> %295 to <2 x double>
br label %300
300: ; preds = %298, %261
%301 = phi i64 [ 0, %261 ], [ %294, %298 ]
%302 = phi <2 x double> [ <double 0.000000e+00, double 1.000000e+00>, %261 ], [ %299, %298 ]
%303 = icmp eq i64 %272, 0
br i1 %303, label %310, label %304
304: ; preds = %300
%305 = fdiv <2 x double> %302, %264
%306 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %305, <2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> <double -1.000000e+00, double -1.000000e+00>)
%307 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %266, <2 x double> %306, <2 x double> %268)
%308 = getelementptr inbounds double, double* %4, i64 %301
%309 = bitcast double* %308 to <2 x double>*
store <2 x double> %307, <2 x double>* %309
br label %310
310: ; preds = %300, %304
%311 = icmp eq i64 %262, %2
br i1 %311, label %328, label %312
312: ; preds = %258, %310
%313 = phi i64 [ 0, %258 ], [ %262, %310 ]
br label %319
314: ; preds = %255, %314
%315 = phi i64 [ %317, %314 ], [ %256, %255 ]
%316 = getelementptr inbounds double, double* %5, i64 %315
store double %179, double* %316
%317 = add nuw i64 %315, 1
%318 = icmp eq i64 %317, %2
br i1 %318, label %257, label %314
319: ; preds = %312, %319
%320 = phi i64 [ %326, %319 ], [ %313, %312 ]
%321 = uitofp i64 %320 to double
%322 = fdiv double %321, %10
%323 = tail call double @llvm.fmuladd.f64(double %322, double 2.000000e+00, double -1.000000e+00)
%324 = tail call double @llvm.fmuladd.f64(double %259, double %323, double %175)
%325 = getelementptr inbounds double, double* %4, i64 %320
store double %324, double* %325
%326 = add nuw i64 %320, 1
%327 = icmp eq i64 %326, %2
br i1 %327, label %328, label %319
328: ; preds = %319, %310, %174, %257
%329 = shl i64 %2, 3
%330 = tail call double* @malloc(i64 %329)
%331 = tail call double* @malloc(i64 %329)
br label %333
332: ; preds = %341, %350
br label %333
333: ; preds = %332, %328
%334 = tail call i32 @print_progress(i64 %2, double* %3, double* %4, double* %5)
%335 = tail call i32 @memcpy(double* %330, double* %4, i64 %329)
%336 = tail call i32 @memcpy(double* %331, double* %5, i64 %329)
%337 = tail call i32 @e_step(i64 %1, i64 %2, double* %0, double* %9, double* %3, double* %4, double* %5)
%338 = tail call i32 @m_step(i64 %1, i64 %2, double* %0, double* %9, double* %3, double* %4, double* %5)
br i1 %12, label %359, label %341
339: ; preds = %350
%340 = icmp eq i64 %358, %2
br i1 %340, label %359, label %341
341: ; preds = %333, %339
%342 = phi i64 [ %358, %339 ], [ 0, %333 ]
%343 = getelementptr inbounds double, double* %4, i64 %342
%344 = load double, double* %343
%345 = getelementptr inbounds double, double* %330, i64 %342
%346 = load double, double* %345
%347 = fsub double %344, %346
%348 = tail call double @llvm.fabs.f64(double %347)
%349 = fcmp ogt double %348, 1.000000e-08
br i1 %349, label %332, label %350
350: ; preds = %341
%351 = getelementptr inbounds double, double* %5, i64 %342
%352 = load double, double* %351
%353 = getelementptr inbounds double, double* %331, i64 %342
%354 = load double, double* %353
%355 = fsub double %352, %354
%356 = tail call double @llvm.fabs.f64(double %355)
%357 = fcmp ogt double %356, 1.000000e-08
%358 = add nuw i64 %342, 1
br i1 %357, label %332, label %339
359: ; preds = %333, %339
%360 = tail call i32 @free(double* %9)
%361 = tail call i32 @free(double* %330)
%362 = tail call i32 @free(double* %331)
ret void
}