#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 */
scalar_t__ double_equal(double, double);
int /*<<< orphan*/ error(char *);
double exp(double);
double fabs(double);
double log(double);
double log10(double);
double log_gamma_lanczos(double);
double log_gamma_windschitl(double);
double pow(double, double);
double nfa(int n, int k, double p, double logNT) {
  static double inv[100000];
  double tolerance = 0.1;
  double log1term, term, bin_term, mult_term, bin_tail, err, p_term;
  int i;
  if (n < 0 || k < 0 || k > n || p <= 0.0 || p >= 1.0)
    error("nfa: wrong n, k or p values.");
  if (n == 0 || k == 0)
    return -logNT;
  if (n == k)
    return -logNT - (double)n * log10(p);
  p_term = p / (1.0 - p);
  log1term = (((double)n + 1.0) > 15.0 ? log_gamma_windschitl((double)n + 1.0)
                                       : log_gamma_lanczos((double)n + 1.0)) -
             (((double)k + 1.0) > 15.0 ? log_gamma_windschitl((double)k + 1.0)
                                       : log_gamma_lanczos((double)k + 1.0)) -
             (((double)(n - k) + 1.0) > 15.0
                  ? log_gamma_windschitl((double)(n - k) + 1.0)
                  : log_gamma_lanczos((double)(n - k) + 1.0)) +
             (double)k * log(p) + (double)(n - k) * log(1.0 - p);
  term = exp(log1term);
  if (double_equal(term, 0.0)) {
    if ((double)k > (double)n * p)
      return -log1term / 2.30258509299404568402 - logNT;
    else
      return -logNT;
  }
  bin_tail = term;
  for (i = k + 1; i <= n; i++) {
    bin_term =
        (double)(n - i + 1) *
        (i < 100000 ? (inv[i] != 0.0 ? inv[i] : (inv[i] = 1.0 / (double)i))
                    : 1.0 / (double)i);
    mult_term = bin_term * p_term;
    term *= mult_term;
    bin_tail += term;
    if (bin_term < 1.0) {
      err = term *
            ((1.0 - pow(mult_term, (double)(n - i + 1))) / (1.0 - mult_term) -
             1.0);
      if (err < tolerance * fabs(-log10(bin_tail) - logNT) * bin_tail)
        break;
    }
  }
  return -log10(bin_tail) - logNT;
}


x86 assembly (clang, -O0):
<nfa>:
push   %rbp
mov    %rsp,%rbp
sub    $0xf0,%rsp
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
movsd  0xe5d(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
cmpl   $0x0,-0xc(%rbp)
jl     11ed <nfa+0x6d>
cmpl   $0x0,-0x10(%rbp)
jl     11ed <nfa+0x6d>
mov    -0x10(%rbp),%eax
cmp    -0xc(%rbp),%eax
jg     11ed <nfa+0x6d>
xorps  %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
jae    11ed <nfa+0x6d>
movsd  -0x18(%rbp),%xmm0
movsd  0xe25(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     11f9 <nfa+0x79>
lea    0xe3c(%rip),%rdi
call   1070 <error@plt>
cmpl   $0x0,-0xc(%rbp)
je     120d <nfa+0x8d>
cmpl   $0x0,-0x10(%rbp)
jne    1233 <nfa+0xb3>
movsd  -0x20(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    17a9 <nfa+0x629>
mov    -0xc(%rbp),%eax
cmp    -0x10(%rbp),%eax
jne    12aa <nfa+0x12a>
movsd  -0x20(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x78(%rbp)
cvtsi2sdl -0xc(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x18(%rbp),%xmm0
call   10a0 <log10@plt>
movsd  -0x78(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x70(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    17a9 <nfa+0x629>
movsd  -0x18(%rbp),%xmm0
movsd  0xd51(%rip),%xmm1
subsd  -0x18(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
cvtsi2sdl -0xc(%rbp),%xmm0
movsd  0xd36(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  0xd32(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1308 <nfa+0x188>
cvtsi2sdl -0xc(%rbp),%xmm0
movsd  0xd13(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1040 <log_gamma_windschitl@plt>
movsd  %xmm0,-0x80(%rbp)
jmp    1323 <nfa+0x1a3>
cvtsi2sdl -0xc(%rbp),%xmm0
movsd  0xcf3(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1030 <log_gamma_lanczos@plt>
movsd  %xmm0,-0x80(%rbp)
movsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
cvtsi2sdl -0x10(%rbp),%xmm0
movsd  0xccb(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  0xcc7(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1376 <nfa+0x1f6>
cvtsi2sdl -0x10(%rbp),%xmm0
movsd  0xca8(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1040 <log_gamma_windschitl@plt>
movsd  %xmm0,-0x90(%rbp)
ff
jmp    1394 <nfa+0x214>
cvtsi2sdl -0x10(%rbp),%xmm0
movsd  0xc85(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1030 <log_gamma_lanczos@plt>
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x88(%rbp),%xmm0
ff
movsd  -0x90(%rbp),%xmm1
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
mov    -0xc(%rbp),%eax
sub    -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  0xc46(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  0xc42(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1400 <nfa+0x280>
mov    -0xc(%rbp),%eax
sub    -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  0xc1e(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1040 <log_gamma_windschitl@plt>
movsd  %xmm0,-0xa0(%rbp)
ff
jmp    1423 <nfa+0x2a3>
mov    -0xc(%rbp),%eax
sub    -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  0xbf6(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1030 <log_gamma_lanczos@plt>
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  -0x98(%rbp),%xmm0
ff
movsd  -0xa0(%rbp),%xmm1
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xc0(%rbp)
ff
cvtsi2sdl -0x10(%rbp),%xmm0
movsd  %xmm0,-0xb8(%rbp)
ff
movsd  -0x18(%rbp),%xmm0
call   1080 <log@plt>
movsd  -0xc0(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0xb8(%rbp),%xmm0
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
mov    -0xc(%rbp),%eax
sub    -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  0xb75(%rip),%xmm0
subsd  -0x18(%rbp),%xmm0
call   1080 <log@plt>
movsd  -0xb0(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0xa8(%rbp),%xmm0
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
call   1060 <exp@plt>
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
xorps  %xmm1,%xmm1
call   1050 <double_equal@plt>
cmp    $0x0,%rax
je     1559 <nfa+0x3d9>
cvtsi2sdl -0x10(%rbp),%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
ucomisd %xmm1,%xmm0
jbe    1533 <nfa+0x3b3>
movsd  -0x30(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xaf8(%rip),%xmm1
divsd  %xmm1,%xmm0
subsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    17a9 <nfa+0x629>
movsd  -0x20(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    17a9 <nfa+0x629>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
mov    -0x64(%rbp),%eax
cmp    -0xc(%rbp),%eax
jg     177e <nfa+0x5fe>
mov    -0xc(%rbp),%eax
sub    -0x64(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0xc8(%rbp)
ff
cmpl   $0x186a0,-0x64(%rbp)
jge    161d <nfa+0x49d>
movslq -0x64(%rbp),%rcx
lea    0x2acb(%rip),%rax
movsd  (%rax,%rcx,8),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    15c2 <nfa+0x442>
jp     15c2 <nfa+0x442>
jmp    15df <nfa+0x45f>
movslq -0x64(%rbp),%rcx
lea    0x2aa3(%rip),%rax
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0xd0(%rbp)
ff
jmp    1608 <nfa+0x488>
cvtsi2sdl -0x64(%rbp),%xmm1
movsd  0xa1c(%rip),%xmm0
divsd  %xmm1,%xmm0
movslq -0x64(%rbp),%rcx
lea    0x2a75(%rip),%rax
movsd  %xmm0,(%rax,%rcx,8)
movsd  %xmm0,-0xd0(%rbp)
ff
movsd  -0xd0(%rbp),%xmm0
ff
movsd  %xmm0,-0xd8(%rbp)
ff
jmp    1636 <nfa+0x4b6>
cvtsi2sdl -0x64(%rbp),%xmm1
movsd  0x9de(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0xd8(%rbp)
ff
movsd  -0xc8(%rbp),%xmm0
ff
movsd  -0xd8(%rbp),%xmm1
ff
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
mulsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
addsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  0x984(%rip),%xmm0
ucomisd -0x40(%rbp),%xmm0
jbe    176b <nfa+0x5eb>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0xf0(%rbp)
ff
movsd  -0x48(%rbp),%xmm0
mov    -0xc(%rbp),%eax
sub    -0x64(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %eax,%xmm1
call   1090 <pow@plt>
movaps %xmm0,%xmm2
movsd  -0xf0(%rbp),%xmm0
ff
movsd  0x942(%rip),%xmm1
subsd  %xmm2,%xmm1
movsd  0x936(%rip),%xmm2
subsd  -0x48(%rbp),%xmm2
divsd  %xmm2,%xmm1
movsd  0x925(%rip),%xmm2
subsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0xe8(%rbp)
ff
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0xe0(%rbp)
ff
movsd  -0x50(%rbp),%xmm0
call   10a0 <log10@plt>
movsd  -0xe8(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0xe0(%rbp),%xmm0
ff
movq   %xmm2,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm2
subsd  -0x20(%rbp),%xmm2
movaps 0x8d6(%rip),%xmm3
pand   %xmm3,%xmm2
mulsd  %xmm2,%xmm0
mulsd  -0x50(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1766 <nfa+0x5e6>
jmp    177e <nfa+0x5fe>
jmp    176b <nfa+0x5eb>
jmp    1770 <nfa+0x5f0>
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    156c <nfa+0x3ec>
movsd  -0x50(%rbp),%xmm0
call   10a0 <log10@plt>
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
subsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0xf0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<nfa>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x50,%rsp
movapd %xmm1,0x30(%rsp)
mov    %esi,%r15d
mov    %edi,%r14d
mov    %esi,%eax
or     %edi,%eax
movsd  %xmm0,0x10(%rsp)
js     11c7 <nfa+0x47>
ucomisd 0xe54(%rip),%xmm0
jae    11c7 <nfa+0x47>
cmp    %r15d,%r14d
jl     11c7 <nfa+0x47>
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jae    11c7 <nfa+0x47>
test   %r14d,%r14d
jne    11e2 <nfa+0x62>
jmp    135d <nfa+0x1dd>
lea    0xe82(%rip),%rdi
call   1070 <error@plt>
movsd  0x10(%rsp),%xmm0
test   %r14d,%r14d
je     135d <nfa+0x1dd>
test   %r15d,%r15d
je     135d <nfa+0x1dd>
mov    %r14d,%ebx
sub    %r15d,%ebx
jne    121b <nfa+0x9b>
xorps  %xmm1,%xmm1
cvtsi2sd %r15d,%xmm1
movapd %xmm1,(%rsp)
call   10a0 <log10@plt>
movapd (%rsp),%xmm1
xorpd  0xe1e(%rip),%xmm1
mulsd  %xmm1,%xmm0
jmp    14f4 <nfa+0x374>
xorps  %xmm0,%xmm0
cvtsi2sd %r14d,%xmm0
movsd  %xmm0,0x48(%rsp)
addsd  0xdcf(%rip),%xmm0
ucomisd 0xdcf(%rip),%xmm0
jbe    1242 <nfa+0xc2>
call   1040 <log_gamma_windschitl@plt>
jmp    1247 <nfa+0xc7>
call   1030 <log_gamma_lanczos@plt>
movsd  %xmm0,(%rsp)
xorps  %xmm1,%xmm1
cvtsi2sd %r15d,%xmm1
movsd  0xda4(%rip),%xmm0
movsd  %xmm1,0x18(%rsp)
addsd  %xmm1,%xmm0
ucomisd 0xd9a(%rip),%xmm0
jbe    1277 <nfa+0xf7>
call   1040 <log_gamma_windschitl@plt>
jmp    127c <nfa+0xfc>
call   1030 <log_gamma_lanczos@plt>
movsd  (%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,(%rsp)
movsd  0xd6e(%rip),%xmm0
subsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x40(%rsp)
xorps  %xmm1,%xmm1
cvtsi2sd %ebx,%xmm1
movsd  0xd53(%rip),%xmm0
movapd %xmm1,0x20(%rsp)
addsd  %xmm1,%xmm0
ucomisd 0xd49(%rip),%xmm0
jbe    12c8 <nfa+0x148>
call   1040 <log_gamma_windschitl@plt>
jmp    12cd <nfa+0x14d>
call   1030 <log_gamma_lanczos@plt>
movsd  (%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,(%rsp)
movsd  0x10(%rsp),%xmm0
call   1080 <log@plt>
mulsd  0x18(%rsp),%xmm0
addsd  (%rsp),%xmm0
movsd  %xmm0,(%rsp)
movsd  0x40(%rsp),%xmm0
call   1080 <log@plt>
movapd 0x20(%rsp),%xmm1
mulsd  %xmm0,%xmm1
addsd  (%rsp),%xmm1
movapd %xmm1,0x20(%rsp)
movapd %xmm1,%xmm0
call   1060 <exp@plt>
xorpd  %xmm1,%xmm1
movsd  %xmm0,(%rsp)
call   1050 <double_equal@plt>
test   %rax,%rax
je     1370 <nfa+0x1f0>
movsd  0x48(%rsp),%xmm0
mulsd  0x10(%rsp),%xmm0
movsd  0x18(%rsp),%xmm1
ucomisd %xmm0,%xmm1
jbe    135d <nfa+0x1dd>
movapd 0x20(%rsp),%xmm0
divsd  0xcb8(%rip),%xmm0
jmp    14f4 <nfa+0x374>
movapd 0x30(%rsp),%xmm0
xorpd  0xcc5(%rip),%xmm0
jmp    14fa <nfa+0x37a>
movsd  (%rsp),%xmm0
mov    %r14d,%ebp
sub    %r15d,%ebp
jle    14e7 <nfa+0x367>
movsd  0x10(%rsp),%xmm2
divsd  0x40(%rsp),%xmm2
movslq %r15d,%rbx
movslq %r14d,%r14
add    $0x1,%r15d
lea    0x2cd2(%rip),%r12
movapd %xmm0,%xmm4
movapd %xmm0,%xmm5
movsd  0xc52(%rip),%xmm3
movsd  %xmm2,0x10(%rsp)
jmp    13d0 <nfa+0x250>
cs nopw 0x0(%rax,%rax,1)
cmp    %r14,%rbx
jge    14e3 <nfa+0x363>
add    $0xffffffff,%ebp
add    $0x1,%r15d
mov    %rbx,%rax
add    $0x1,%rbx
cmp    $0x1869e,%rax
jg     1410 <nfa+0x290>
movsd  (%r12,%rbx,8),%xmm6
ucomisd 0xc3b(%rip),%xmm6
jne    1420 <nfa+0x2a0>
jp     1420 <nfa+0x2a0>
xorps  %xmm1,%xmm1
cvtsi2sd %r15d,%xmm1
movapd %xmm3,%xmm6
divsd  %xmm1,%xmm6
movsd  %xmm6,(%r12,%rbx,8)
jmp    1420 <nfa+0x2a0>
nopl   0x0(%rax)
xorps  %xmm1,%xmm1
cvtsi2sd %r15d,%xmm1
movapd %xmm3,%xmm6
divsd  %xmm1,%xmm6
xorps  %xmm1,%xmm1
cvtsi2sd %ebp,%xmm1
mulsd  %xmm1,%xmm6
movapd %xmm2,%xmm0
mulsd  %xmm6,%xmm0
mulsd  %xmm0,%xmm4
addsd  %xmm4,%xmm5
ucomisd %xmm6,%xmm3
jbe    13c0 <nfa+0x240>
movsd  %xmm4,(%rsp)
movsd  %xmm5,0x20(%rsp)
movsd  %xmm0,0x18(%rsp)
call   1090 <pow@plt>
movsd  0xb9d(%rip),%xmm2
movapd %xmm2,%xmm1
subsd  %xmm0,%xmm1
movapd %xmm2,%xmm0
subsd  0x18(%rsp),%xmm0
divsd  %xmm0,%xmm1
addsd  0xb97(%rip),%xmm1
mulsd  (%rsp),%xmm1
movsd  %xmm1,0x18(%rsp)
movsd  0x20(%rsp),%xmm0
call   10a0 <log10@plt>
movsd  0x20(%rsp),%xmm5
xorpd  0xb8b(%rip),%xmm0
subsd  0x30(%rsp),%xmm0
andpd  0xb8d(%rip),%xmm0
mulsd  0xb65(%rip),%xmm0
mulsd  %xmm5,%xmm0
ucomisd 0x18(%rsp),%xmm0
ja     14e3 <nfa+0x363>
cmp    %r14,%rbx
movsd  0x10(%rsp),%xmm2
movsd  0xb28(%rip),%xmm3
movsd  (%rsp),%xmm4
jl     13c9 <nfa+0x249>
movapd %xmm5,%xmm0
call   10a0 <log10@plt>
xorpd  0xb3c(%rip),%xmm0
subsd  0x30(%rsp),%xmm0
add    $0x50,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
@nfa.inv = internal unnamed_addr global [100000 x double] zeroinitializer
@.str = [29 x i8] c"nfa: wrong n, k or p values.\00"
define double @nfa(i32 %0, i32 %1, double %2, double %3) {
%5 = or i32 %1, %0
%6 = icmp sgt i32 %5, -1
br i1 %6, label %7, label %13
7: ; preds = %4
%8 = icmp slt i32 %0, %1
%9 = fcmp ole double %2, 0.000000e+00
%10 = or i1 %8, %9
%11 = fcmp oge double %2, 1.000000e+00
%12 = or i1 %11, %10
br i1 %12, label %13, label %15
13: ; preds = %7, %4
%14 = tail call i32 @error(i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str, i64 0, i64 0))
br label %15
15: ; preds = %7, %13
%16 = icmp eq i32 %0, 0
%17 = icmp eq i32 %1, 0
%18 = or i1 %16, %17
br i1 %18, label %19, label %21
19: ; preds = %15
%20 = fneg double %3
br label %134
21: ; preds = %15
%22 = icmp eq i32 %0, %1
br i1 %22, label %23, label %29
23: ; preds = %21
%24 = fneg double %3
%25 = sitofp i32 %1 to double
%26 = tail call double @log10(double %2)
%27 = fneg double %25
%28 = tail call double @llvm.fmuladd.f64(double %27, double %26, double %24)
br label %134
29: ; preds = %21
%30 = fsub double 1.000000e+00, %2
%31 = fdiv double %2, %30
%32 = sitofp i32 %0 to double
%33 = fadd double %32, 1.000000e+00
%34 = fcmp ogt double %33, 1.500000e+01
br i1 %34, label %35, label %37
35: ; preds = %29
%36 = tail call double @log_gamma_windschitl(double %33)
br label %39
37: ; preds = %29
%38 = tail call double @log_gamma_lanczos(double %33)
br label %39
39: ; preds = %37, %35
%40 = phi double [ %36, %35 ], [ %38, %37 ]
%41 = sitofp i32 %1 to double
%42 = fadd double %41, 1.000000e+00
%43 = fcmp ogt double %42, 1.500000e+01
br i1 %43, label %44, label %46
44: ; preds = %39
%45 = tail call double @log_gamma_windschitl(double %42)
br label %48
46: ; preds = %39
%47 = tail call double @log_gamma_lanczos(double %42)
br label %48
48: ; preds = %46, %44
%49 = phi double [ %45, %44 ], [ %47, %46 ]
%50 = fsub double %40, %49
%51 = sub nsw i32 %0, %1
%52 = sitofp i32 %51 to double
%53 = fadd double %52, 1.000000e+00
%54 = fcmp ogt double %53, 1.500000e+01
br i1 %54, label %55, label %57
55: ; preds = %48
%56 = tail call double @log_gamma_windschitl(double %53)
br label %59
57: ; preds = %48
%58 = tail call double @log_gamma_lanczos(double %53)
br label %59
59: ; preds = %57, %55
%60 = phi double [ %56, %55 ], [ %58, %57 ]
%61 = fsub double %50, %60
%62 = tail call double @log(double %2)
%63 = tail call double @llvm.fmuladd.f64(double %41, double %62, double %61)
%64 = tail call double @log(double %30)
%65 = tail call double @llvm.fmuladd.f64(double %52, double %64, double %63)
%66 = tail call double @exp(double %65)
%67 = tail call i64 @double_equal(double %66, double 0.000000e+00)
%68 = icmp eq i64 %67, 0
br i1 %68, label %69, label %74
69: ; preds = %59
%70 = icmp sgt i32 %0, %1
br i1 %70, label %71, label %129
71: ; preds = %69
%72 = sext i32 %1 to i64
%73 = sext i32 %0 to i64
br label %82
74: ; preds = %59
%75 = fmul double %32, %2
%76 = fcmp olt double %75, %41
br i1 %76, label %77, label %80
77: ; preds = %74
%78 = fdiv double %65, 0xC0026BB1BBB55516
%79 = fsub double %78, %3
br label %134
80: ; preds = %74
%81 = fneg double %3
br label %134
82: ; preds = %128, %71
%83 = phi i64 [ %72, %71 ], [ %86, %128 ]
%84 = phi double [ %66, %71 ], [ %107, %128 ]
%85 = phi double [ %66, %71 ], [ %108, %128 ]
%86 = add i64 %83, 1
%87 = trunc i64 %83 to i32
%88 = sub i32 %0, %87
%89 = sitofp i32 %88 to double
%90 = icmp slt i64 %83, 99999
br i1 %90, label %91, label %99
91: ; preds = %82
%92 = getelementptr inbounds [100000 x double], [100000 x double]* @nfa.inv, i64 0, i64 %86
%93 = load double, double* %92
%94 = fcmp une double %93, 0.000000e+00
br i1 %94, label %103, label %95
95: ; preds = %91
%96 = trunc i64 %86 to i32
%97 = sitofp i32 %96 to double
%98 = fdiv double 1.000000e+00, %97
store double %98, double* %92
br label %103
99: ; preds = %82
%100 = trunc i64 %86 to i32
%101 = sitofp i32 %100 to double
%102 = fdiv double 1.000000e+00, %101
br label %103
103: ; preds = %91, %95, %99
%104 = phi double [ %102, %99 ], [ %98, %95 ], [ %93, %91 ]
%105 = fmul double %104, %89
%106 = fmul double %31, %105
%107 = fmul double %84, %106
%108 = fadd double %85, %107
%109 = fcmp olt double %105, 1.000000e+00
br i1 %109, label %110, label %126
110: ; preds = %103
%111 = tail call double @pow(double %106, double %89)
%112 = fsub double 1.000000e+00, %111
%113 = fsub double 1.000000e+00, %106
%114 = fdiv double %112, %113
%115 = fadd double %114, -1.000000e+00
%116 = fmul double %107, %115
%117 = tail call double @log10(double %108)
%118 = fneg double %117
%119 = fsub double %118, %3
%120 = tail call double @llvm.fabs.f64(double %119)
%121 = fmul double %120, 1.000000e-01
%122 = fmul double %108, %121
%123 = fcmp uge double %116, %122
%124 = icmp slt i64 %86, %73
%125 = select i1 %123, i1 %124, i1 false
br i1 %125, label %128, label %129
126: ; preds = %103
%127 = icmp slt i64 %86, %73
br i1 %127, label %128, label %129
128: ; preds = %126, %110
br label %82
129: ; preds = %126, %110, %69
%130 = phi double [ %66, %69 ], [ %108, %110 ], [ %108, %126 ]
%131 = tail call double @log10(double %130)
%132 = fneg double %131
%133 = fsub double %132, %3
br label %134
134: ; preds = %129, %80, %77, %23, %19
%135 = phi double [ %20, %19 ], [ %28, %23 ], [ %79, %77 ], [ %81, %80 ], [ %133, %129 ]
ret double %135
}