void scf_gradient_helper(double *xyz, int K, double G, double M, double r_s,
                         double *Snlm, double *Tnlm, int nmax, int lmax,
                         double *grad) {
  int i, j, k, n, l, m;
  double r, s, X, phi;
  double sintheta, cosphi, sinphi, tmp;
  double tmp_grad[3], tmp_grad2[3 * K];
  double cosmphi[lmax + 1], sinmphi[lmax + 1];
  memset(cosmphi, 0, (lmax + 1) * sizeof(double));
  memset(sinmphi, 0, (lmax + 1) * sizeof(double));
  for (k = 0; k < K; k++) {
    j = 3 * k;
    r = sqrt(xyz[j] * xyz[j] + xyz[j + 1] * xyz[j + 1] +
             xyz[j + 2] * xyz[j + 2]);
    s = r / r_s;
    X = xyz[j + 2] / r;
    phi = atan2(xyz[j + 1], xyz[j + 0]);
    sintheta = sqrt(1 - X * X);
    cosphi = cos(phi);
    sinphi = sin(phi);
    for (m = 0; m < (lmax + 1); m++) {
      cosmphi[m] = cos(m * phi);
      sinmphi[m] = sin(m * phi);
    }
    tmp_grad2[j + 0] = 0.;
    tmp_grad2[j + 1] = 0.;
    tmp_grad2[j + 2] = 0.;
    for (n = 0; n < (nmax + 1); n++) {
      for (l = 0; l < (lmax + 1); l++) {
        for (m = 0; m < (lmax + 1); m++) {
          if (m > l) {
            continue;
          }
          i = m + (lmax + 1) * (l + (lmax + 1) * n);
          tmp = (Snlm[i] * cosmphi[m] + Tnlm[i] * sinmphi[m]);
          if ((Snlm[i] == 0.) & (Tnlm[i] == 0.)) {
            continue;
          }
          sph_grad_phi_nlm(s, phi, X, n, l, m, lmax, &tmp_grad[0]);
          tmp_grad2[j + 0] += tmp_grad[0] * tmp;
          tmp_grad2[j + 1] += tmp_grad[1] * tmp;
          tmp_grad2[j + 2] += tmp_grad[2] *
                              (Tnlm[i] * cosmphi[m] - Snlm[i] * sinmphi[m]) /
                              (s * sintheta);
        }
      }
    }
    tmp_grad[0] = tmp_grad2[j + 0];
    tmp_grad[1] = tmp_grad2[j + 1];
    tmp_grad[2] = tmp_grad2[j + 2];
    tmp_grad2[j + 0] = sintheta * cosphi * tmp_grad[0] +
                       X * cosphi * tmp_grad[1] - sinphi * tmp_grad[2];
    tmp_grad2[j + 1] = sintheta * sinphi * tmp_grad[0] +
                       X * sinphi * tmp_grad[1] + cosphi * tmp_grad[2];
    tmp_grad2[j + 2] = X * tmp_grad[0] - sintheta * tmp_grad[1];
    grad[j + 0] = grad[j + 0] + tmp_grad2[j + 0] * G * M / (r_s * r_s);
    grad[j + 1] = grad[j + 1] + tmp_grad2[j + 1] * G * M / (r_s * r_s);
    grad[j + 2] = grad[j + 2] + tmp_grad2[j + 2] * G * M / (r_s * r_s);
  }
}


x86 assembly (clang, -O0):
<scf_gradient_helper>:
push   %rbp
mov    %rsp,%rbp
sub    $0xf0,%rsp
mov    0x10(%rbp),%rax
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
movsd  %xmm2,-0x28(%rbp)
mov    %rdx,-0x30(%rbp)
mov    %rcx,-0x38(%rbp)
mov    %r8d,-0x3c(%rbp)
mov    %r9d,-0x40(%rbp)
mov    -0xc(%rbp),%ecx
mov    %ecx,%eax
lea    (%rax,%rax,2),%eax
mov    %rsp,%rcx
mov    %rcx,-0xb8(%rbp)
lea    0xf(,%rax,8),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0xe8(%rbp)
mov    %rcx,%rsp
mov    %rax,-0xc0(%rbp)
mov    -0x40(%rbp),%eax
add    $0x1,%eax
lea    0xf(,%rax,8),%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%rdi
sub    %rcx,%rdi
mov    %rdi,-0xe0(%rbp)
mov    %rdi,%rsp
mov    %rax,-0xc8(%rbp)
mov    -0x40(%rbp),%eax
add    $0x1,%eax
lea    0xf(,%rax,8),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0xd8(%rbp)
mov    %rcx,%rsp
mov    %rax,-0xd0(%rbp)
mov    -0x40(%rbp),%eax
add    $0x1,%eax
movslq %eax,%rdx
shl    $0x3,%rdx
xor    %esi,%esi
call   1040 <memset@plt>
mov    -0xd8(%rbp),%rdi
mov    -0x40(%rbp),%eax
add    $0x1,%eax
movslq %eax,%rdx
shl    $0x3,%rdx
xor    %esi,%esi
call   1040 <memset@plt>
movl   $0x0,-0x4c(%rbp)
mov    -0x4c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    18e0 <scf_gradient_helper+0x780>
imul   $0x3,-0x4c(%rbp),%eax
mov    %eax,-0x48(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x48(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x8(%rbp),%rax
movslq -0x48(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
call   1080 <sqrt@plt>
movsd  %xmm0,-0x60(%rbp)
movsd  -0x60(%rbp),%xmm0
divsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
divsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
call   1030 <atan2@plt>
movsd  %xmm0,-0x78(%rbp)
movsd  -0x70(%rbp),%xmm0
movsd  -0x70(%rbp),%xmm1
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm1,%xmm0
movsd  0xc99(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1080 <sqrt@plt>
movsd  %xmm0,-0x80(%rbp)
movsd  -0x78(%rbp),%xmm0
call   1070 <cos@plt>
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x78(%rbp),%xmm0
call   1050 <sin@plt>
movsd  %xmm0,-0x90(%rbp)
ff
movl   $0x0,-0x58(%rbp)
mov    -0x58(%rbp),%eax
mov    -0x40(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    13fd <scf_gradient_helper+0x29d>
cvtsi2sdl -0x58(%rbp),%xmm0
mulsd  -0x78(%rbp),%xmm0
call   1070 <cos@plt>
mov    -0xe0(%rbp),%rax
movslq -0x58(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
cvtsi2sdl -0x58(%rbp),%xmm0
mulsd  -0x78(%rbp),%xmm0
call   1050 <sin@plt>
mov    -0xd8(%rbp),%rax
movslq -0x58(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x58(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x58(%rbp)
jmp    13a0 <scf_gradient_helper+0x240>
mov    -0xe8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x48(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movl   $0x0,-0x50(%rbp)
mov    -0x50(%rbp),%eax
mov    -0x3c(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    1691 <scf_gradient_helper+0x531>
movl   $0x0,-0x54(%rbp)
mov    -0x54(%rbp),%eax
mov    -0x40(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    167e <scf_gradient_helper+0x51e>
movl   $0x0,-0x58(%rbp)
mov    -0x58(%rbp),%eax
mov    -0x40(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    166b <scf_gradient_helper+0x50b>
mov    -0x58(%rbp),%eax
cmp    -0x54(%rbp),%eax
jle    1490 <scf_gradient_helper+0x330>
jmp    165d <scf_gradient_helper+0x4fd>
mov    -0xd8(%rbp),%rax
mov    -0xe0(%rbp),%rcx
mov    -0x58(%rbp),%edx
mov    -0x40(%rbp),%esi
add    $0x1,%esi
mov    -0x54(%rbp),%edi
mov    -0x40(%rbp),%r8d
add    $0x1,%r8d
imul   -0x50(%rbp),%r8d
add    %r8d,%edi
imul   %edi,%esi
add    %esi,%edx
mov    %edx,-0x44(%rbp)
mov    -0x30(%rbp),%rdx
movslq -0x44(%rbp),%rsi
movsd  (%rdx,%rsi,8),%xmm0
movslq -0x58(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm2
mov    -0x38(%rbp),%rcx
movslq -0x44(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm1
movslq -0x58(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
mov    -0x30(%rbp),%rax
movslq -0x44(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
and    $0x1,%al
movzbl %al,%eax
mov    -0x38(%rbp),%rcx
movslq -0x44(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
sete   %cl
setnp  %dl
and    %dl,%cl
and    $0x1,%cl
movzbl %cl,%ecx
and    %ecx,%eax
cmp    $0x0,%eax
je     1551 <scf_gradient_helper+0x3f1>
jmp    165d <scf_gradient_helper+0x4fd>
movsd  -0x68(%rbp),%xmm0
movsd  -0x78(%rbp),%xmm1
movsd  -0x70(%rbp),%xmm2
mov    -0x50(%rbp),%edi
mov    -0x54(%rbp),%esi
mov    -0x58(%rbp),%edx
mov    -0x40(%rbp),%ecx
lea    -0xb0(%rbp),%r8
mov    $0x3,%al
call   1060 <sph_grad_phi_nlm@plt>
mov    -0xe0(%rbp),%rdx
mov    -0xd8(%rbp),%rcx
mov    -0xe8(%rbp),%rax
movsd  -0xb0(%rbp),%xmm0
ff
movsd  -0x98(%rbp),%xmm2
ff
mov    -0x48(%rbp),%esi
add    $0x0,%esi
movslq %esi,%rsi
movsd  (%rax,%rsi,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rsi,8)
movsd  -0xa8(%rbp),%xmm0
ff
movsd  -0x98(%rbp),%xmm2
ff
mov    -0x48(%rbp),%esi
add    $0x1,%esi
movslq %esi,%rsi
movsd  (%rax,%rsi,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rsi,8)
movsd  -0xa0(%rbp),%xmm0
ff
mov    -0x38(%rbp),%rsi
movslq -0x44(%rbp),%rdi
movsd  (%rsi,%rdi,8),%xmm1
movslq -0x58(%rbp),%rsi
movsd  (%rdx,%rsi,8),%xmm3
mov    -0x30(%rbp),%rdx
movslq -0x44(%rbp),%rsi
movsd  (%rdx,%rsi,8),%xmm2
movslq -0x58(%rbp),%rdx
mulsd  (%rcx,%rdx,8),%xmm2
movq   %xmm2,%rcx
movabs $0x8000000000000000,%rdx
xor    %rdx,%rcx
movq   %rcx,%xmm2
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  -0x68(%rbp),%xmm1
mulsd  -0x80(%rbp),%xmm1
divsd  %xmm1,%xmm0
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x58(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x58(%rbp)
jmp    146e <scf_gradient_helper+0x30e>
jmp    1670 <scf_gradient_helper+0x510>
mov    -0x54(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
jmp    1456 <scf_gradient_helper+0x2f6>
jmp    1683 <scf_gradient_helper+0x523>
mov    -0x50(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x50(%rbp)
jmp    143e <scf_gradient_helper+0x2de>
mov    -0xe8(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
mov    -0x48(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  -0x80(%rbp),%xmm1
mulsd  -0x88(%rbp),%xmm1
ff
movsd  -0xb0(%rbp),%xmm2
ff
movsd  -0x70(%rbp),%xmm0
mulsd  -0x88(%rbp),%xmm0
ff
mulsd  -0xa8(%rbp),%xmm0
ff
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x90(%rbp),%xmm0
ff
movsd  -0xa0(%rbp),%xmm2
ff
movq   %xmm0,%rcx
movabs $0x8000000000000000,%rdx
xor    %rdx,%rcx
movq   %rcx,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x48(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x80(%rbp),%xmm1
mulsd  -0x90(%rbp),%xmm1
ff
movsd  -0xb0(%rbp),%xmm2
ff
movsd  -0x70(%rbp),%xmm0
mulsd  -0x90(%rbp),%xmm0
ff
mulsd  -0xa8(%rbp),%xmm0
ff
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x88(%rbp),%xmm0
ff
movsd  -0xa0(%rbp),%xmm2
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x48(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x70(%rbp),%xmm0
movsd  -0xb0(%rbp),%xmm2
ff
movsd  -0x80(%rbp),%xmm1
mulsd  -0xa8(%rbp),%xmm1
ff
movq   %xmm1,%rcx
movabs $0x8000000000000000,%rdx
xor    %rdx,%rcx
movq   %rcx,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    0x10(%rbp),%rcx
mov    -0x48(%rbp),%edx
add    $0x0,%edx
movslq %edx,%rdx
movsd  (%rcx,%rdx,8),%xmm0
mov    -0x48(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  -0x18(%rbp),%xmm1
mulsd  -0x20(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm2
mulsd  -0x28(%rbp),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
mov    0x10(%rbp),%rcx
mov    -0x48(%rbp),%edx
add    $0x0,%edx
movslq %edx,%rdx
movsd  %xmm0,(%rcx,%rdx,8)
mov    0x10(%rbp),%rcx
mov    -0x48(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movsd  (%rcx,%rdx,8),%xmm0
mov    -0x48(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  -0x18(%rbp),%xmm1
mulsd  -0x20(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm2
mulsd  -0x28(%rbp),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
mov    0x10(%rbp),%rcx
mov    -0x48(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movsd  %xmm0,(%rcx,%rdx,8)
mov    0x10(%rbp),%rcx
mov    -0x48(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movsd  (%rcx,%rdx,8),%xmm0
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  -0x18(%rbp),%xmm1
mulsd  -0x20(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm2
mulsd  -0x28(%rbp),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
mov    0x10(%rbp),%rax
mov    -0x48(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x4c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4c(%rbp)
jmp    1252 <scf_gradient_helper+0xf2>
mov    -0xb8(%rbp),%rax
mov    %rax,%rsp
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<scf_gradient_helper>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x1a8,%rsp
mov    %r8,-0x80(%rbp)
mov    %rcx,-0xc0(%rbp)
mov    %rdx,-0xb8(%rbp)
movsd  %xmm2,-0x78(%rbp)
movapd %xmm1,-0x150(%rbp)
ff
movapd %xmm0,-0x140(%rbp)
ff
mov    %esi,%r14d
mov    %rdi,-0xd0(%rbp)
mov    %rsp,-0xa8(%rbp)
mov    %r9,-0x68(%rbp)
lea    0x1(%r9),%r15d
mov    %rsp,%r12
lea    0xf(,%r15,8),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r12
mov    %r12,%rsp
mov    %rsp,%rbx
sub    %rax,%rbx
mov    %rbx,%rsp
movslq %r15d,%rax
mov    %rax,-0x58(%rbp)
lea    0x0(,%rax,8),%r13
mov    %r12,%rdi
xor    %esi,%esi
mov    %r13,%rdx
call   1040 <memset@plt>
mov    %rbx,%rdi
xor    %esi,%esi
mov    %r13,-0x100(%rbp)
mov    %r13,%rdx
call   1040 <memset@plt>
test   %r14d,%r14d
jle    1751 <scf_gradient_helper+0x5f1>
movsd  -0x78(%rbp),%xmm0
mulsd  %xmm0,%xmm0
mov    -0x80(%rbp),%rax
add    $0x1,%eax
mov    %rax,-0xe8(%rbp)
mov    %r14d,%eax
mov    %rax,-0xc8(%rbp)
movaps -0x140(%rbp),%xmm1
movlhps %xmm1,%xmm1
movaps %xmm1,-0x180(%rbp)
movapd -0x150(%rbp),%xmm1
ff
unpcklpd %xmm1,%xmm1
movapd %xmm1,-0x170(%rbp)
ff
movapd %xmm0,-0x190(%rbp)
ff
unpcklpd %xmm0,%xmm0
movapd %xmm0,-0x160(%rbp)
ff
mov    %r15d,%eax
and    $0xfffffffe,%eax
mov    %rax,-0xb0(%rbp)
mov    -0x58(%rbp),%r13
imul   %r13,%r13
shl    $0x3,%r13
mov    %r13,-0x58(%rbp)
xor    %eax,%eax
xorpd  %xmm3,%xmm3
mov    %r12,-0x40(%rbp)
mov    %rbx,-0x38(%rbp)
jmp    13a8 <scf_gradient_helper+0x248>
cs nopw 0x0(%rax,%rax,1)
nop
xorpd  %xmm6,%xmm6
xorpd  %xmm5,%xmm5
movapd %xmm6,-0x130(%rbp)
ff
movapd -0x90(%rbp),%xmm8
ff ff
movapd %xmm8,%xmm0
unpcklpd %xmm8,%xmm0
movapd -0x1b0(%rbp),%xmm9
ff ff
movapd %xmm9,%xmm1
movapd -0x1a0(%rbp),%xmm7
ff
unpcklpd %xmm7,%xmm1
mulpd  %xmm1,%xmm0
movapd -0xa0(%rbp),%xmm4
ff
movapd %xmm4,%xmm2
unpcklpd %xmm4,%xmm2
mulpd  %xmm1,%xmm2
movapd %xmm6,%xmm1
mulsd  %xmm6,%xmm4
unpcklpd %xmm6,%xmm6
mulpd  %xmm0,%xmm6
unpckhpd %xmm1,%xmm1
mulpd  %xmm1,%xmm2
addpd  %xmm2,%xmm6
xorpd  0xcf7(%rip),%xmm7
unpcklpd %xmm9,%xmm7
movsd  %xmm5,-0x120(%rbp)
ff
unpcklpd %xmm5,%xmm5
mulpd  %xmm7,%xmm5
addpd  %xmm6,%xmm5
mulsd  %xmm8,%xmm1
mulpd  -0x180(%rbp),%xmm5
ff
mulpd  -0x170(%rbp),%xmm5
ff
divpd  -0x160(%rbp),%xmm5
ff
subsd  %xmm1,%xmm4
mov    0x10(%rbp),%rax
mov    -0xd8(%rbp),%rcx
movupd (%rax,%rcx,8),%xmm0
addpd  %xmm5,%xmm0
movupd %xmm0,(%rax,%rcx,8)
mulsd  -0x140(%rbp),%xmm4
ff
mulsd  -0x150(%rbp),%xmm4
ff
divsd  -0x190(%rbp),%xmm4
ff
addsd  0x10(%rax,%rcx,8),%xmm4
movsd  %xmm4,0x10(%rax,%rcx,8)
mov    -0xe0(%rbp),%rax
add    $0x1,%rax
cmp    -0xc8(%rbp),%rax
je     1751 <scf_gradient_helper+0x5f1>
lea    (%rax,%rax,2),%rcx
mov    -0xd0(%rbp),%rbx
movsd  (%rbx,%rcx,8),%xmm1
movsd  0x8(%rbx,%rcx,8),%xmm0
mulsd  %xmm0,%xmm0
mulsd  %xmm1,%xmm1
addsd  %xmm0,%xmm1
movsd  0x10(%rbx,%rcx,8),%xmm0
mulsd  %xmm0,%xmm0
addsd  %xmm1,%xmm0
ucomisd %xmm3,%xmm0
mov    %rax,-0xe0(%rbp)
jb     13f0 <scf_gradient_helper+0x290>
sqrtsd %xmm0,%xmm0
jmp    13fb <scf_gradient_helper+0x29b>
nopl   0x0(%rax,%rax,1)
mov    %rcx,%r14
call   1080 <sqrt@plt>
mov    %r14,%rcx
movsd  0x10(%rbx,%rcx,8),%xmm1
movsd  %xmm0,-0x60(%rbp)
divsd  %xmm0,%xmm1
movapd %xmm1,-0xa0(%rbp)
ff
movsd  (%rbx,%rcx,8),%xmm1
mov    %rcx,-0xd8(%rbp)
movsd  0x8(%rbx,%rcx,8),%xmm0
call   1030 <atan2@plt>
movapd %xmm0,%xmm2
movapd -0xa0(%rbp),%xmm1
ff
mulsd  %xmm1,%xmm1
movsd  0xbbf(%rip),%xmm0
subsd  %xmm1,%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
movsd  %xmm2,-0x30(%rbp)
jb     1460 <scf_gradient_helper+0x300>
sqrtsd %xmm0,%xmm0
jmp    146a <scf_gradient_helper+0x30a>
nopw   0x0(%rax,%rax,1)
call   1080 <sqrt@plt>
movsd  -0x30(%rbp),%xmm2
movapd %xmm0,-0x90(%rbp)
ff
movapd %xmm2,%xmm0
call   1070 <cos@plt>
movapd %xmm0,-0x1b0(%rbp)
ff
movsd  -0x30(%rbp),%xmm0
call   1050 <sin@plt>
movapd %xmm0,-0x1a0(%rbp)
ff
cmpl   $0x0,-0x68(%rbp)
mov    -0x38(%rbp),%rcx
xorpd  %xmm3,%xmm3
js     1570 <scf_gradient_helper+0x410>
je     1740 <scf_gradient_helper+0x5e0>
xor    %ebx,%ebx
mov    -0x40(%rbp),%r14
mov    -0xb0(%rbp),%r12
nopw   0x0(%rax,%rax,1)
xorps  %xmm0,%xmm0
cvtsi2sd %ebx,%xmm0
mulsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
call   1070 <cos@plt>
movsd  %xmm0,(%r14,%rbx,8)
movsd  -0x50(%rbp),%xmm0
call   1050 <sin@plt>
mov    -0x38(%rbp),%rax
movsd  %xmm0,(%rax,%rbx,8)
lea    0x1(%rbx),%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
mulsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
call   1070 <cos@plt>
movsd  %xmm0,0x8(%r14,%rbx,8)
movsd  -0x50(%rbp),%xmm0
call   1050 <sin@plt>
mov    -0x38(%rbp),%rcx
movsd  %xmm0,0x8(%rcx,%rbx,8)
add    $0x2,%rbx
cmp    %r12,%rbx
jne    14c0 <scf_gradient_helper+0x360>
xorpd  %xmm3,%xmm3
test   $0x1,%r15b
je     1570 <scf_gradient_helper+0x410>
xorps  %xmm1,%xmm1
cvtsi2sd %ebx,%xmm1
movsd  -0x30(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
call   1070 <cos@plt>
mov    -0x40(%rbp),%rax
movsd  %xmm0,(%rax,%rbx,8)
movsd  -0x50(%rbp),%xmm0
call   1050 <sin@plt>
xorpd  %xmm3,%xmm3
mov    -0x38(%rbp),%rcx
movsd  %xmm0,(%rcx,%rbx,8)
cmpl   $0x0,-0x80(%rbp)
js     12a0 <scf_gradient_helper+0x140>
movsd  -0x60(%rbp),%xmm0
divsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
mulsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x108(%rbp)
ff
xorpd  %xmm6,%xmm6
xorpd  %xmm5,%xmm5
mov    -0xc0(%rbp),%r12
mov    -0xb8(%rbp),%r14
xor    %eax,%eax
mov    %rax,-0x70(%rbp)
mov    -0x40(%rbp),%rax
jmp    15f4 <scf_gradient_helper+0x494>
nopl   0x0(%rax,%rax,1)
mov    -0x70(%rbp),%rsi
add    $0x1,%rsi
mov    -0x58(%rbp),%rdx
mov    -0xf0(%rbp),%r14
add    %rdx,%r14
mov    -0xf8(%rbp),%r12
add    %rdx,%r12
mov    %rsi,%rdx
mov    %rsi,-0x70(%rbp)
cmp    -0xe8(%rbp),%rsi
je     12a8 <scf_gradient_helper+0x148>
cmpl   $0x0,-0x68(%rbp)
mov    %r12,-0xf8(%rbp)
mov    %r14,-0xf0(%rbp)
js     15c0 <scf_gradient_helper+0x460>
xor    %r13d,%r13d
jmp    1626 <scf_gradient_helper+0x4c6>
nopl   (%rax)
add    $0x1,%r13
mov    -0x100(%rbp),%rdx
add    %rdx,%r14
add    %rdx,%r12
cmp    %r15,%r13
je     15c0 <scf_gradient_helper+0x460>
xor    %ebx,%ebx
jmp    1700 <scf_gradient_helper+0x5a0>
nopl   (%rax)
mulsd  %xmm2,%xmm0
mulsd  %xmm1,%xmm4
addsd  %xmm0,%xmm4
movapd %xmm4,-0x1c0(%rbp)
ff
movsd  -0x60(%rbp),%xmm0
movsd  %xmm1,-0x118(%rbp)
ff
movsd  -0x30(%rbp),%xmm1
movsd  %xmm2,-0x110(%rbp)
ff
movapd -0xa0(%rbp),%xmm2
ff
mov    -0x70(%rbp),%rdi
mov    %r13d,%esi
mov    %ebx,%edx
mov    -0x68(%rbp),%rcx
lea    -0x130(%rbp),%r8
mov    $0x3,%al
movapd %xmm5,-0x50(%rbp)
movapd %xmm6,-0x1d0(%rbp)
ff
call   1060 <sph_grad_phi_nlm@plt>
movapd -0x1d0(%rbp),%xmm6
ff
movapd -0x50(%rbp),%xmm5
xorpd  %xmm3,%xmm3
mov    -0x38(%rbp),%rcx
mov    -0x40(%rbp),%rax
movapd -0x1c0(%rbp),%xmm0
ff
unpcklpd %xmm0,%xmm0
mulpd  -0x130(%rbp),%xmm0
ff
movsd  -0x110(%rbp),%xmm1
ff
mulsd  (%r14,%rbx,8),%xmm1
addpd  %xmm0,%xmm6
movsd  -0x118(%rbp),%xmm0
ff
mulsd  (%r12,%rbx,8),%xmm0
subsd  %xmm1,%xmm0
mulsd  -0x120(%rbp),%xmm0
ff
divsd  -0x108(%rbp),%xmm0
ff
addsd  %xmm0,%xmm5
add    $0x1,%rbx
cmp    %rbx,%r15
je     1610 <scf_gradient_helper+0x4b0>
cmp    %r13,%rbx
ja     16f3 <scf_gradient_helper+0x593>
movsd  (%r14,%rbx,8),%xmm4
movsd  (%rax,%rbx,8),%xmm1
movsd  (%r12,%rbx,8),%xmm0
movsd  (%rcx,%rbx,8),%xmm2
ucomisd %xmm3,%xmm4
jne    1630 <scf_gradient_helper+0x4d0>
jp     1630 <scf_gradient_helper+0x4d0>
ucomisd %xmm3,%xmm0
jne    1630 <scf_gradient_helper+0x4d0>
jnp    16f3 <scf_gradient_helper+0x593>
jmp    1630 <scf_gradient_helper+0x4d0>
nopl   0x0(%rax)
xor    %ebx,%ebx
test   $0x1,%r15b
jne    1536 <scf_gradient_helper+0x3d6>
jmp    1570 <scf_gradient_helper+0x410>
mov    -0xa8(%rbp),%rsp
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @scf_gradient_helper(double* %0, i32 %1, double %2, double %3, double %4, double* %5, double* %6, i32 %7, i32 %8, double* %9) {
%11 = alloca double*
%12 = alloca i32
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double*
%17 = alloca double*
%18 = alloca i32
%19 = alloca i32
%20 = alloca double*
%21 = alloca i32
%22 = alloca i32
%23 = alloca i32
%24 = alloca i32
%25 = alloca i32
%26 = alloca i32
%27 = alloca double
%28 = alloca double
%29 = alloca double
%30 = alloca double
%31 = alloca double
%32 = alloca double
%33 = alloca double
%34 = alloca double
%35 = alloca [3 x double]
%36 = alloca i8*
%37 = alloca i64
%38 = alloca i64
%39 = alloca i64
store double* %0, double** %11
store i32 %1, i32* %12
store double %2, double* %13
store double %3, double* %14
store double %4, double* %15
store double* %5, double** %16
store double* %6, double** %17
store i32 %7, i32* %18
store i32 %8, i32* %19
store double* %9, double** %20
%40 = load i32, i32* %12
%41 = mul nsw i32 3, %40
%42 = zext i32 %41 to i64
%43 = call i8* @llvm.stacksave()
store i8* %43, i8** %36
%44 = alloca double, i64 %42
store i64 %42, i64* %37
%45 = load i32, i32* %19
%46 = add nsw i32 %45, 1
%47 = zext i32 %46 to i64
%48 = alloca double, i64 %47
store i64 %47, i64* %38
%49 = load i32, i32* %19
%50 = add nsw i32 %49, 1
%51 = zext i32 %50 to i64
%52 = alloca double, i64 %51
store i64 %51, i64* %39
%53 = bitcast double* %48 to i8*
%54 = load i32, i32* %19
%55 = add nsw i32 %54, 1
%56 = sext i32 %55 to i64
%57 = mul i64 %56, 8
%58 = bitcast double* %52 to i8*
%59 = load i32, i32* %19
%60 = add nsw i32 %59, 1
%61 = sext i32 %60 to i64
%62 = mul i64 %61, 8
store i32 0, i32* %23
br label %63
63: ; preds = %471, %10
%64 = load i32, i32* %23
%65 = load i32, i32* %12
%66 = icmp slt i32 %64, %65
br i1 %66, label %67, label %474
67: ; preds = %63
%68 = load i32, i32* %23
%69 = mul nsw i32 3, %68
store i32 %69, i32* %22
%70 = load double*, double** %11
%71 = load i32, i32* %22
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds double, double* %70, i64 %72
%74 = load double, double* %73
%75 = load double*, double** %11
%76 = load i32, i32* %22
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds double, double* %75, i64 %77
%79 = load double, double* %78
%80 = load double*, double** %11
%81 = load i32, i32* %22
%82 = add nsw i32 %81, 1
%83 = sext i32 %82 to i64
%84 = getelementptr inbounds double, double* %80, i64 %83
%85 = load double, double* %84
%86 = load double*, double** %11
%87 = load i32, i32* %22
%88 = add nsw i32 %87, 1
%89 = sext i32 %88 to i64
%90 = getelementptr inbounds double, double* %86, i64 %89
%91 = load double, double* %90
%92 = fmul double %85, %91
%93 = call double @llvm.fmuladd.f64(double %74, double %79, double %92)
%94 = load double*, double** %11
%95 = load i32, i32* %22
%96 = add nsw i32 %95, 2
%97 = sext i32 %96 to i64
%98 = getelementptr inbounds double, double* %94, i64 %97
%99 = load double, double* %98
%100 = load double*, double** %11
%101 = load i32, i32* %22
%102 = add nsw i32 %101, 2
%103 = sext i32 %102 to i64
%104 = getelementptr inbounds double, double* %100, i64 %103
%105 = load double, double* %104
%106 = call double @llvm.fmuladd.f64(double %99, double %105, double %93)
%107 = call double @sqrt(double %106)
store double %107, double* %27
%108 = load double, double* %27
%109 = load double, double* %15
%110 = fdiv double %108, %109
store double %110, double* %28
%111 = load double*, double** %11
%112 = load i32, i32* %22
%113 = add nsw i32 %112, 2
%114 = sext i32 %113 to i64
%115 = getelementptr inbounds double, double* %111, i64 %114
%116 = load double, double* %115
%117 = load double, double* %27
%118 = fdiv double %116, %117
store double %118, double* %29
%119 = load double*, double** %11
%120 = load i32, i32* %22
%121 = add nsw i32 %120, 1
%122 = sext i32 %121 to i64
%123 = getelementptr inbounds double, double* %119, i64 %122
%124 = load double, double* %123
%125 = load double*, double** %11
%126 = load i32, i32* %22
%127 = add nsw i32 %126, 0
%128 = sext i32 %127 to i64
%129 = getelementptr inbounds double, double* %125, i64 %128
%130 = load double, double* %129
%131 = call double @atan2(double %124, double %130)
store double %131, double* %30
%132 = load double, double* %29
%133 = load double, double* %29
%134 = fneg double %132
%135 = call double @llvm.fmuladd.f64(double %134, double %133, double 1.000000e+00)
%136 = call double @sqrt(double %135)
store double %136, double* %31
%137 = load double, double* %30
%138 = call double @cos(double %137)
store double %138, double* %32
%139 = load double, double* %30
%140 = call double @sin(double %139)
store double %140, double* %33
store i32 0, i32* %26
br label %141
141: ; preds = %163, %67
%142 = load i32, i32* %26
%143 = load i32, i32* %19
%144 = add nsw i32 %143, 1
%145 = icmp slt i32 %142, %144
br i1 %145, label %146, label %166
146: ; preds = %141
%147 = load i32, i32* %26
%148 = sitofp i32 %147 to double
%149 = load double, double* %30
%150 = fmul double %148, %149
%151 = call double @cos(double %150)
%152 = load i32, i32* %26
%153 = sext i32 %152 to i64
%154 = getelementptr inbounds double, double* %48, i64 %153
store double %151, double* %154
%155 = load i32, i32* %26
%156 = sitofp i32 %155 to double
%157 = load double, double* %30
%158 = fmul double %156, %157
%159 = call double @sin(double %158)
%160 = load i32, i32* %26
%161 = sext i32 %160 to i64
%162 = getelementptr inbounds double, double* %52, i64 %161
store double %159, double* %162
br label %163
163: ; preds = %146
%164 = load i32, i32* %26
%165 = add nsw i32 %164, 1
store i32 %165, i32* %26
br label %141
166: ; preds = %141
%167 = load i32, i32* %22
%168 = add nsw i32 %167, 0
%169 = sext i32 %168 to i64
%170 = getelementptr inbounds double, double* %44, i64 %169
store double 0.000000e+00, double* %170
%171 = load i32, i32* %22
%172 = add nsw i32 %171, 1
%173 = sext i32 %172 to i64
%174 = getelementptr inbounds double, double* %44, i64 %173
store double 0.000000e+00, double* %174
%175 = load i32, i32* %22
%176 = add nsw i32 %175, 2
%177 = sext i32 %176 to i64
%178 = getelementptr inbounds double, double* %44, i64 %177
store double 0.000000e+00, double* %178
store i32 0, i32* %24
br label %179
179: ; preds = %320, %166
%180 = load i32, i32* %24
%181 = load i32, i32* %18
%182 = add nsw i32 %181, 1
%183 = icmp slt i32 %180, %182
br i1 %183, label %184, label %323
184: ; preds = %179
store i32 0, i32* %25
br label %185
185: ; preds = %316, %184
%186 = load i32, i32* %25
%187 = load i32, i32* %19
%188 = add nsw i32 %187, 1
%189 = icmp slt i32 %186, %188
br i1 %189, label %190, label %319
190: ; preds = %185
store i32 0, i32* %26
br label %191
191: ; preds = %312, %190
%192 = load i32, i32* %26
%193 = load i32, i32* %19
%194 = add nsw i32 %193, 1
%195 = icmp slt i32 %192, %194
br i1 %195, label %196, label %315
196: ; preds = %191
%197 = load i32, i32* %26
%198 = load i32, i32* %25
%199 = icmp sgt i32 %197, %198
br i1 %199, label %200, label %201
200: ; preds = %196
br label %312
201: ; preds = %196
%202 = load i32, i32* %26
%203 = load i32, i32* %19
%204 = add nsw i32 %203, 1
%205 = load i32, i32* %25
%206 = load i32, i32* %19
%207 = add nsw i32 %206, 1
%208 = load i32, i32* %24
%209 = mul nsw i32 %207, %208
%210 = add nsw i32 %205, %209
%211 = mul nsw i32 %204, %210
%212 = add nsw i32 %202, %211
store i32 %212, i32* %21
%213 = load double*, double** %16
%214 = load i32, i32* %21
%215 = sext i32 %214 to i64
%216 = getelementptr inbounds double, double* %213, i64 %215
%217 = load double, double* %216
%218 = load i32, i32* %26
%219 = sext i32 %218 to i64
%220 = getelementptr inbounds double, double* %48, i64 %219
%221 = load double, double* %220
%222 = load double*, double** %17
%223 = load i32, i32* %21
%224 = sext i32 %223 to i64
%225 = getelementptr inbounds double, double* %222, i64 %224
%226 = load double, double* %225
%227 = load i32, i32* %26
%228 = sext i32 %227 to i64
%229 = getelementptr inbounds double, double* %52, i64 %228
%230 = load double, double* %229
%231 = fmul double %226, %230
%232 = call double @llvm.fmuladd.f64(double %217, double %221, double %231)
store double %232, double* %34
%233 = load double*, double** %16
%234 = load i32, i32* %21
%235 = sext i32 %234 to i64
%236 = getelementptr inbounds double, double* %233, i64 %235
%237 = load double, double* %236
%238 = fcmp oeq double %237, 0.000000e+00
%239 = zext i1 %238 to i32
%240 = load double*, double** %17
%241 = load i32, i32* %21
%242 = sext i32 %241 to i64
%243 = getelementptr inbounds double, double* %240, i64 %242
%244 = load double, double* %243
%245 = fcmp oeq double %244, 0.000000e+00
%246 = zext i1 %245 to i32
%247 = and i32 %239, %246
%248 = icmp ne i32 %247, 0
br i1 %248, label %249, label %250
249: ; preds = %201
br label %312
250: ; preds = %201
%251 = load double, double* %28
%252 = load double, double* %30
%253 = load double, double* %29
%254 = load i32, i32* %24
%255 = load i32, i32* %25
%256 = load i32, i32* %26
%257 = load i32, i32* %19
%258 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 0
%259 = call i32 (double, double, double, i32, i32, i32, i32, double*, ...) bitcast (i32 (...)* @sph_grad_phi_nlm to i32 (double, double, double, i32, i32, i32, i32, double*, ...)*)(double %251, double %252, double %253, i32 %254, i32 %255, i32 %256, i32 %257, double* %258)
%260 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 0
%261 = load double, double* %260
%262 = load double, double* %34
%263 = load i32, i32* %22
%264 = add nsw i32 %263, 0
%265 = sext i32 %264 to i64
%266 = getelementptr inbounds double, double* %44, i64 %265
%267 = load double, double* %266
%268 = call double @llvm.fmuladd.f64(double %261, double %262, double %267)
store double %268, double* %266
%269 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 1
%270 = load double, double* %269
%271 = load double, double* %34
%272 = load i32, i32* %22
%273 = add nsw i32 %272, 1
%274 = sext i32 %273 to i64
%275 = getelementptr inbounds double, double* %44, i64 %274
%276 = load double, double* %275
%277 = call double @llvm.fmuladd.f64(double %270, double %271, double %276)
store double %277, double* %275
%278 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 2
%279 = load double, double* %278
%280 = load double*, double** %17
%281 = load i32, i32* %21
%282 = sext i32 %281 to i64
%283 = getelementptr inbounds double, double* %280, i64 %282
%284 = load double, double* %283
%285 = load i32, i32* %26
%286 = sext i32 %285 to i64
%287 = getelementptr inbounds double, double* %48, i64 %286
%288 = load double, double* %287
%289 = load double*, double** %16
%290 = load i32, i32* %21
%291 = sext i32 %290 to i64
%292 = getelementptr inbounds double, double* %289, i64 %291
%293 = load double, double* %292
%294 = load i32, i32* %26
%295 = sext i32 %294 to i64
%296 = getelementptr inbounds double, double* %52, i64 %295
%297 = load double, double* %296
%298 = fmul double %293, %297
%299 = fneg double %298
%300 = call double @llvm.fmuladd.f64(double %284, double %288, double %299)
%301 = fmul double %279, %300
%302 = load double, double* %28
%303 = load double, double* %31
%304 = fmul double %302, %303
%305 = fdiv double %301, %304
%306 = load i32, i32* %22
%307 = add nsw i32 %306, 2
%308 = sext i32 %307 to i64
%309 = getelementptr inbounds double, double* %44, i64 %308
%310 = load double, double* %309
%311 = fadd double %310, %305
store double %311, double* %309
br label %312
312: ; preds = %250, %249, %200
%313 = load i32, i32* %26
%314 = add nsw i32 %313, 1
store i32 %314, i32* %26
br label %191
315: ; preds = %191
br label %316
316: ; preds = %315
%317 = load i32, i32* %25
%318 = add nsw i32 %317, 1
store i32 %318, i32* %25
br label %185
319: ; preds = %185
br label %320
320: ; preds = %319
%321 = load i32, i32* %24
%322 = add nsw i32 %321, 1
store i32 %322, i32* %24
br label %179
323: ; preds = %179
%324 = load i32, i32* %22
%325 = add nsw i32 %324, 0
%326 = sext i32 %325 to i64
%327 = getelementptr inbounds double, double* %44, i64 %326
%328 = load double, double* %327
%329 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 0
store double %328, double* %329
%330 = load i32, i32* %22
%331 = add nsw i32 %330, 1
%332 = sext i32 %331 to i64
%333 = getelementptr inbounds double, double* %44, i64 %332
%334 = load double, double* %333
%335 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 1
store double %334, double* %335
%336 = load i32, i32* %22
%337 = add nsw i32 %336, 2
%338 = sext i32 %337 to i64
%339 = getelementptr inbounds double, double* %44, i64 %338
%340 = load double, double* %339
%341 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 2
store double %340, double* %341
%342 = load double, double* %31
%343 = load double, double* %32
%344 = fmul double %342, %343
%345 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 0
%346 = load double, double* %345
%347 = load double, double* %29
%348 = load double, double* %32
%349 = fmul double %347, %348
%350 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 1
%351 = load double, double* %350
%352 = fmul double %349, %351
%353 = call double @llvm.fmuladd.f64(double %344, double %346, double %352)
%354 = load double, double* %33
%355 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 2
%356 = load double, double* %355
%357 = fneg double %354
%358 = call double @llvm.fmuladd.f64(double %357, double %356, double %353)
%359 = load i32, i32* %22
%360 = add nsw i32 %359, 0
%361 = sext i32 %360 to i64
%362 = getelementptr inbounds double, double* %44, i64 %361
store double %358, double* %362
%363 = load double, double* %31
%364 = load double, double* %33
%365 = fmul double %363, %364
%366 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 0
%367 = load double, double* %366
%368 = load double, double* %29
%369 = load double, double* %33
%370 = fmul double %368, %369
%371 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 1
%372 = load double, double* %371
%373 = fmul double %370, %372
%374 = call double @llvm.fmuladd.f64(double %365, double %367, double %373)
%375 = load double, double* %32
%376 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 2
%377 = load double, double* %376
%378 = call double @llvm.fmuladd.f64(double %375, double %377, double %374)
%379 = load i32, i32* %22
%380 = add nsw i32 %379, 1
%381 = sext i32 %380 to i64
%382 = getelementptr inbounds double, double* %44, i64 %381
store double %378, double* %382
%383 = load double, double* %29
%384 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 0
%385 = load double, double* %384
%386 = load double, double* %31
%387 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 1
%388 = load double, double* %387
%389 = fmul double %386, %388
%390 = fneg double %389
%391 = call double @llvm.fmuladd.f64(double %383, double %385, double %390)
%392 = load i32, i32* %22
%393 = add nsw i32 %392, 2
%394 = sext i32 %393 to i64
%395 = getelementptr inbounds double, double* %44, i64 %394
store double %391, double* %395
%396 = load double*, double** %20
%397 = load i32, i32* %22
%398 = add nsw i32 %397, 0
%399 = sext i32 %398 to i64
%400 = getelementptr inbounds double, double* %396, i64 %399
%401 = load double, double* %400
%402 = load i32, i32* %22
%403 = add nsw i32 %402, 0
%404 = sext i32 %403 to i64
%405 = getelementptr inbounds double, double* %44, i64 %404
%406 = load double, double* %405
%407 = load double, double* %13
%408 = fmul double %406, %407
%409 = load double, double* %14
%410 = fmul double %408, %409
%411 = load double, double* %15
%412 = load double, double* %15
%413 = fmul double %411, %412
%414 = fdiv double %410, %413
%415 = fadd double %401, %414
%416 = load double*, double** %20
%417 = load i32, i32* %22
%418 = add nsw i32 %417, 0
%419 = sext i32 %418 to i64
%420 = getelementptr inbounds double, double* %416, i64 %419
store double %415, double* %420
%421 = load double*, double** %20
%422 = load i32, i32* %22
%423 = add nsw i32 %422, 1
%424 = sext i32 %423 to i64
%425 = getelementptr inbounds double, double* %421, i64 %424
%426 = load double, double* %425
%427 = load i32, i32* %22
%428 = add nsw i32 %427, 1
%429 = sext i32 %428 to i64
%430 = getelementptr inbounds double, double* %44, i64 %429
%431 = load double, double* %430
%432 = load double, double* %13
%433 = fmul double %431, %432
%434 = load double, double* %14
%435 = fmul double %433, %434
%436 = load double, double* %15
%437 = load double, double* %15
%438 = fmul double %436, %437
%439 = fdiv double %435, %438
%440 = fadd double %426, %439
%441 = load double*, double** %20
%442 = load i32, i32* %22
%443 = add nsw i32 %442, 1
%444 = sext i32 %443 to i64
%445 = getelementptr inbounds double, double* %441, i64 %444
store double %440, double* %445
%446 = load double*, double** %20
%447 = load i32, i32* %22
%448 = add nsw i32 %447, 2
%449 = sext i32 %448 to i64
%450 = getelementptr inbounds double, double* %446, i64 %449
%451 = load double, double* %450
%452 = load i32, i32* %22
%453 = add nsw i32 %452, 2
%454 = sext i32 %453 to i64
%455 = getelementptr inbounds double, double* %44, i64 %454
%456 = load double, double* %455
%457 = load double, double* %13
%458 = fmul double %456, %457
%459 = load double, double* %14
%460 = fmul double %458, %459
%461 = load double, double* %15
%462 = load double, double* %15
%463 = fmul double %461, %462
%464 = fdiv double %460, %463
%465 = fadd double %451, %464
%466 = load double*, double** %20
%467 = load i32, i32* %22
%468 = add nsw i32 %467, 2
%469 = sext i32 %468 to i64
%470 = getelementptr inbounds double, double* %466, i64 %469
store double %465, double* %470
br label %471
471: ; preds = %323
%472 = load i32, i32* %23
%473 = add nsw i32 %472, 1
store i32 %473, i32* %23
br label %63
474: ; preds = %63
%475 = load i8*, i8** %36
ret void
}

LLVM IR (-O2):
define void @scf_gradient_helper(double* nocapture %0, i32 %1, double %2, double %3, double %4, double* nocapture %5, double* nocapture %6, i32 %7, i32 %8, double* nocapture %9) {
%11 = alloca [3 x double]
%12 = bitcast [3 x double]* %11 to i8*
%13 = tail call i8* @llvm.stacksave()
%14 = add i32 %8, 1
%15 = zext i32 %14 to i64
%16 = alloca double, i64 %15
%17 = alloca double, i64 %15
%18 = bitcast double* %16 to i8*
%19 = sext i32 %14 to i64
%20 = shl nsw i64 %19, 3
%21 = bitcast double* %17 to i8*
%22 = icmp sgt i32 %1, 0
br i1 %22, label %23, label %210
23: ; preds = %10
%24 = icmp slt i32 %8, 0
%25 = icmp slt i32 %7, 0
%26 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%27 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 2
%28 = fmul double %4, %4
%29 = add i32 %7, 1
%30 = zext i32 %1 to i64
%31 = zext i32 %29 to i64
%32 = insertelement <2 x double> poison, double %2, i64 0
%33 = shufflevector <2 x double> %32, <2 x double> poison, <2 x i32> zeroinitializer
%34 = insertelement <2 x double> poison, double %3, i64 0
%35 = shufflevector <2 x double> %34, <2 x double> poison, <2 x i32> zeroinitializer
%36 = insertelement <2 x double> poison, double %28, i64 0
%37 = shufflevector <2 x double> %36, <2 x double> poison, <2 x i32> zeroinitializer
%38 = and i64 %15, 1
%39 = icmp eq i32 %8, 0
%40 = and i64 %15, 4294967294
%41 = icmp eq i64 %38, 0
%42 = bitcast [3 x double]* %11 to <2 x double>*
%43 = bitcast [3 x double]* %11 to <2 x double>*
br label %44
44: ; preds = %23, %168
%45 = phi i64 [ 0, %23 ], [ %208, %168 ]
%46 = mul nuw nsw i64 %45, 3
%47 = getelementptr inbounds double, double* %0, i64 %46
%48 = load double, double* %47
%49 = add nuw nsw i64 %46, 1
%50 = getelementptr inbounds double, double* %0, i64 %49
%51 = load double, double* %50
%52 = fmul double %51, %51
%53 = call double @llvm.fmuladd.f64(double %48, double %48, double %52)
%54 = add nuw nsw i64 %46, 2
%55 = getelementptr inbounds double, double* %0, i64 %54
%56 = load double, double* %55
%57 = call double @llvm.fmuladd.f64(double %56, double %56, double %53)
%58 = call double @sqrt(double %57)
%59 = fdiv double %58, %4
%60 = load double, double* %55
%61 = fdiv double %60, %58
%62 = load double, double* %50
%63 = load double, double* %47
%64 = call double @atan2(double %62, double %63)
%65 = fneg double %61
%66 = call double @llvm.fmuladd.f64(double %65, double %61, double 1.000000e+00)
%67 = call double @sqrt(double %66)
%68 = call double @cos(double %64)
%69 = call double @sin(double %64)
br i1 %24, label %102, label %70
70: ; preds = %44
br i1 %39, label %92, label %71
71: ; preds = %70, %71
%72 = phi i64 [ %89, %71 ], [ 0, %70 ]
%73 = phi i64 [ %90, %71 ], [ 0, %70 ]
%74 = trunc i64 %72 to i32
%75 = sitofp i32 %74 to double
%76 = fmul double %64, %75
%77 = call double @cos(double %76)
%78 = getelementptr inbounds double, double* %16, i64 %72
store double %77, double* %78
%79 = call double @sin(double %76)
%80 = getelementptr inbounds double, double* %17, i64 %72
store double %79, double* %80
%81 = or i64 %72, 1
%82 = trunc i64 %81 to i32
%83 = sitofp i32 %82 to double
%84 = fmul double %64, %83
%85 = call double @cos(double %84)
%86 = getelementptr inbounds double, double* %16, i64 %81
store double %85, double* %86
%87 = call double @sin(double %84)
%88 = getelementptr inbounds double, double* %17, i64 %81
store double %87, double* %88
%89 = add nuw nsw i64 %72, 2
%90 = add i64 %73, 2
%91 = icmp eq i64 %90, %40
br i1 %91, label %92, label %71
92: ; preds = %71, %70
%93 = phi i64 [ 0, %70 ], [ %89, %71 ]
br i1 %41, label %102, label %94
94: ; preds = %92
%95 = trunc i64 %93 to i32
%96 = sitofp i32 %95 to double
%97 = fmul double %64, %96
%98 = call double @cos(double %97)
%99 = getelementptr inbounds double, double* %16, i64 %93
store double %98, double* %99
%100 = call double @sin(double %97)
%101 = getelementptr inbounds double, double* %17, i64 %93
store double %100, double* %101
br label %102
102: ; preds = %94, %92, %44
br i1 %25, label %168, label %103
103: ; preds = %102
%104 = fmul double %59, %67
br label %105
105: ; preds = %103, %163
%106 = phi double [ 0.000000e+00, %103 ], [ %164, %163 ]
%107 = phi i64 [ 0, %103 ], [ %166, %163 ]
%108 = phi <2 x double> [ zeroinitializer, %103 ], [ %165, %163 ]
br i1 %24, label %163, label %109
109: ; preds = %105
%110 = mul nsw i64 %107, %19
%111 = trunc i64 %107 to i32
br label %112
112: ; preds = %160, %109
%113 = phi double [ %106, %109 ], [ %156, %160 ]
%114 = phi i64 [ 0, %109 ], [ %161, %160 ]
%115 = phi <2 x double> [ %108, %109 ], [ %157, %160 ]
%116 = add nsw i64 %114, %110
%117 = mul nsw i64 %116, %19
%118 = trunc i64 %114 to i32
br label %119
119: ; preds = %112, %155
%120 = phi double [ %113, %112 ], [ %156, %155 ]
%121 = phi i64 [ 0, %112 ], [ %158, %155 ]
%122 = phi <2 x double> [ %115, %112 ], [ %157, %155 ]
%123 = icmp ugt i64 %121, %114
br i1 %123, label %155, label %124
124: ; preds = %119
%125 = add nsw i64 %121, %117
%126 = getelementptr inbounds double, double* %5, i64 %125
%127 = load double, double* %126
%128 = getelementptr inbounds double, double* %16, i64 %121
%129 = load double, double* %128
%130 = getelementptr inbounds double, double* %6, i64 %125
%131 = load double, double* %130
%132 = getelementptr inbounds double, double* %17, i64 %121
%133 = load double, double* %132
%134 = fcmp oeq double %127, 0.000000e+00
%135 = fcmp oeq double %131, 0.000000e+00
%136 = and i1 %134, %135
br i1 %136, label %155, label %137
137: ; preds = %124
%138 = fmul double %131, %133
%139 = call double @llvm.fmuladd.f64(double %127, double %129, double %138)
%140 = trunc i64 %121 to i32
%141 = call i32 (double, double, double, i32, i32, i32, i32, double*, ...) bitcast (i32 (...)* @sph_grad_phi_nlm to i32 (double, double, double, i32, i32, i32, i32, double*, ...)*)(double %59, double %64, double %61, i32 %111, i32 %118, i32 %140, i32 %8, double* %26)
%142 = load <2 x double>, <2 x double>* %42
%143 = insertelement <2 x double> poison, double %139, i64 0
%144 = shufflevector <2 x double> %143, <2 x double> poison, <2 x i32> zeroinitializer
%145 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %142, <2 x double> %144, <2 x double> %122)
%146 = load double, double* %27
%147 = load double, double* %130
%148 = load double, double* %126
%149 = fneg double %148
%150 = fmul double %133, %149
%151 = call double @llvm.fmuladd.f64(double %147, double %129, double %150)
%152 = fmul double %146, %151
%153 = fdiv double %152, %104
%154 = fadd double %120, %153
br label %155
155: ; preds = %124, %119, %137
%156 = phi double [ %120, %124 ], [ %120, %119 ], [ %154, %137 ]
%157 = phi <2 x double> [ %122, %124 ], [ %122, %119 ], [ %145, %137 ]
%158 = add nuw nsw i64 %121, 1
%159 = icmp eq i64 %158, %15
br i1 %159, label %160, label %119
160: ; preds = %155
%161 = add nuw nsw i64 %114, 1
%162 = icmp eq i64 %161, %15
br i1 %162, label %163, label %112
163: ; preds = %160, %105
%164 = phi double [ %106, %105 ], [ %156, %160 ]
%165 = phi <2 x double> [ %108, %105 ], [ %157, %160 ]
%166 = add nuw nsw i64 %107, 1
%167 = icmp eq i64 %166, %31
br i1 %167, label %168, label %105
168: ; preds = %163, %102
%169 = phi double [ 0.000000e+00, %102 ], [ %164, %163 ]
%170 = phi <2 x double> [ zeroinitializer, %102 ], [ %165, %163 ]
store <2 x double> %170, <2 x double>* %43
store double %169, double* %27
%171 = extractelement <2 x double> %170, i64 1
%172 = extractelement <2 x double> %170, i64 0
%173 = fneg double %69
%174 = insertelement <2 x double> poison, double %67, i64 0
%175 = shufflevector <2 x double> %174, <2 x double> poison, <2 x i32> zeroinitializer
%176 = insertelement <2 x double> poison, double %68, i64 0
%177 = insertelement <2 x double> %176, double %69, i64 1
%178 = fmul <2 x double> %175, %177
%179 = insertelement <2 x double> poison, double %61, i64 0
%180 = shufflevector <2 x double> %179, <2 x double> poison, <2 x i32> zeroinitializer
%181 = fmul <2 x double> %180, %177
%182 = shufflevector <2 x double> %170, <2 x double> undef, <2 x i32> <i32 1, i32 1>
%183 = fmul <2 x double> %181, %182
%184 = shufflevector <2 x double> %170, <2 x double> undef, <2 x i32> zeroinitializer
%185 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %178, <2 x double> %184, <2 x double> %183)
%186 = insertelement <2 x double> poison, double %173, i64 0
%187 = insertelement <2 x double> %186, double %68, i64 1
%188 = insertelement <2 x double> poison, double %169, i64 0
%189 = shufflevector <2 x double> %188, <2 x double> poison, <2 x i32> zeroinitializer
%190 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %187, <2 x double> %189, <2 x double> %185)
%191 = fneg double %67
%192 = fmul double %171, %191
%193 = call double @llvm.fmuladd.f64(double %61, double %172, double %192)
%194 = getelementptr inbounds double, double* %9, i64 %46
%195 = bitcast double* %194 to <2 x double>*
%196 = load <2 x double>, <2 x double>* %195
%197 = fmul <2 x double> %190, %33
%198 = fmul <2 x double> %197, %35
%199 = fdiv <2 x double> %198, %37
%200 = fadd <2 x double> %199, %196
%201 = bitcast double* %194 to <2 x double>*
store <2 x double> %200, <2 x double>* %201
%202 = getelementptr inbounds double, double* %9, i64 %54
%203 = load double, double* %202
%204 = fmul double %193, %2
%205 = fmul double %204, %3
%206 = fdiv double %205, %28
%207 = fadd double %206, %203
store double %207, double* %202
%208 = add nuw nsw i64 %45, 1
%209 = icmp eq i64 %208, %30
br i1 %209, label %210, label %44
210: ; preds = %168, %10
ret void
}