#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*/ _generate_row_indexes(int *, int, int, int *);
int /*<<< orphan*/ _normalize_all_sparse(double *, int *, int *, int, int);
double _sum_row_sparse(double *, int, int, int *, int, int);
double _update_step(double, double, double, double, double, double, int);
int /*<<< orphan*/ free(int *);
double genbet(double, double);
scalar_t__ is_positive(double);
scalar_t__ malloc(int);
void _update_sparse(double *C, double *sumC, double *X, double *sumX, int *I,
                    int *J, int n, int n_idx, int n_step) {
  int iter, i, j, k;
  double tmp1, tmp2;
  int *row_indexes = (int *)malloc((n + 1) * sizeof(int));
  _generate_row_indexes(I, n, n_idx, row_indexes);
  for (iter = 0; iter < n_step; iter++) {
    for (i = 0; i < n; i++)
      sumX[i] = _sum_row_sparse(X, n, i, J, row_indexes[i], row_indexes[i + 1]);
    for (k = 0; k < n_idx; k++) {
      i = I[k];
      j = J[k];
      if (i == j) {
        if (is_positive(C[i * n + i]) && is_positive(sumC[i] - C[i * n + i])) {
          tmp1 = genbet(C[i * n + i], sumC[i] - C[i * n + i]);
          tmp2 = tmp1 / (1 - tmp1) * (sumX[i] - X[i * n + i]);
          if (is_positive(tmp2)) {
            sumX[i] += tmp2 - X[i * n + i];
            X[i * n + i] = tmp2;
          }
        }
      }
      if (i < j) {
        tmp1 = sumX[i] - X[i * n + j];
        tmp2 = sumX[j] - X[j * n + i];
        X[i * n + j] =
            _update_step(X[i * n + j], tmp1, tmp2, C[i * n + j] + C[j * n + i],
                         sumC[i], sumC[j], 1);
        X[j * n + i] = X[i * n + j];
        sumX[i] = tmp1 + X[i * n + j];
        sumX[j] = tmp2 + X[j * n + i];
      }
    }
    _normalize_all_sparse(X, I, J, n, n_idx);
  }
  free(row_indexes);
}


x86 assembly (clang, -O0):
<_update_sparse>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    0x20(%rbp),%eax
mov    0x18(%rbp),%eax
mov    0x10(%rbp),%eax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    0x10(%rbp),%eax
add    $0x1,%eax
cltq
shl    $0x2,%rax
mov    %eax,%edi
call   1060 <malloc@plt>
mov    %rax,-0x58(%rbp)
mov    -0x28(%rbp),%rdi
mov    0x10(%rbp),%esi
mov    0x18(%rbp),%edx
mov    -0x58(%rbp),%rcx
call   1090 <_generate_row_indexes@plt>
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    0x20(%rbp),%eax
jge    155a <_update_sparse+0x3da>
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
cmp    0x10(%rbp),%eax
jge    1246 <_update_sparse+0xc6>
mov    -0x18(%rbp),%rdi
mov    0x10(%rbp),%esi
mov    -0x38(%rbp),%edx
mov    -0x30(%rbp),%rcx
mov    -0x58(%rbp),%rax
movslq -0x38(%rbp),%r8
mov    (%rax,%r8,4),%r8d
mov    -0x58(%rbp),%rax
mov    -0x38(%rbp),%r9d
add    $0x1,%r9d
movslq %r9d,%r9
mov    (%rax,%r9,4),%r9d
call   1080 <_sum_row_sparse@plt>
mov    -0x20(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    11ed <_update_sparse+0x6d>
movl   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%eax
cmp    0x18(%rbp),%eax
jge    1534 <_update_sparse+0x3b4>
mov    -0x28(%rbp),%rax
movslq -0x40(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
movslq -0x40(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x38(%rbp),%eax
cmp    -0x3c(%rbp),%eax
jne    13c3 <_update_sparse+0x243>
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
call   10a0 <is_positive@plt>
cmp    $0x0,%rax
je     13be <_update_sparse+0x23e>
mov    -0x10(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm0
call   10a0 <is_positive@plt>
cmp    $0x0,%rax
je     13be <_update_sparse+0x23e>
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm1
call   1040 <genbet@plt>
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  0xcd8(%rip),%xmm1
subsd  -0x48(%rbp),%xmm1
divsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
call   10a0 <is_positive@plt>
cmp    $0x0,%rax
je     13b9 <_update_sparse+0x239>
movsd  -0x50(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x38(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x50(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    13be <_update_sparse+0x23e>
jmp    13c3 <_update_sparse+0x243>
mov    -0x38(%rbp),%eax
cmp    -0x3c(%rbp),%eax
jge    1521 <_update_sparse+0x3a1>
mov    -0x20(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x3c(%rbp),%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x3c(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x3c(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x50(%rbp),%xmm2
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x3c(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm3
mov    -0x8(%rbp),%rax
mov    -0x3c(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
addsd  (%rax,%rcx,8),%xmm3
mov    -0x10(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm4
mov    -0x10(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm5
mov    $0x1,%edi
call   1070 <_update_step@plt>
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x3c(%rbp),%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x3c(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x3c(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x48(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x3c(%rbp),%ecx
movslq %ecx,%rcx
addsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x50(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x3c(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
addsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    1526 <_update_sparse+0x3a6>
mov    -0x40(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x40(%rbp)
jmp    124d <_update_sparse+0xcd>
mov    -0x18(%rbp),%rdi
mov    -0x28(%rbp),%rsi
mov    -0x30(%rbp),%rdx
mov    0x10(%rbp),%ecx
mov    0x18(%rbp),%r8d
call   1050 <_normalize_all_sparse@plt>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    11da <_update_sparse+0x5a>
mov    -0x58(%rbp),%rdi
call   1030 <free@plt>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<_update_sparse>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x78,%rsp
mov    %r9,%r14
mov    %r8,%r15
mov    %rcx,0x10(%rsp)
mov    %rdx,%rbx
mov    %rsi,0x38(%rsp)
mov    %rdi,0x28(%rsp)
mov    0xc0(%rsp),%eax
mov    %eax,0x1c(%rsp)
mov    0xb8(%rsp),%r13d
mov    0xb0(%rsp),%ebp
mov    %rbp,(%rsp)
lea    0x4(,%rbp,4),%edi
call   1060 <malloc@plt>
mov    %rax,%r12
mov    %r15,0x40(%rsp)
mov    %r15,%rdi
mov    %ebp,%esi
mov    %r13d,0xc(%rsp)
mov    %r13d,%edx
mov    %rax,%rcx
call   1090 <_generate_row_indexes@plt>
mov    0x10(%rsp),%r13
cmpl   $0x0,0x1c(%rsp)
jle    1483 <_update_sparse+0x303>
mov    (%rsp),%eax
mov    %rax,0x68(%rsp)
mov    0xc(%rsp),%eax
mov    %rax,0x60(%rsp)
xor    %eax,%eax
mov    %r14,0x70(%rsp)
mov    %rbx,0x20(%rsp)
mov    %r12,0x48(%rsp)
jmp    126a <_update_sparse+0xea>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    0x20(%rsp),%rdi
mov    %rdi,%rbx
mov    0x40(%rsp),%rsi
mov    %r14,%rdx
mov    (%rsp),%rcx
mov    0xc(%rsp),%r8d
call   1050 <_normalize_all_sparse@plt>
mov    0x50(%rsp),%rax
add    $0x1,%eax
cmp    0x1c(%rsp),%eax
mov    0x10(%rsp),%r13
mov    0x48(%rsp),%r12
je     1483 <_update_sparse+0x303>
mov    %rax,0x50(%rsp)
cmpl   $0x0,(%rsp)
jle    12af <_update_sparse+0x12f>
mov    %rbx,%r15
xor    %ebp,%ebp
nopw   0x0(%rax,%rax,1)
lea    0x1(%rbp),%rbx
mov    (%r12,%rbp,4),%r8d
mov    0x4(%r12,%rbp,4),%r9d
mov    %r15,%rdi
mov    (%rsp),%rsi
mov    %ebp,%edx
mov    %r14,%rcx
call   1080 <_sum_row_sparse@plt>
movsd  %xmm0,0x0(%r13,%rbp,8)
mov    %rbx,%rbp
cmp    %rbx,0x68(%rsp)
jne    1280 <_update_sparse+0x100>
cmpl   $0x0,0xc(%rsp)
jle    1230 <_update_sparse+0xb0>
xor    %ebp,%ebp
jmp    12d4 <_update_sparse+0x154>
xchg   %ax,%ax
add    $0x1,%rbp
cmp    %rbp,0x60(%rsp)
mov    0x70(%rsp),%r14
je     1230 <_update_sparse+0xb0>
mov    0x40(%rsp),%rax
movslq (%rax,%rbp,4),%r15
movslq (%r14,%rbp,4),%r12
cmp    %r12d,%r15d
jne    13c0 <_update_sparse+0x240>
mov    %r15d,%eax
imul   (%rsp),%eax
add    %r15d,%eax
movslq %eax,%r14
mov    0x28(%rsp),%rax
movsd  (%rax,%r14,8),%xmm0
call   10a0 <is_positive@plt>
test   %rax,%rax
je     13c0 <_update_sparse+0x240>
mov    0x38(%rsp),%rax
movsd  (%rax,%r15,8),%xmm0
mov    0x28(%rsp),%rax
subsd  (%rax,%r14,8),%xmm0
call   10a0 <is_positive@plt>
test   %rax,%rax
je     13c0 <_update_sparse+0x240>
mov    0x28(%rsp),%rax
movsd  (%rax,%r14,8),%xmm0
mov    0x38(%rsp),%rax
movsd  (%rax,%r15,8),%xmm1
subsd  %xmm0,%xmm1
call   1040 <genbet@plt>
movsd  0xca5(%rip),%xmm1
subsd  %xmm0,%xmm1
divsd  %xmm1,%xmm0
mov    0x10(%rsp),%rax
movsd  (%rax,%r15,8),%xmm1
mov    0x20(%rsp),%rax
subsd  (%rax,%r14,8),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,0x30(%rsp)
movapd %xmm1,%xmm0
call   10a0 <is_positive@plt>
test   %rax,%rax
je     13c0 <_update_sparse+0x240>
movsd  0x30(%rsp),%xmm1
movapd %xmm1,%xmm0
mov    0x20(%rsp),%rcx
subsd  (%rcx,%r14,8),%xmm0
mov    0x10(%rsp),%rax
addsd  (%rax,%r15,8),%xmm0
movsd  %xmm0,(%rax,%r15,8)
movsd  %xmm1,(%rcx,%r14,8)
nopl   (%rax)
cmp    %r12d,%r15d
jge    12c0 <_update_sparse+0x140>
mov    0x10(%rsp),%rax
movsd  (%rax,%r15,8),%xmm1
mov    %rax,%rcx
mov    %r15d,%eax
imul   (%rsp),%eax
add    %r12d,%eax
movslq %eax,%r14
mov    0x20(%rsp),%r13
movsd  0x0(%r13,%r14,8),%xmm0
subsd  %xmm0,%xmm1
movsd  %xmm1,0x58(%rsp)
movsd  (%rcx,%r12,8),%xmm2
mov    %r12d,%eax
imul   (%rsp),%eax
add    %r15d,%eax
movslq %eax,%rbx
subsd  0x0(%r13,%rbx,8),%xmm2
movsd  %xmm2,0x30(%rsp)
mov    0x28(%rsp),%rax
movsd  (%rax,%r14,8),%xmm3
addsd  (%rax,%rbx,8),%xmm3
mov    0x38(%rsp),%rax
movsd  (%rax,%r15,8),%xmm4
movsd  (%rax,%r12,8),%xmm5
mov    $0x1,%edi
call   1070 <_update_step@plt>
movsd  %xmm0,0x0(%r13,%r14,8)
movsd  %xmm0,0x0(%r13,%rbx,8)
movsd  0x58(%rsp),%xmm0
addsd  0x0(%r13,%r14,8),%xmm0
mov    0x10(%rsp),%rax
movsd  %xmm0,(%rax,%r15,8)
movsd  0x30(%rsp),%xmm0
addsd  0x0(%r13,%rbx,8),%xmm0
movsd  %xmm0,(%rax,%r12,8)
jmp    12c0 <_update_sparse+0x140>
mov    %r12,%rdi
add    $0x78,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <free@plt>

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

LLVM IR (-O2):
define void @_update_sparse(double* nocapture %0, double* nocapture %1, double* %2, double* nocapture %3, i32* %4, i32* %5, i32 %6, i32 %7, i32 %8) {
%10 = shl i32 %6, 2
%11 = add i32 %10, 4
%12 = tail call i64 @malloc(i32 %11)
%13 = inttoptr i64 %12 to i32*
%14 = tail call i32 @_generate_row_indexes(i32* %4, i32 %6, i32 %7, i32* %13)
%15 = icmp sgt i32 %8, 0
br i1 %15, label %16, label %120
16: ; preds = %9
%17 = icmp sgt i32 %6, 0
%18 = icmp sgt i32 %7, 0
%19 = zext i32 %6 to i64
%20 = zext i32 %7 to i64
br label %21
21: ; preds = %16, %116
%22 = phi i32 [ 0, %16 ], [ %118, %116 ]
br i1 %17, label %24, label %23
23: ; preds = %24, %21
br i1 %18, label %35, label %116
24: ; preds = %21, %24
%25 = phi i64 [ %28, %24 ], [ 0, %21 ]
%26 = getelementptr inbounds i32, i32* %13, i64 %25
%27 = load i32, i32* %26
%28 = add nuw nsw i64 %25, 1
%29 = getelementptr inbounds i32, i32* %13, i64 %28
%30 = load i32, i32* %29
%31 = trunc i64 %25 to i32
%32 = tail call double @_sum_row_sparse(double* %2, i32 %6, i32 %31, i32* %5, i32 %27, i32 %30)
%33 = getelementptr inbounds double, double* %3, i64 %25
store double %32, double* %33
%34 = icmp eq i64 %28, %19
br i1 %34, label %23, label %24
35: ; preds = %23, %113
%36 = phi i64 [ %114, %113 ], [ 0, %23 ]
%37 = getelementptr inbounds i32, i32* %4, i64 %36
%38 = load i32, i32* %37
%39 = getelementptr inbounds i32, i32* %5, i64 %36
%40 = load i32, i32* %39
%41 = icmp eq i32 %38, %40
br i1 %41, label %42, label %78
42: ; preds = %35
%43 = mul nsw i32 %38, %6
%44 = add nsw i32 %43, %38
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds double, double* %0, i64 %45
%47 = load double, double* %46
%48 = tail call i64 @is_positive(double %47)
%49 = icmp eq i64 %48, 0
br i1 %49, label %78, label %50
50: ; preds = %42
%51 = sext i32 %38 to i64
%52 = getelementptr inbounds double, double* %1, i64 %51
%53 = load double, double* %52
%54 = load double, double* %46
%55 = fsub double %53, %54
%56 = tail call i64 @is_positive(double %55)
%57 = icmp eq i64 %56, 0
br i1 %57, label %78, label %58
58: ; preds = %50
%59 = load double, double* %46
%60 = load double, double* %52
%61 = fsub double %60, %59
%62 = tail call double @genbet(double %59, double %61)
%63 = fsub double 1.000000e+00, %62
%64 = fdiv double %62, %63
%65 = getelementptr inbounds double, double* %3, i64 %51
%66 = load double, double* %65
%67 = getelementptr inbounds double, double* %2, i64 %45
%68 = load double, double* %67
%69 = fsub double %66, %68
%70 = fmul double %64, %69
%71 = tail call i64 @is_positive(double %70)
%72 = icmp eq i64 %71, 0
br i1 %72, label %78, label %73
73: ; preds = %58
%74 = load double, double* %67
%75 = fsub double %70, %74
%76 = load double, double* %65
%77 = fadd double %76, %75
store double %77, double* %65
store double %70, double* %67
br label %78
78: ; preds = %42, %50, %73, %58, %35
%79 = icmp slt i32 %38, %40
br i1 %79, label %80, label %113
80: ; preds = %78
%81 = sext i32 %38 to i64
%82 = getelementptr inbounds double, double* %3, i64 %81
%83 = load double, double* %82
%84 = mul nsw i32 %38, %6
%85 = add nsw i32 %84, %40
%86 = sext i32 %85 to i64
%87 = getelementptr inbounds double, double* %2, i64 %86
%88 = load double, double* %87
%89 = fsub double %83, %88
%90 = sext i32 %40 to i64
%91 = getelementptr inbounds double, double* %3, i64 %90
%92 = load double, double* %91
%93 = mul nsw i32 %40, %6
%94 = add nsw i32 %93, %38
%95 = sext i32 %94 to i64
%96 = getelementptr inbounds double, double* %2, i64 %95
%97 = load double, double* %96
%98 = fsub double %92, %97
%99 = getelementptr inbounds double, double* %0, i64 %86
%100 = load double, double* %99
%101 = getelementptr inbounds double, double* %0, i64 %95
%102 = load double, double* %101
%103 = fadd double %100, %102
%104 = getelementptr inbounds double, double* %1, i64 %81
%105 = load double, double* %104
%106 = getelementptr inbounds double, double* %1, i64 %90
%107 = load double, double* %106
%108 = tail call double @_update_step(double %88, double %89, double %98, double %103, double %105, double %107, i32 1)
store double %108, double* %87
store double %108, double* %96
%109 = load double, double* %87
%110 = fadd double %89, %109
store double %110, double* %82
%111 = load double, double* %96
%112 = fadd double %98, %111
store double %112, double* %91
br label %113
113: ; preds = %78, %80
%114 = add nuw nsw i64 %36, 1
%115 = icmp eq i64 %114, %20
br i1 %115, label %116, label %35
116: ; preds = %113, %23
%117 = tail call i32 @_normalize_all_sparse(double* %2, i32* %4, i32* %5, i32 %6, i32 %7)
%118 = add nuw nsw i32 %22, 1
%119 = icmp eq i32 %118, %8
br i1 %119, label %120, label %21
120: ; preds = %116, %9
%121 = tail call i32 @free(i32* %13)
ret void
}