#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 HUGE_VAL;
int /*<<< orphan*/ assert(int);
int exp(double);
double lgamma(int);
double log(int);
double S_approx(int n, int m, float a) {
  assert(a > 0);
  if (n == m)
    return 0.0;
  if (n < m)
    return -HUGE_VAL;
  if (m == 1) {
    return lgamma(n - a) - lgamma(1 - a);
  } else if (m == 2) {
    double ga = lgamma(n - a) - lgamma(1 - a);
    double g2a = lgamma(n - 2 * a) - lgamma(1 - 2 * a);
    return g2a - log(a) + log(exp(ga - g2a) - 1.0);
  } else if (m == 3) {
    double ga = lgamma(n - a) - lgamma(1 - a);
    double g2a = lgamma(n - 2 * a) - lgamma(1 - 2 * a);
    double g3a = lgamma(n - 3 * a) - lgamma(1 - 3 * a);
    return g3a - 2 * log(a) - log(2.0) +
           log(exp(ga - g3a) - 2 * exp(g2a - g3a) + 1.0);
  } else if (m == 4) {
    double ga = lgamma(n - a) - lgamma(1 - a);
    double g2a = lgamma(n - 2 * a) - lgamma(1 - 2 * a);
    double g3a = lgamma(n - 3 * a) - lgamma(1 - 3 * a);
    double g4a = lgamma(n - 4 * a) - lgamma(1 - 4 * a);
    return g4a - 3 * log(a) - log(6.0) +
           log(exp(ga - g4a) - 3 * exp(g2a - g4a) + 3 * exp(g3a - g4a) - 1.0);
  }
  return -HUGE_VAL;
}


x86 assembly (clang, -O0):
<S_approx>:
push   %rbp
mov    %rsp,%rbp
sub    $0x100,%rsp
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
movss  %xmm0,-0x14(%rbp)
movss  -0x14(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
cmp    -0x10(%rbp),%eax
jne    1187 <S_approx+0x47>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    174e <S_approx+0x60e>
mov    -0xc(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    11bf <S_approx+0x7f>
mov    0x2e4e(%rip),%rax
movsd  (%rax),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    174e <S_approx+0x60e>
cmpl   $0x1,-0x10(%rbp)
jne    120d <S_approx+0xcd>
cvtsi2ssl -0xc(%rbp),%xmm0
subss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0x68(%rbp)
movss  0xe2b(%rip),%xmm0
subss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0x68(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    174e <S_approx+0x60e>
cmpl   $0x2,-0x10(%rbp)
jne    130e <S_approx+0x1ce>
cvtsi2ssl -0xc(%rbp),%xmm0
subss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0x88(%rbp)
ff
movss  0xdda(%rip),%xmm0
subss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0x88(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm0
movss  -0x14(%rbp),%xmm1
addss  %xmm1,%xmm1
subss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0x80(%rbp)
movss  -0x14(%rbp),%xmm1
addss  %xmm1,%xmm1
movss  0xd87(%rip),%xmm0
subss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0x80(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
cvttss2si -0x14(%rbp),%edi
call   1060 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x78(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x20(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
call   1040 <exp@plt>
cvtsi2sd %eax,%xmm0
movsd  0xd15(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%edi
call   1060 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x70(%rbp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    174e <S_approx+0x60e>
cmpl   $0x3,-0x10(%rbp)
jne    14cd <S_approx+0x38d>
cvtsi2ssl -0xc(%rbp),%xmm0
subss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0xc0(%rbp)
ff
movss  0xcd9(%rip),%xmm0
subss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0xc0(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm0
movss  -0x14(%rbp),%xmm1
addss  %xmm1,%xmm1
subss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0xb8(%rbp)
ff
movss  -0x14(%rbp),%xmm1
addss  %xmm1,%xmm1
movss  0xc83(%rip),%xmm0
subss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0xb8(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm1
movss  -0x14(%rbp),%xmm0
movss  0xc54(%rip),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0xb0(%rbp)
ff
movss  -0x14(%rbp),%xmm0
movss  0xc2e(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  0xc1e(%rip),%xmm1
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0xb0(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
cvttss2si -0x14(%rbp),%edi
call   1060 <log@plt>
movaps %xmm0,%xmm1
movsd  -0xa8(%rbp),%xmm0
ff
addsd  %xmm1,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
mov    $0x2,%edi
call   1060 <log@plt>
movaps %xmm0,%xmm1
movsd  -0xa0(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x30(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
call   1040 <exp@plt>
mov    %eax,-0x94(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
call   1040 <exp@plt>
mov    %eax,%ecx
mov    -0x94(%rbp),%eax
shl    $0x1,%ecx
sub    %ecx,%eax
cvtsi2sd %eax,%xmm0
movsd  0xb59(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%edi
call   1060 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x90(%rbp),%xmm0
ff
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    174e <S_approx+0x60e>
cmpl   $0x4,-0x10(%rbp)
jne    1718 <S_approx+0x5d8>
cvtsi2ssl -0xc(%rbp),%xmm0
subss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0x100(%rbp)
ff
movss  0xb1a(%rip),%xmm0
subss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0x100(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm0
movss  -0x14(%rbp),%xmm1
addss  %xmm1,%xmm1
subss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0xf8(%rbp)
ff
movss  -0x14(%rbp),%xmm1
addss  %xmm1,%xmm1
movss  0xac4(%rip),%xmm0
subss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0xf8(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm1
movss  -0x14(%rbp),%xmm0
movss  0xa95(%rip),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0xf0(%rbp)
ff
movss  -0x14(%rbp),%xmm0
movss  0xa6f(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  0xa5f(%rip),%xmm1
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0xf0(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm1
movss  -0x14(%rbp),%xmm0
movss  0xa28(%rip),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,-0xe8(%rbp)
movss  -0x14(%rbp),%xmm0
movss  0xa02(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  0x9fa(%rip),%xmm1
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,%xmm1
movsd  -0xe8(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0xe0(%rbp)
ff
cvttss2si -0x14(%rbp),%edi
call   1060 <log@plt>
movsd  -0xe0(%rbp),%xmm1
ff
movsd  0x9a6(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0xd8(%rbp)
ff
mov    $0x6,%edi
call   1060 <log@plt>
movaps %xmm0,%xmm1
movsd  -0xd8(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xc8(%rbp)
ff
movsd  -0x48(%rbp),%xmm0
subsd  -0x60(%rbp),%xmm0
call   1040 <exp@plt>
mov    %eax,-0xd0(%rbp)
movsd  -0x50(%rbp),%xmm0
subsd  -0x60(%rbp),%xmm0
call   1040 <exp@plt>
mov    %eax,%ecx
mov    -0xd0(%rbp),%eax
imul   $0x3,%ecx,%ecx
sub    %ecx,%eax
mov    %eax,-0xcc(%rbp)
movsd  -0x58(%rbp),%xmm0
subsd  -0x60(%rbp),%xmm0
call   1040 <exp@plt>
mov    %eax,%ecx
mov    -0xcc(%rbp),%eax
imul   $0x3,%ecx,%ecx
add    %ecx,%eax
cvtsi2sd %eax,%xmm0
movsd  0x90e(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%edi
call   1060 <log@plt>
movaps %xmm0,%xmm1
movsd  -0xc8(%rbp),%xmm0
ff
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    174e <S_approx+0x60e>
jmp    171d <S_approx+0x5dd>
jmp    1722 <S_approx+0x5e2>
jmp    1727 <S_approx+0x5e7>
mov    0x28ba(%rip),%rax
movsd  (%rax),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x100,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<S_approx>:
push   %rbp
push   %rbx
sub    $0x48,%rsp
mov    %esi,%ebx
mov    %edi,%ebp
xorps  %xmm1,%xmm1
xor    %edi,%edi
movss  %xmm0,0x8(%rsp)
ucomiss %xmm1,%xmm0
seta   %dil
call   1030 <assert@plt>
xorps  %xmm0,%xmm0
cmp    %ebx,%ebp
je     15dc <S_approx+0x49c>
jge    1185 <S_approx+0x45>
mov    0x2e73(%rip),%rax
movsd  (%rax),%xmm0
xorps  0xea0(%rip),%xmm0
jmp    15dc <S_approx+0x49c>
add    $0xffffffff,%ebx
cmp    $0x3,%ebx
ja     116e <S_approx+0x2e>
lea    0xe9c(%rip),%rax
movslq (%rax,%rbx,4),%rcx
add    %rax,%rcx
jmp    *%rcx
xorps  %xmm0,%xmm0
cvtsi2ss %ebp,%xmm0
subss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movaps %xmm0,0x10(%rsp)
movss  0xe40(%rip),%xmm0
subss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movapd 0x10(%rsp),%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
jmp    15dc <S_approx+0x49c>
xorps  %xmm0,%xmm0
cvtsi2ss %ebp,%xmm0
movss  %xmm0,0x10(%rsp)
subss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x28(%rsp)
movss  0xdf4(%rip),%xmm0
subss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x28(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x28(%rsp)
movss  0xdd1(%rip),%xmm1
mulss  0x8(%rsp),%xmm1
movss  %xmm1,0x38(%rsp)
movss  0x10(%rsp),%xmm0
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x10(%rsp)
movss  0x38(%rsp),%xmm0
addss  0xd9a(%rip),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x10(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rsp)
cvttss2si 0x8(%rsp),%edi
call   1060 <log@plt>
movsd  0x28(%rsp),%xmm1
movsd  0x10(%rsp),%xmm2
subsd  %xmm2,%xmm1
subsd  %xmm0,%xmm2
movsd  %xmm2,0x10(%rsp)
movapd %xmm1,%xmm0
call   1040 <exp@plt>
lea    -0x1(%rax),%edi
call   1060 <log@plt>
addsd  0x10(%rsp),%xmm0
jmp    15dc <S_approx+0x49c>
xorps  %xmm0,%xmm0
cvtsi2ss %ebp,%xmm0
movss  %xmm0,0x10(%rsp)
subss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x28(%rsp)
movss  0xd16(%rip),%xmm0
subss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x28(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x28(%rsp)
movss  0xcf3(%rip),%xmm0
mulss  0x8(%rsp),%xmm0
movss  %xmm0,0x30(%rsp)
addss  0x10(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x38(%rsp)
movss  0x30(%rsp),%xmm0
addss  0xcc0(%rip),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x38(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x38(%rsp)
movss  0xca7(%rip),%xmm1
mulss  0x8(%rsp),%xmm1
movss  %xmm1,0x30(%rsp)
movss  0x10(%rsp),%xmm0
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x10(%rsp)
movss  0x30(%rsp),%xmm0
addss  0xc6c(%rip),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x10(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rsp)
cvttss2si 0x8(%rsp),%edi
call   1060 <log@plt>
addsd  %xmm0,%xmm0
movsd  0x10(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
mov    $0x2,%edi
call   1060 <log@plt>
movsd  0x8(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0x28(%rsp),%xmm0
subsd  0x10(%rsp),%xmm0
call   1040 <exp@plt>
mov    %eax,%ebx
movsd  0x38(%rsp),%xmm0
subsd  0x10(%rsp),%xmm0
call   1040 <exp@plt>
add    %eax,%eax
neg    %eax
lea    (%rbx,%rax,1),%edi
add    $0x1,%edi
jmp    15d1 <S_approx+0x491>
xorps  %xmm0,%xmm0
cvtsi2ss %ebp,%xmm0
movss  %xmm0,0x10(%rsp)
subss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x28(%rsp)
movss  0xbbd(%rip),%xmm0
subss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x28(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x28(%rsp)
movss  0xb9a(%rip),%xmm0
mulss  0x8(%rsp),%xmm0
movss  %xmm0,0x30(%rsp)
addss  0x10(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x38(%rsp)
movss  0x30(%rsp),%xmm0
addss  0xb67(%rip),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x38(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x38(%rsp)
movss  0xb4e(%rip),%xmm0
mulss  0x8(%rsp),%xmm0
movss  %xmm0,0x44(%rsp)
addss  0x10(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x30(%rsp)
movss  0x44(%rsp),%xmm0
addss  0xb17(%rip),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x30(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x30(%rsp)
movss  0xb02(%rip),%xmm1
mulss  0x8(%rsp),%xmm1
movss  %xmm1,0x44(%rsp)
movss  0x10(%rsp),%xmm0
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  %xmm0,0x10(%rsp)
movss  0x44(%rsp),%xmm0
addss  0xac3(%rip),%xmm0
cvttss2si %xmm0,%edi
call   1050 <lgamma@plt>
movsd  0x10(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rsp)
cvttss2si 0x8(%rsp),%edi
call   1060 <log@plt>
mulsd  0xaa7(%rip),%xmm0
addsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
mov    $0x6,%edi
call   1060 <log@plt>
movsd  0x8(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0x28(%rsp),%xmm0
subsd  0x10(%rsp),%xmm0
call   1040 <exp@plt>
mov    %eax,%ebx
movsd  0x38(%rsp),%xmm0
subsd  0x10(%rsp),%xmm0
call   1040 <exp@plt>
mov    %eax,%ebp
movsd  0x30(%rsp),%xmm0
subsd  0x10(%rsp),%xmm0
call   1040 <exp@plt>
sub    %ebp,%eax
lea    (%rax,%rax,2),%eax
lea    (%rbx,%rax,1),%edi
add    $0xffffffff,%edi
call   1060 <log@plt>
addsd  0x8(%rsp),%xmm0
add    $0x48,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
@HUGE_VAL = global double 0.000000e+00
define double @S_approx(i32 %0, i32 %1, float %2) {
%4 = alloca double
%5 = alloca i32
%6 = alloca i32
%7 = alloca float
%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
store i32 %0, i32* %5
store i32 %1, i32* %6
store float %2, float* %7
%17 = load float, float* %7
%18 = fcmp ogt float %17, 0.000000e+00
%19 = zext i1 %18 to i32
%20 = call i32 @assert(i32 %19)
%21 = load i32, i32* %5
%22 = load i32, i32* %6
%23 = icmp eq i32 %21, %22
br i1 %23, label %24, label %25
24: ; preds = %3
store double 0.000000e+00, double* %4
br label %228
25: ; preds = %3
%26 = load i32, i32* %5
%27 = load i32, i32* %6
%28 = icmp slt i32 %26, %27
br i1 %28, label %29, label %32
29: ; preds = %25
%30 = load double, double* @HUGE_VAL
%31 = fneg double %30
store double %31, double* %4
br label %228
32: ; preds = %25
%33 = load i32, i32* %6
%34 = icmp eq i32 %33, 1
br i1 %34, label %35, label %47
35: ; preds = %32
%36 = load i32, i32* %5
%37 = sitofp i32 %36 to float
%38 = load float, float* %7
%39 = fsub float %37, %38
%40 = fptosi float %39 to i32
%41 = call double @lgamma(i32 %40)
%42 = load float, float* %7
%43 = fsub float 1.000000e+00, %42
%44 = fptosi float %43 to i32
%45 = call double @lgamma(i32 %44)
%46 = fsub double %41, %45
store double %46, double* %4
br label %228
47: ; preds = %32
%48 = load i32, i32* %6
%49 = icmp eq i32 %48, 2
br i1 %49, label %50, label %87
50: ; preds = %47
%51 = load i32, i32* %5
%52 = sitofp i32 %51 to float
%53 = load float, float* %7
%54 = fsub float %52, %53
%55 = fptosi float %54 to i32
%56 = call double @lgamma(i32 %55)
%57 = load float, float* %7
%58 = fsub float 1.000000e+00, %57
%59 = fptosi float %58 to i32
%60 = call double @lgamma(i32 %59)
%61 = fsub double %56, %60
store double %61, double* %8
%62 = load i32, i32* %5
%63 = sitofp i32 %62 to float
%64 = load float, float* %7
%65 = call float @llvm.fmuladd.f32(float -2.000000e+00, float %64, float %63)
%66 = fptosi float %65 to i32
%67 = call double @lgamma(i32 %66)
%68 = load float, float* %7
%69 = call float @llvm.fmuladd.f32(float -2.000000e+00, float %68, float 1.000000e+00)
%70 = fptosi float %69 to i32
%71 = call double @lgamma(i32 %70)
%72 = fsub double %67, %71
store double %72, double* %9
%73 = load double, double* %9
%74 = load float, float* %7
%75 = fptosi float %74 to i32
%76 = call double @log(i32 %75)
%77 = fsub double %73, %76
%78 = load double, double* %8
%79 = load double, double* %9
%80 = fsub double %78, %79
%81 = call i32 @exp(double %80)
%82 = sitofp i32 %81 to double
%83 = fsub double %82, 1.000000e+00
%84 = fptosi double %83 to i32
%85 = call double @log(i32 %84)
%86 = fadd double %77, %85
store double %86, double* %4
br label %228
87: ; preds = %47
%88 = load i32, i32* %6
%89 = icmp eq i32 %88, 3
br i1 %89, label %90, label %146
90: ; preds = %87
%91 = load i32, i32* %5
%92 = sitofp i32 %91 to float
%93 = load float, float* %7
%94 = fsub float %92, %93
%95 = fptosi float %94 to i32
%96 = call double @lgamma(i32 %95)
%97 = load float, float* %7
%98 = fsub float 1.000000e+00, %97
%99 = fptosi float %98 to i32
%100 = call double @lgamma(i32 %99)
%101 = fsub double %96, %100
store double %101, double* %10
%102 = load i32, i32* %5
%103 = sitofp i32 %102 to float
%104 = load float, float* %7
%105 = call float @llvm.fmuladd.f32(float -2.000000e+00, float %104, float %103)
%106 = fptosi float %105 to i32
%107 = call double @lgamma(i32 %106)
%108 = load float, float* %7
%109 = call float @llvm.fmuladd.f32(float -2.000000e+00, float %108, float 1.000000e+00)
%110 = fptosi float %109 to i32
%111 = call double @lgamma(i32 %110)
%112 = fsub double %107, %111
store double %112, double* %11
%113 = load i32, i32* %5
%114 = sitofp i32 %113 to float
%115 = load float, float* %7
%116 = call float @llvm.fmuladd.f32(float -3.000000e+00, float %115, float %114)
%117 = fptosi float %116 to i32
%118 = call double @lgamma(i32 %117)
%119 = load float, float* %7
%120 = call float @llvm.fmuladd.f32(float -3.000000e+00, float %119, float 1.000000e+00)
%121 = fptosi float %120 to i32
%122 = call double @lgamma(i32 %121)
%123 = fsub double %118, %122
store double %123, double* %12
%124 = load double, double* %12
%125 = load float, float* %7
%126 = fptosi float %125 to i32
%127 = call double @log(i32 %126)
%128 = call double @llvm.fmuladd.f64(double -2.000000e+00, double %127, double %124)
%129 = call double @log(i32 2)
%130 = fsub double %128, %129
%131 = load double, double* %10
%132 = load double, double* %12
%133 = fsub double %131, %132
%134 = call i32 @exp(double %133)
%135 = load double, double* %11
%136 = load double, double* %12
%137 = fsub double %135, %136
%138 = call i32 @exp(double %137)
%139 = mul nsw i32 2, %138
%140 = sub nsw i32 %134, %139
%141 = sitofp i32 %140 to double
%142 = fadd double %141, 1.000000e+00
%143 = fptosi double %142 to i32
%144 = call double @log(i32 %143)
%145 = fadd double %130, %144
store double %145, double* %4
br label %228
146: ; preds = %87
%147 = load i32, i32* %6
%148 = icmp eq i32 %147, 4
br i1 %148, label %149, label %222
149: ; preds = %146
%150 = load i32, i32* %5
%151 = sitofp i32 %150 to float
%152 = load float, float* %7
%153 = fsub float %151, %152
%154 = fptosi float %153 to i32
%155 = call double @lgamma(i32 %154)
%156 = load float, float* %7
%157 = fsub float 1.000000e+00, %156
%158 = fptosi float %157 to i32
%159 = call double @lgamma(i32 %158)
%160 = fsub double %155, %159
store double %160, double* %13
%161 = load i32, i32* %5
%162 = sitofp i32 %161 to float
%163 = load float, float* %7
%164 = call float @llvm.fmuladd.f32(float -2.000000e+00, float %163, float %162)
%165 = fptosi float %164 to i32
%166 = call double @lgamma(i32 %165)
%167 = load float, float* %7
%168 = call float @llvm.fmuladd.f32(float -2.000000e+00, float %167, float 1.000000e+00)
%169 = fptosi float %168 to i32
%170 = call double @lgamma(i32 %169)
%171 = fsub double %166, %170
store double %171, double* %14
%172 = load i32, i32* %5
%173 = sitofp i32 %172 to float
%174 = load float, float* %7
%175 = call float @llvm.fmuladd.f32(float -3.000000e+00, float %174, float %173)
%176 = fptosi float %175 to i32
%177 = call double @lgamma(i32 %176)
%178 = load float, float* %7
%179 = call float @llvm.fmuladd.f32(float -3.000000e+00, float %178, float 1.000000e+00)
%180 = fptosi float %179 to i32
%181 = call double @lgamma(i32 %180)
%182 = fsub double %177, %181
store double %182, double* %15
%183 = load i32, i32* %5
%184 = sitofp i32 %183 to float
%185 = load float, float* %7
%186 = call float @llvm.fmuladd.f32(float -4.000000e+00, float %185, float %184)
%187 = fptosi float %186 to i32
%188 = call double @lgamma(i32 %187)
%189 = load float, float* %7
%190 = call float @llvm.fmuladd.f32(float -4.000000e+00, float %189, float 1.000000e+00)
%191 = fptosi float %190 to i32
%192 = call double @lgamma(i32 %191)
%193 = fsub double %188, %192
store double %193, double* %16
%194 = load double, double* %16
%195 = load float, float* %7
%196 = fptosi float %195 to i32
%197 = call double @log(i32 %196)
%198 = call double @llvm.fmuladd.f64(double -3.000000e+00, double %197, double %194)
%199 = call double @log(i32 6)
%200 = fsub double %198, %199
%201 = load double, double* %13
%202 = load double, double* %16
%203 = fsub double %201, %202
%204 = call i32 @exp(double %203)
%205 = load double, double* %14
%206 = load double, double* %16
%207 = fsub double %205, %206
%208 = call i32 @exp(double %207)
%209 = mul nsw i32 3, %208
%210 = sub nsw i32 %204, %209
%211 = load double, double* %15
%212 = load double, double* %16
%213 = fsub double %211, %212
%214 = call i32 @exp(double %213)
%215 = mul nsw i32 3, %214
%216 = add nsw i32 %210, %215
%217 = sitofp i32 %216 to double
%218 = fsub double %217, 1.000000e+00
%219 = fptosi double %218 to i32
%220 = call double @log(i32 %219)
%221 = fadd double %200, %220
store double %221, double* %4
br label %228
222: ; preds = %146
br label %223
223: ; preds = %222
br label %224
224: ; preds = %223
br label %225
225: ; preds = %224
%226 = load double, double* @HUGE_VAL
%227 = fneg double %226
store double %227, double* %4
br label %228
228: ; preds = %225, %149, %90, %50, %35, %29, %24
%229 = load double, double* %4
ret double %229
}

LLVM IR (-O2):
@HUGE_VAL = global double 0.000000e+00
define double @S_approx(i32 %0, i32 %1, float %2) {
%4 = fcmp ogt float %2, 0.000000e+00
%5 = zext i1 %4 to i32
%6 = tail call i32 @assert(i32 %5)
%7 = icmp eq i32 %0, %1
br i1 %7, label %134, label %8
8: ; preds = %3
%9 = icmp slt i32 %0, %1
br i1 %9, label %10, label %13
10: ; preds = %8
%11 = load double, double* @HUGE_VAL
%12 = fneg double %11
br label %134
13: ; preds = %8
switch i32 %1, label %131 [
i32 1, label %14
i32 2, label %23
i32 3, label %47
i32 4, label %84
]
14: ; preds = %13
%15 = sitofp i32 %0 to float
%16 = fsub float %15, %2
%17 = fptosi float %16 to i32
%18 = tail call double @lgamma(i32 %17)
%19 = fsub float 1.000000e+00, %2
%20 = fptosi float %19 to i32
%21 = tail call double @lgamma(i32 %20)
%22 = fsub double %18, %21
br label %134
23: ; preds = %13
%24 = sitofp i32 %0 to float
%25 = fsub float %24, %2
%26 = fptosi float %25 to i32
%27 = tail call double @lgamma(i32 %26)
%28 = fsub float 1.000000e+00, %2
%29 = fptosi float %28 to i32
%30 = tail call double @lgamma(i32 %29)
%31 = fsub double %27, %30
%32 = tail call float @llvm.fmuladd.f32(float %2, float -2.000000e+00, float %24)
%33 = fptosi float %32 to i32
%34 = tail call double @lgamma(i32 %33)
%35 = tail call float @llvm.fmuladd.f32(float %2, float -2.000000e+00, float 1.000000e+00)
%36 = fptosi float %35 to i32
%37 = tail call double @lgamma(i32 %36)
%38 = fsub double %34, %37
%39 = fptosi float %2 to i32
%40 = tail call double @log(i32 %39)
%41 = fsub double %38, %40
%42 = fsub double %31, %38
%43 = tail call i32 @exp(double %42)
%44 = add i32 %43, -1
%45 = tail call double @log(i32 %44)
%46 = fadd double %41, %45
br label %134
47: ; preds = %13
%48 = sitofp i32 %0 to float
%49 = fsub float %48, %2
%50 = fptosi float %49 to i32
%51 = tail call double @lgamma(i32 %50)
%52 = fsub float 1.000000e+00, %2
%53 = fptosi float %52 to i32
%54 = tail call double @lgamma(i32 %53)
%55 = fsub double %51, %54
%56 = tail call float @llvm.fmuladd.f32(float %2, float -2.000000e+00, float %48)
%57 = fptosi float %56 to i32
%58 = tail call double @lgamma(i32 %57)
%59 = tail call float @llvm.fmuladd.f32(float %2, float -2.000000e+00, float 1.000000e+00)
%60 = fptosi float %59 to i32
%61 = tail call double @lgamma(i32 %60)
%62 = fsub double %58, %61
%63 = tail call float @llvm.fmuladd.f32(float %2, float -3.000000e+00, float %48)
%64 = fptosi float %63 to i32
%65 = tail call double @lgamma(i32 %64)
%66 = tail call float @llvm.fmuladd.f32(float %2, float -3.000000e+00, float 1.000000e+00)
%67 = fptosi float %66 to i32
%68 = tail call double @lgamma(i32 %67)
%69 = fsub double %65, %68
%70 = fptosi float %2 to i32
%71 = tail call double @log(i32 %70)
%72 = tail call double @llvm.fmuladd.f64(double %71, double -2.000000e+00, double %69)
%73 = tail call double @log(i32 2)
%74 = fsub double %72, %73
%75 = fsub double %55, %69
%76 = tail call i32 @exp(double %75)
%77 = fsub double %62, %69
%78 = tail call i32 @exp(double %77)
%79 = mul i32 %78, -2
%80 = add i32 %79, %76
%81 = add i32 %80, 1
%82 = tail call double @log(i32 %81)
%83 = fadd double %74, %82
br label %134
84: ; preds = %13
%85 = sitofp i32 %0 to float
%86 = fsub float %85, %2
%87 = fptosi float %86 to i32
%88 = tail call double @lgamma(i32 %87)
%89 = fsub float 1.000000e+00, %2
%90 = fptosi float %89 to i32
%91 = tail call double @lgamma(i32 %90)
%92 = fsub double %88, %91
%93 = tail call float @llvm.fmuladd.f32(float %2, float -2.000000e+00, float %85)
%94 = fptosi float %93 to i32
%95 = tail call double @lgamma(i32 %94)
%96 = tail call float @llvm.fmuladd.f32(float %2, float -2.000000e+00, float 1.000000e+00)
%97 = fptosi float %96 to i32
%98 = tail call double @lgamma(i32 %97)
%99 = fsub double %95, %98
%100 = tail call float @llvm.fmuladd.f32(float %2, float -3.000000e+00, float %85)
%101 = fptosi float %100 to i32
%102 = tail call double @lgamma(i32 %101)
%103 = tail call float @llvm.fmuladd.f32(float %2, float -3.000000e+00, float 1.000000e+00)
%104 = fptosi float %103 to i32
%105 = tail call double @lgamma(i32 %104)
%106 = fsub double %102, %105
%107 = tail call float @llvm.fmuladd.f32(float %2, float -4.000000e+00, float %85)
%108 = fptosi float %107 to i32
%109 = tail call double @lgamma(i32 %108)
%110 = tail call float @llvm.fmuladd.f32(float %2, float -4.000000e+00, float 1.000000e+00)
%111 = fptosi float %110 to i32
%112 = tail call double @lgamma(i32 %111)
%113 = fsub double %109, %112
%114 = fptosi float %2 to i32
%115 = tail call double @log(i32 %114)
%116 = tail call double @llvm.fmuladd.f64(double %115, double -3.000000e+00, double %113)
%117 = tail call double @log(i32 6)
%118 = fsub double %116, %117
%119 = fsub double %92, %113
%120 = tail call i32 @exp(double %119)
%121 = fsub double %99, %113
%122 = tail call i32 @exp(double %121)
%123 = fsub double %106, %113
%124 = tail call i32 @exp(double %123)
%125 = sub i32 %124, %122
%126 = mul i32 %125, 3
%127 = add i32 %126, %120
%128 = add i32 %127, -1
%129 = tail call double @log(i32 %128)
%130 = fadd double %118, %129
br label %134
131: ; preds = %13
%132 = load double, double* @HUGE_VAL
%133 = fneg double %132
br label %134
134: ; preds = %3, %131, %84, %47, %23, %14, %10
%135 = phi double [ %12, %10 ], [ %22, %14 ], [ %46, %23 ], [ %83, %47 ], [ %130, %84 ], [ %133, %131 ], [ 0.000000e+00, %3 ]
ret double %135
}