#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 */
double Binomial(int, int, double *);
scalar_t__ StirlingS2(int, int);
int /*<<< orphan*/ error2(char *);
int exp(double);
int fabs(double);
double ldexp(int, int);
double log(double);
double lnStirlingS2(int n, int k) {
  int i;
  double lnS = 0, t0, x0, x, A, nk, y;
  if (k > n)
    error2("k<n in lnStirlingS2");
  if (n == 0 && k == 0)
    return 0;
  if (k == 0)
    return -1e300;
  if (k == 1 || k == n)
    return (0);
  if (k == 2)
    return (n < 50 ? log(ldexp(1, n - 1) - 1) : (n - 1) * 0.693147);
  if (k == n - 1)
    return log(n * (n - 1) / 2.0);
  if (n < 8)
    return log((double)StirlingS2(n, k));
  nk = (double)n / k;
  for (i = 0, x0 = x = 1; i < 10000; i++) {
    x = (x0 + nk - nk * exp(-x0)) / 2;
    if (fabs(x - x0) / (1 + x) < 1e-10)
      break;
    x0 = x;
  }
  t0 = n / (double)k - 1;
  if (x < 100)
    A = -n * log(x) + k * log(exp(x) - 1);
  else
    A = -n * log(x) + k * x;
  A += -k * t0 + (n - k) * log(t0);
  lnS = A + (n - k) * log((double)k) + 0.5 * log(t0 / ((1 + t0) * (x - t0)));
  lnS += log(Binomial(n, k, &y));
  lnS += y;
  return (lnS);
}


x86 assembly (clang, -O0):
<lnStirlingS2>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0xc(%rbp),%eax
jle    11a1 <lnStirlingS2+0x31>
lea    0xe9c(%rip),%rdi
call   1040 <error2@plt>
cmpl   $0x0,-0xc(%rbp)
jne    11c2 <lnStirlingS2+0x52>
cmpl   $0x0,-0x10(%rbp)
jne    11c2 <lnStirlingS2+0x52>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    15e3 <lnStirlingS2+0x473>
cmpl   $0x0,-0x10(%rbp)
jne    11de <lnStirlingS2+0x6e>
movsd  0xe5c(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    15e3 <lnStirlingS2+0x473>
cmpl   $0x1,-0x10(%rbp)
je     11f4 <lnStirlingS2+0x84>
mov    -0x10(%rbp),%eax
cmp    -0xc(%rbp),%eax
jne    1201 <lnStirlingS2+0x91>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    15e3 <lnStirlingS2+0x473>
cmpl   $0x2,-0x10(%rbp)
jne    126a <lnStirlingS2+0xfa>
cmpl   $0x32,-0xc(%rbp)
jge    1240 <lnStirlingS2+0xd0>
mov    -0xc(%rbp),%esi
sub    $0x1,%esi
mov    $0x1,%edi
call   1030 <ldexp@plt>
movsd  0xdd3(%rip),%xmm1
subsd  %xmm1,%xmm0
call   1080 <log@plt>
movsd  %xmm0,-0x58(%rbp)
jmp    125b <lnStirlingS2+0xeb>
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
cvtsi2sd %eax,%xmm0
movsd  0xdd6(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    15e3 <lnStirlingS2+0x473>
mov    -0x10(%rbp),%eax
mov    -0xc(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    12a6 <lnStirlingS2+0x136>
mov    -0xc(%rbp),%eax
mov    -0xc(%rbp),%ecx
sub    $0x1,%ecx
imul   %ecx,%eax
cvtsi2sd %eax,%xmm0
movsd  0xd7d(%rip),%xmm1
divsd  %xmm1,%xmm0
call   1080 <log@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    15e3 <lnStirlingS2+0x473>
cmpl   $0x8,-0xc(%rbp)
jge    12cf <lnStirlingS2+0x15f>
mov    -0xc(%rbp),%edi
mov    -0x10(%rbp),%esi
call   1090 <StirlingS2@plt>
cvtsi2sd %rax,%xmm0
call   1080 <log@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    15e3 <lnStirlingS2+0x473>
cvtsi2sdl -0xc(%rbp),%xmm0
cvtsi2sdl -0x10(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movl   $0x0,-0x14(%rbp)
movsd  0xd0f(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0xd02(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
cmpl   $0x2710,-0x14(%rbp)
jge    13db <lnStirlingS2+0x26b>
movsd  -0x30(%rbp),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x30(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1070 <exp@plt>
movsd  -0x68(%rbp),%xmm0
movsd  -0x60(%rbp),%xmm1
cvtsi2sd %eax,%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xc91(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
call   1050 <fabs@plt>
cvtsi2sd %eax,%xmm1
movsd  0xc5d(%rip),%xmm0
addsd  -0x38(%rbp),%xmm0
divsd  %xmm0,%xmm1
movsd  0xc54(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    13c3 <lnStirlingS2+0x253>
jmp    13db <lnStirlingS2+0x26b>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1303 <lnStirlingS2+0x193>
cvtsi2sdl -0xc(%rbp),%xmm0
cvtsi2sdl -0x10(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  0xc0f(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xc16(%rip),%xmm0
ucomisd -0x38(%rbp),%xmm0
jbe    1472 <lnStirlingS2+0x302>
xor    %eax,%eax
sub    -0xc(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x38(%rbp),%xmm0
call   1080 <log@plt>
movsd  %xmm0,-0x78(%rbp)
cvtsi2sdl -0x10(%rbp),%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  -0x38(%rbp),%xmm0
call   1070 <exp@plt>
sub    $0x1,%eax
cvtsi2sd %eax,%xmm0
call   1080 <log@plt>
movsd  -0x80(%rbp),%xmm1
movsd  -0x78(%rbp),%xmm2
movaps %xmm0,%xmm3
movsd  -0x70(%rbp),%xmm0
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    14af <lnStirlingS2+0x33f>
xor    %eax,%eax
sub    -0xc(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x38(%rbp),%xmm0
call   1080 <log@plt>
movaps %xmm0,%xmm2
movsd  -0x88(%rbp),%xmm0
ff
cvtsi2sdl -0x10(%rbp),%xmm1
mulsd  -0x38(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
xor    %eax,%eax
sub    -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
mov    -0xc(%rbp),%eax
sub    -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0xb8(%rbp)
ff
movsd  -0x28(%rbp),%xmm0
call   1080 <log@plt>
movsd  -0xb8(%rbp),%xmm1
ff
movsd  -0xb0(%rbp),%xmm2
ff
movaps %xmm0,%xmm3
movsd  -0xa8(%rbp),%xmm0
ff
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
mov    -0xc(%rbp),%eax
sub    -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
cvtsi2sdl -0x10(%rbp),%xmm0
call   1080 <log@plt>
movsd  -0xa0(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0x98(%rbp),%xmm0
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x28(%rbp),%xmm0
movsd  0xa8d(%rip),%xmm1
addsd  -0x28(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm2
subsd  -0x28(%rbp),%xmm2
mulsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
call   1080 <log@plt>
movsd  -0x90(%rbp),%xmm1
ff
movsd  0xa81(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0xc(%rbp),%edi
mov    -0x10(%rbp),%esi
lea    -0x50(%rbp),%rdx
call   1060 <Binomial@plt>
call   1080 <log@plt>
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x50(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<lnStirlingS2>:
push   %rbp
push   %r15
push   %r14
push   %rbx
sub    $0x88,%rsp
mov    %esi,%ebx
mov    %edi,%r14d
cmp    %esi,%edi
jge    1192 <lnStirlingS2+0x22>
lea    0xec3(%rip),%rdi
call   1040 <error2@plt>
xorpd  %xmm0,%xmm0
mov    %ebx,%eax
or     %r14d,%eax
je     11d9 <lnStirlingS2+0x69>
test   %ebx,%ebx
je     11d1 <lnStirlingS2+0x61>
cmp    $0x1,%ebx
je     11d9 <lnStirlingS2+0x69>
mov    %r14d,%r15d
sub    %ebx,%r15d
je     11d9 <lnStirlingS2+0x69>
cmp    $0x2,%ebx
jne    11e7 <lnStirlingS2+0x77>
lea    -0x1(%r14),%esi
cmp    $0x31,%r14d
jg     1204 <lnStirlingS2+0x94>
mov    $0x1,%edi
call   1030 <ldexp@plt>
addsd  0xe51(%rip),%xmm0
jmp    122d <lnStirlingS2+0xbd>
movsd  0xe27(%rip),%xmm0
add    $0x88,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret
lea    -0x1(%r14),%eax
cmp    %ebx,%eax
jne    1215 <lnStirlingS2+0xa5>
imul   %r14d,%ebx
xorps  %xmm0,%xmm0
cvtsi2sd %ebx,%xmm0
mulsd  0xe0e(%rip),%xmm0
jmp    122d <lnStirlingS2+0xbd>
xorps  %xmm0,%xmm0
cvtsi2sd %esi,%xmm0
mulsd  0xe1d(%rip),%xmm0
jmp    11d9 <lnStirlingS2+0x69>
cmp    $0x7,%r14d
jg     123f <lnStirlingS2+0xcf>
mov    %r14d,%edi
mov    %ebx,%esi
call   1090 <StirlingS2@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
add    $0x88,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
jmp    1080 <log@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %r14d,%xmm0
cvtsi2sd %ebx,%xmm1
movapd %xmm1,0x70(%rsp)
divsd  %xmm1,%xmm0
movapd 0xde3(%rip),%xmm1
movapd %xmm0,0x20(%rsp)
xorpd  %xmm0,%xmm1
movapd %xmm1,0x30(%rsp)
movsd  0xd93(%rip),%xmm2
mov    $0x270f,%ebp
nopw   0x0(%rax,%rax,1)
movapd %xmm2,(%rsp)
movapd 0x20(%rsp),%xmm1
addsd  %xmm2,%xmm1
movapd %xmm1,0x10(%rsp)
xorpd  0xda3(%rip),%xmm2
movapd %xmm2,%xmm0
call   1070 <exp@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
mulsd  0x30(%rsp),%xmm0
addsd  0x10(%rsp),%xmm0
mulsd  0xd4f(%rip),%xmm0
movapd %xmm0,0x10(%rsp)
subsd  (%rsp),%xmm0
call   1050 <fabs@plt>
movapd 0x10(%rsp),%xmm2
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movapd %xmm2,%xmm1
addsd  0xd1e(%rip),%xmm1
divsd  %xmm1,%xmm0
sub    $0x1,%ebp
setb   %al
movsd  0xd1c(%rip),%xmm1
ucomisd %xmm0,%xmm1
ja     130a <lnStirlingS2+0x19a>
test   %al,%al
je     1280 <lnStirlingS2+0x110>
movapd 0x20(%rsp),%xmm0
addsd  0xd08(%rip),%xmm0
movapd %xmm0,0x20(%rsp)
mov    %r14d,%ebp
neg    %ebp
movapd %xmm2,%xmm0
call   1080 <log@plt>
movapd %xmm0,0x60(%rsp)
movsd  0xcee(%rip),%xmm0
movapd 0x10(%rsp),%xmm1
ucomisd %xmm1,%xmm0
xorps  %xmm0,%xmm0
cvtsi2sd %ebp,%xmm0
movapd %xmm0,(%rsp)
movapd %xmm1,%xmm0
jbe    136f <lnStirlingS2+0x1ff>
movaps 0x10(%rsp),%xmm0
call   1070 <exp@plt>
add    $0xffffffff,%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
call   1080 <log@plt>
movapd %xmm0,0x50(%rsp)
mov    %ebx,%eax
neg    %eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movapd (%rsp),%xmm1
unpcklpd %xmm0,%xmm1
movapd %xmm1,(%rsp)
xorps  %xmm0,%xmm0
cvtsi2sd %r15d,%xmm0
movapd %xmm0,0x30(%rsp)
movapd 0x20(%rsp),%xmm0
call   1080 <log@plt>
movapd 0x50(%rsp),%xmm2
unpcklpd %xmm0,%xmm2
movapd 0x70(%rsp),%xmm0
movapd %xmm0,%xmm1
unpcklpd 0x30(%rsp),%xmm1
mulpd  %xmm2,%xmm1
movapd 0x60(%rsp),%xmm2
unpcklpd 0x20(%rsp),%xmm2
mulpd  (%rsp),%xmm2
addpd  %xmm1,%xmm2
movapd %xmm2,%xmm1
unpckhpd %xmm2,%xmm1
addsd  %xmm2,%xmm1
movapd %xmm1,(%rsp)
call   1080 <log@plt>
mulsd  0x30(%rsp),%xmm0
addsd  (%rsp),%xmm0
movsd  %xmm0,(%rsp)
movsd  0xc00(%rip),%xmm0
movapd 0x20(%rsp),%xmm2
addsd  %xmm2,%xmm0
movapd 0x10(%rsp),%xmm1
subsd  %xmm2,%xmm1
mulsd  %xmm0,%xmm1
divsd  %xmm1,%xmm2
movapd %xmm2,%xmm0
call   1080 <log@plt>
mulsd  0xbdb(%rip),%xmm0
addsd  (%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
lea    0x48(%rsp),%rdx
mov    %r14d,%edi
mov    %ebx,%esi
call   1060 <Binomial@plt>
call   1080 <log@plt>
addsd  0x10(%rsp),%xmm0
addsd  0x48(%rsp),%xmm0
jmp    11d9 <lnStirlingS2+0x69>

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

LLVM IR (-O2):
@.str = [20 x i8] c"k<n in lnStirlingS2\00"
define double @lnStirlingS2(i32 %0, i32 %1) {
%3 = alloca double
%4 = bitcast double* %3 to i8*
%5 = icmp slt i32 %0, %1
br i1 %5, label %6, label %8
6: ; preds = %2
%7 = tail call i32 @error2(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0))
br label %8
8: ; preds = %6, %2
%9 = or i32 %1, %0
%10 = icmp eq i32 %9, 0
br i1 %10, label %108, label %11
11: ; preds = %8
switch i32 %1, label %12 [
i32 0, label %108
i32 1, label %14
]
12: ; preds = %11
%13 = icmp eq i32 %0, %1
br i1 %13, label %14, label %15
14: ; preds = %11, %12
br label %108
15: ; preds = %12
%16 = icmp eq i32 %1, 2
br i1 %16, label %17, label %27
17: ; preds = %15
%18 = icmp slt i32 %0, 50
%19 = add nsw i32 %0, -1
br i1 %18, label %20, label %24
20: ; preds = %17
%21 = tail call double @ldexp(i32 1, i32 %19)
%22 = fadd double %21, -1.000000e+00
%23 = tail call double @log(double %22)
br label %108
24: ; preds = %17
%25 = sitofp i32 %19 to double
%26 = fmul double %25, 0x3FE62E429E0A41A2
br label %108
27: ; preds = %15
%28 = add nsw i32 %0, -1
%29 = icmp eq i32 %28, %1
br i1 %29, label %30, label %35
30: ; preds = %27
%31 = mul nsw i32 %1, %0
%32 = sitofp i32 %31 to double
%33 = fmul double %32, 5.000000e-01
%34 = tail call double @log(double %33)
br label %108
35: ; preds = %27
%36 = icmp slt i32 %0, 8
br i1 %36, label %37, label %41
37: ; preds = %35
%38 = tail call i64 @StirlingS2(i32 %0, i32 %1)
%39 = sitofp i64 %38 to double
%40 = tail call double @log(double %39)
br label %108
41: ; preds = %35
%42 = sitofp i32 %0 to double
%43 = sitofp i32 %1 to double
%44 = fdiv double %42, %43
%45 = fneg double %44
br label %46
46: ; preds = %46, %41
%47 = phi double [ 1.000000e+00, %41 ], [ %54, %46 ]
%48 = phi i32 [ 0, %41 ], [ %61, %46 ]
%49 = fadd double %44, %47
%50 = fneg double %47
%51 = tail call i32 @exp(double %50)
%52 = sitofp i32 %51 to double
%53 = tail call double @llvm.fmuladd.f64(double %45, double %52, double %49)
%54 = fmul double %53, 5.000000e-01
%55 = fsub double %54, %47
%56 = tail call i32 @fabs(double %55)
%57 = sitofp i32 %56 to double
%58 = fadd double %54, 1.000000e+00
%59 = fdiv double %57, %58
%60 = fcmp olt double %59, 1.000000e-10
%61 = add nuw nsw i32 %48, 1
%62 = icmp eq i32 %61, 10000
%63 = select i1 %60, i1 true, i1 %62
br i1 %63, label %64, label %46
64: ; preds = %46
%65 = fadd double %44, -1.000000e+00
%66 = fcmp olt double %54, 1.000000e+02
%67 = sub nsw i32 0, %0
%68 = sitofp i32 %67 to double
%69 = tail call double @log(double %54)
br i1 %66, label %70, label %75
70: ; preds = %64
%71 = tail call i32 @exp(double %54)
%72 = add nsw i32 %71, -1
%73 = sitofp i32 %72 to double
%74 = tail call double @log(double %73)
br label %75
75: ; preds = %64, %70
%76 = phi double [ %74, %70 ], [ %54, %64 ]
%77 = sub nsw i32 0, %1
%78 = sitofp i32 %77 to double
%79 = sub nsw i32 %0, %1
%80 = sitofp i32 %79 to double
%81 = tail call double @log(double %65)
%82 = insertelement <2 x double> poison, double %76, i64 0
%83 = insertelement <2 x double> %82, double %81, i64 1
%84 = insertelement <2 x double> poison, double %43, i64 0
%85 = insertelement <2 x double> %84, double %80, i64 1
%86 = fmul <2 x double> %83, %85
%87 = insertelement <2 x double> poison, double %68, i64 0
%88 = insertelement <2 x double> %87, double %78, i64 1
%89 = insertelement <2 x double> poison, double %69, i64 0
%90 = insertelement <2 x double> %89, double %65, i64 1
%91 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %88, <2 x double> %90, <2 x double> %86)
%92 = shufflevector <2 x double> %91, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%93 = fadd <2 x double> %91, %92
%94 = extractelement <2 x double> %93, i64 0
%95 = tail call double @log(double %43)
%96 = tail call double @llvm.fmuladd.f64(double %80, double %95, double %94)
%97 = fadd double %65, 1.000000e+00
%98 = fsub double %54, %65
%99 = fmul double %97, %98
%100 = fdiv double %65, %99
%101 = tail call double @log(double %100)
%102 = tail call double @llvm.fmuladd.f64(double %101, double 5.000000e-01, double %96)
%103 = call double @Binomial(i32 %0, i32 %1, double* %3)
%104 = call double @log(double %103)
%105 = fadd double %104, %102
%106 = load double, double* %3
%107 = fadd double %106, %105
br label %108
108: ; preds = %20, %24, %11, %8, %75, %37, %30, %14
%109 = phi double [ 0.000000e+00, %14 ], [ %34, %30 ], [ %40, %37 ], [ %107, %75 ], [ 0.000000e+00, %8 ], [ -1.000000e+300, %11 ], [ %23, %20 ], [ %26, %24 ]
ret double %109
}