double SimInf_local_spread(const double *neighbors, const double *phi,
                           const int *u, const double N_i, const double phi_i,
                           const int Nc, const double D) {
  int j, k;
  double N_j, ls = 0.0;
  const double phi_i_N_i = phi_i * N_i;
  j = (int)*neighbors++;
  while (j >= 0) {
    for (k = j * Nc, N_j = 0; k < (j + 1) * Nc; k++)
      N_j += u[k];
    if (N_j > 0.0)
      ls += ((phi[j] * N_j - phi_i_N_i) * D) / (N_i * (*neighbors));
    neighbors++;
    j = (int)*neighbors++;
  }
  return ls;
}


x86 assembly (clang, -O0):
<SimInf_local_spread>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movsd  %xmm0,-0x20(%rbp)
movsd  %xmm1,-0x28(%rbp)
mov    %ecx,-0x2c(%rbp)
movsd  %xmm2,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x8(%rbp)
cvttsd2si (%rax),%eax
mov    %eax,-0x3c(%rbp)
cmpl   $0x0,-0x3c(%rbp)
jl     1234 <SimInf_local_spread+0x134>
mov    -0x3c(%rbp),%eax
imul   -0x2c(%rbp),%eax
mov    %eax,-0x40(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x40(%rbp),%eax
mov    -0x3c(%rbp),%ecx
add    $0x1,%ecx
imul   -0x2c(%rbp),%ecx
cmp    %ecx,%eax
jge    11a5 <SimInf_local_spread+0xa5>
mov    -0x18(%rbp),%rax
movslq -0x40(%rbp),%rcx
cvtsi2sdl (%rax,%rcx,4),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x40(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x40(%rbp)
jmp    116b <SimInf_local_spread+0x6b>
movsd  -0x48(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    120d <SimInf_local_spread+0x10d>
mov    -0x10(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  -0x48(%rbp),%xmm2
movsd  -0x58(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm1
mov    -0x8(%rbp),%rax
mulsd  (%rax),%xmm1
divsd  %xmm1,%xmm0
addsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x8(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x8(%rbp)
cvttsd2si (%rax),%eax
mov    %eax,-0x3c(%rbp)
jmp    114f <SimInf_local_spread+0x4f>
movsd  -0x50(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<SimInf_local_spread>:
cvttsd2si (%rdi),%r8d
test   %r8d,%r8d
js     1210 <SimInf_local_spread+0x110>
xorpd  0xeea(%rip),%xmm1
add    $0x8,%rdi
mulsd  %xmm0,%xmm1
xorpd  %xmm4,%xmm4
xorpd  %xmm3,%xmm3
jmp    1143 <SimInf_local_spread+0x43>
nopl   0x0(%rax,%rax,1)
cvttsd2si 0x8(%rdi),%r8d
add    $0x10,%rdi
test   %r8d,%r8d
js     120b <SimInf_local_spread+0x10b>
mov    %r8d,%r11d
imul   %ecx,%r11d
lea    0x1(%r8),%r10d
imul   %ecx,%r10d
cmp    %r10d,%r11d
jge    1130 <SimInf_local_spread+0x30>
movslq %r11d,%rax
movslq %r10d,%r9
sub    %r11d,%r10d
mov    %rax,%r11
not    %r11
add    %r9,%r11
xorpd  %xmm5,%xmm5
and    $0x3,%r10
je     1196 <SimInf_local_spread+0x96>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
xorps  %xmm6,%xmm6
cvtsi2sdl (%rdx,%rax,4),%xmm6
addsd  %xmm6,%xmm5
add    $0x1,%rax
add    $0xffffffffffffffff,%r10
jne    1180 <SimInf_local_spread+0x80>
cmp    $0x3,%r11
jb     11dc <SimInf_local_spread+0xdc>
nopl   0x0(%rax)
xorps  %xmm6,%xmm6
cvtsi2sdl (%rdx,%rax,4),%xmm6
addsd  %xmm5,%xmm6
xorps  %xmm7,%xmm7
cvtsi2sdl 0x4(%rdx,%rax,4),%xmm7
addsd  %xmm6,%xmm7
xorps  %xmm6,%xmm6
cvtsi2sdl 0x8(%rdx,%rax,4),%xmm6
xorps  %xmm5,%xmm5
cvtsi2sdl 0xc(%rdx,%rax,4),%xmm5
addsd  %xmm7,%xmm6
addsd  %xmm6,%xmm5
add    $0x4,%rax
cmp    %rax,%r9
jne    11a0 <SimInf_local_spread+0xa0>
ucomisd %xmm4,%xmm5
jbe    1130 <SimInf_local_spread+0x30>
movslq %r8d,%rax
mulsd  (%rsi,%rax,8),%xmm5
addsd  %xmm1,%xmm5
mulsd  %xmm2,%xmm5
movsd  (%rdi),%xmm6
mulsd  %xmm0,%xmm6
divsd  %xmm6,%xmm5
addsd  %xmm5,%xmm3
jmp    1130 <SimInf_local_spread+0x30>
movapd %xmm3,%xmm0
ret
xorps  %xmm0,%xmm0
ret

LLVM IR (-O0):
define double @SimInf_local_spread(double* %0, double* %1, i32* %2, double %3, double %4, i32 %5, double %6) {
%8 = alloca double*
%9 = alloca double*
%10 = alloca i32*
%11 = alloca double
%12 = alloca double
%13 = alloca i32
%14 = alloca double
%15 = alloca i32
%16 = alloca i32
%17 = alloca double
%18 = alloca double
%19 = alloca double
store double* %0, double** %8
store double* %1, double** %9
store i32* %2, i32** %10
store double %3, double* %11
store double %4, double* %12
store i32 %5, i32* %13
store double %6, double* %14
store double 0.000000e+00, double* %18
%20 = load double, double* %12
%21 = load double, double* %11
%22 = fmul double %20, %21
store double %22, double* %19
%23 = load double*, double** %8
%24 = getelementptr inbounds double, double* %23, i32 1
store double* %24, double** %8
%25 = load double, double* %23
%26 = fptosi double %25 to i32
store i32 %26, i32* %15
br label %27
27: ; preds = %75, %7
%28 = load i32, i32* %15
%29 = icmp sge i32 %28, 0
br i1 %29, label %30, label %82
30: ; preds = %27
%31 = load i32, i32* %15
%32 = load i32, i32* %13
%33 = mul nsw i32 %31, %32
store i32 %33, i32* %16
store double 0.000000e+00, double* %17
br label %34
34: ; preds = %50, %30
%35 = load i32, i32* %16
%36 = load i32, i32* %15
%37 = add nsw i32 %36, 1
%38 = load i32, i32* %13
%39 = mul nsw i32 %37, %38
%40 = icmp slt i32 %35, %39
br i1 %40, label %41, label %53
41: ; preds = %34
%42 = load i32*, i32** %10
%43 = load i32, i32* %16
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds i32, i32* %42, i64 %44
%46 = load i32, i32* %45
%47 = sitofp i32 %46 to double
%48 = load double, double* %17
%49 = fadd double %48, %47
store double %49, double* %17
br label %50
50: ; preds = %41
%51 = load i32, i32* %16
%52 = add nsw i32 %51, 1
store i32 %52, i32* %16
br label %34
53: ; preds = %34
%54 = load double, double* %17
%55 = fcmp ogt double %54, 0.000000e+00
br i1 %55, label %56, label %75
56: ; preds = %53
%57 = load double*, double** %9
%58 = load i32, i32* %15
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds double, double* %57, i64 %59
%61 = load double, double* %60
%62 = load double, double* %17
%63 = load double, double* %19
%64 = fneg double %63
%65 = call double @llvm.fmuladd.f64(double %61, double %62, double %64)
%66 = load double, double* %14
%67 = fmul double %65, %66
%68 = load double, double* %11
%69 = load double*, double** %8
%70 = load double, double* %69
%71 = fmul double %68, %70
%72 = fdiv double %67, %71
%73 = load double, double* %18
%74 = fadd double %73, %72
store double %74, double* %18
br label %75
75: ; preds = %56, %53
%76 = load double*, double** %8
%77 = getelementptr inbounds double, double* %76, i32 1
store double* %77, double** %8
%78 = load double*, double** %8
%79 = getelementptr inbounds double, double* %78, i32 1
store double* %79, double** %8
%80 = load double, double* %78
%81 = fptosi double %80 to i32
store i32 %81, i32* %15
br label %27
82: ; preds = %27
%83 = load double, double* %18
ret double %83
}

LLVM IR (-O2):
define double @SimInf_local_spread(double* nocapture %0, double* nocapture %1, i32* nocapture %2, double %3, double %4, i32 %5, double %6) {
%8 = load double, double* %0
%9 = fptosi double %8 to i32
%10 = icmp sgt i32 %9, -1
br i1 %10, label %11, label %91
11: ; preds = %7
%12 = getelementptr inbounds double, double* %0, i64 1
%13 = fneg double %4
%14 = fmul double %13, %3
br label %15
15: ; preds = %11, %84
%16 = phi i32 [ %9, %11 ], [ %89, %84 ]
%17 = phi double* [ %12, %11 ], [ %87, %84 ]
%18 = phi double [ 0.000000e+00, %11 ], [ %85, %84 ]
%19 = mul i32 %16, %5
%20 = add nuw nsw i32 %16, 1
%21 = mul i32 %20, %5
%22 = icmp slt i32 %19, %21
br i1 %22, label %23, label %84
23: ; preds = %15
%24 = sext i32 %19 to i64
%25 = sext i32 %21 to i64
%26 = sub nsw i64 %25, %24
%27 = xor i64 %24, -1
%28 = add nsw i64 %27, %25
%29 = and i64 %26, 3
%30 = icmp eq i64 %29, 0
br i1 %30, label %42, label %31
31: ; preds = %23, %31
%32 = phi i64 [ %39, %31 ], [ %24, %23 ]
%33 = phi double [ %38, %31 ], [ 0.000000e+00, %23 ]
%34 = phi i64 [ %40, %31 ], [ 0, %23 ]
%35 = getelementptr inbounds i32, i32* %2, i64 %32
%36 = load i32, i32* %35
%37 = sitofp i32 %36 to double
%38 = fadd double %33, %37
%39 = add nsw i64 %32, 1
%40 = add i64 %34, 1
%41 = icmp eq i64 %40, %29
br i1 %41, label %42, label %31
42: ; preds = %31, %23
%43 = phi double [ undef, %23 ], [ %38, %31 ]
%44 = phi i64 [ %24, %23 ], [ %39, %31 ]
%45 = phi double [ 0.000000e+00, %23 ], [ %38, %31 ]
%46 = icmp ult i64 %28, 3
br i1 %46, label %71, label %47
47: ; preds = %42, %47
%48 = phi i64 [ %69, %47 ], [ %44, %42 ]
%49 = phi double [ %68, %47 ], [ %45, %42 ]
%50 = getelementptr inbounds i32, i32* %2, i64 %48
%51 = load i32, i32* %50
%52 = sitofp i32 %51 to double
%53 = fadd double %49, %52
%54 = add nsw i64 %48, 1
%55 = getelementptr inbounds i32, i32* %2, i64 %54
%56 = load i32, i32* %55
%57 = sitofp i32 %56 to double
%58 = fadd double %53, %57
%59 = add nsw i64 %48, 2
%60 = getelementptr inbounds i32, i32* %2, i64 %59
%61 = load i32, i32* %60
%62 = sitofp i32 %61 to double
%63 = fadd double %58, %62
%64 = add nsw i64 %48, 3
%65 = getelementptr inbounds i32, i32* %2, i64 %64
%66 = load i32, i32* %65
%67 = sitofp i32 %66 to double
%68 = fadd double %63, %67
%69 = add nsw i64 %48, 4
%70 = icmp eq i64 %69, %25
br i1 %70, label %71, label %47
71: ; preds = %47, %42
%72 = phi double [ %43, %42 ], [ %68, %47 ]
%73 = fcmp ogt double %72, 0.000000e+00
br i1 %73, label %74, label %84
74: ; preds = %71
%75 = sext i32 %16 to i64
%76 = getelementptr inbounds double, double* %1, i64 %75
%77 = load double, double* %76
%78 = tail call double @llvm.fmuladd.f64(double %77, double %72, double %14)
%79 = fmul double %78, %6
%80 = load double, double* %17
%81 = fmul double %80, %3
%82 = fdiv double %79, %81
%83 = fadd double %18, %82
br label %84
84: ; preds = %15, %74, %71
%85 = phi double [ %83, %74 ], [ %18, %71 ], [ %18, %15 ]
%86 = getelementptr inbounds double, double* %17, i64 1
%87 = getelementptr inbounds double, double* %17, i64 2
%88 = load double, double* %86
%89 = fptosi double %88 to i32
%90 = icmp sgt i32 %89, -1
br i1 %90, label %15, label %91
91: ; preds = %84, %7
%92 = phi double [ 0.000000e+00, %7 ], [ %85, %84 ]
ret double %92
}