#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 log(double);
double logGamma(double x) {
  int k;
  double s, t, y;
  y = x;
  for (k = 16; y < 16.0; --k) {
    y += 1.0;
  }
  s = y + 2.269488974204959960;
  s = y + 1.517473649153287398 / s;
  s = y + 1.011523068126841711 / s;
  s = y + 0.525606469002695417 / s;
  s = y + 0.252380952380952380 / s;
  s = y + 0.033333333333333333 / s;
  s = 0.083333333333333333 / s;
  s = s + 0.91893853320467 - y + (y - 0.5) * log(y);
  t = 1.0;
  for (++k; k <= 16; ++k) {
    y -= 1.0;
    t *= y;
  }
  s -= log(t);
  return s;
}


x86 assembly (clang, -O0):
<logGamma>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movl   $0x10,-0xc(%rbp)
movsd  0xeca(%rip),%xmm0
ucomisd -0x28(%rbp),%xmm0
jbe    1161 <logGamma+0x51>
movsd  0xebf(%rip),%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
jmp    112e <logGamma+0x1e>
movsd  0xee7(%rip),%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xec8(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xea5(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xe82(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xe5f(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xe3c(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xe1e(%rip),%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xe04(%rip),%xmm0
addsd  -0x18(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xde0(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x28(%rbp),%xmm0
call   1030 <log@plt>
movsd  -0x38(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x30(%rbp),%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xda3(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x10,-0xc(%rbp)
jg     12b0 <logGamma+0x1a0>
movsd  -0x28(%rbp),%xmm0
movsd  0xd7e(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1273 <logGamma+0x163>
movsd  -0x20(%rbp),%xmm0
call   1030 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x18(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<logGamma>:
push   %rbx
sub    $0x10,%rsp
movsd  0xee3(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    11a8 <logGamma+0x98>
mov    $0x10,%ebx
nopl   0x0(%rax)
addsd  0xed0(%rip),%xmm0
add    $0xffffffff,%ebx
ucomisd %xmm0,%xmm1
ja     1130 <logGamma+0x20>
movsd  %xmm0,0x8(%rsp)
call   1030 <log@plt>
lea    0x1(%rbx),%eax
cmp    $0x10,%eax
jg     11b3 <logGamma+0xa3>
mov    %ebx,%ecx
neg    %ecx
test   $0x7,%cl
je     126c <logGamma+0x15c>
mov    $0x1,%cl
sub    %al,%cl
movzbl %cl,%eax
and    $0x7,%eax
neg    %eax
movsd  0xe93(%rip),%xmm4
xor    %ecx,%ecx
movsd  0xe91(%rip),%xmm2
movsd  0x8(%rsp),%xmm3
movapd %xmm3,%xmm1
nopl   0x0(%rax)
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
add    $0xffffffff,%ecx
cmp    %ecx,%eax
jne    1190 <logGamma+0x80>
mov    %ebx,%eax
sub    %ecx,%eax
jmp    1280 <logGamma+0x170>
movsd  %xmm0,0x8(%rsp)
call   1030 <log@plt>
movsd  0x8(%rsp),%xmm3
movsd  0xe47(%rip),%xmm4
movsd  0xe4f(%rip),%xmm1
addsd  %xmm3,%xmm1
mulsd  %xmm0,%xmm1
movsd  0xe47(%rip),%xmm0
addsd  %xmm3,%xmm0
movsd  0xe43(%rip),%xmm2
divsd  %xmm0,%xmm2
addsd  %xmm3,%xmm2
movsd  0xe3b(%rip),%xmm0
divsd  %xmm2,%xmm0
addsd  %xmm3,%xmm0
movsd  0xe33(%rip),%xmm2
divsd  %xmm0,%xmm2
addsd  %xmm3,%xmm2
movsd  0xe2b(%rip),%xmm0
divsd  %xmm2,%xmm0
addsd  %xmm3,%xmm0
movsd  0xe23(%rip),%xmm2
divsd  %xmm0,%xmm2
addsd  %xmm3,%xmm2
movsd  0xe1b(%rip),%xmm0
divsd  %xmm2,%xmm0
addsd  0xe17(%rip),%xmm0
subsd  %xmm3,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rsp)
movapd %xmm4,%xmm0
call   1030 <log@plt>
movsd  0x8(%rsp),%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
add    $0x10,%rsp
pop    %rbx
ret
movsd  0xd94(%rip),%xmm4
movsd  0x8(%rsp),%xmm3
movapd %xmm3,%xmm1
mov    %ebx,%eax
add    $0xfffffff7,%ebx
cmp    $0x7,%ebx
jb     11c1 <logGamma+0xb1>
add    $0xfffffff0,%eax
movsd  0xd79(%rip),%xmm2
nopw   0x0(%rax,%rax,1)
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm4
add    $0x8,%eax
jne    12a0 <logGamma+0x190>
jmp    11c1 <logGamma+0xb1>

LLVM IR (-O0):
define double @logGamma(double %0) {
%2 = alloca double
%3 = alloca i32
%4 = alloca double
%5 = alloca double
%6 = alloca double
store double %0, double* %2
%7 = load double, double* %2
store double %7, double* %6
store i32 16, i32* %3
br label %8
8: ; preds = %14, %1
%9 = load double, double* %6
%10 = fcmp olt double %9, 1.600000e+01
br i1 %10, label %11, label %17
11: ; preds = %8
%12 = load double, double* %6
%13 = fadd double %12, 1.000000e+00
store double %13, double* %6
br label %14
14: ; preds = %11
%15 = load i32, i32* %3
%16 = add nsw i32 %15, -1
store i32 %16, i32* %3
br label %8
17: ; preds = %8
%18 = load double, double* %6
%19 = fadd double %18, 0x400227E9D5D6BE3D
store double %19, double* %4
%20 = load double, double* %6
%21 = load double, double* %4
%22 = fdiv double 0x3FF8479272FA7B7C, %21
%23 = fadd double %20, %22
store double %23, double* %4
%24 = load double, double* %6
%25 = load double, double* %4
%26 = fdiv double 0x3FF02F32D00C11E1, %25
%27 = fadd double %24, %26
store double %27, double* %4
%28 = load double, double* %6
%29 = load double, double* %4
%30 = fdiv double 0x3FE0D1C4A85DD7FA, %29
%31 = fadd double %28, %30
store double %31, double* %4
%32 = load double, double* %6
%33 = load double, double* %4
%34 = fdiv double 0x3FD0270270270270, %33
%35 = fadd double %32, %34
store double %35, double* %4
%36 = load double, double* %6
%37 = load double, double* %4
%38 = fdiv double 0x3FA1111111111111, %37
%39 = fadd double %36, %38
store double %39, double* %4
%40 = load double, double* %4
%41 = fdiv double 0x3FB5555555555555, %40
store double %41, double* %4
%42 = load double, double* %4
%43 = fadd double %42, 0x3FED67F1C864BE9C
%44 = load double, double* %6
%45 = fsub double %43, %44
%46 = load double, double* %6
%47 = fsub double %46, 5.000000e-01
%48 = load double, double* %6
%49 = call double @log(double %48)
%50 = call double @llvm.fmuladd.f64(double %47, double %49, double %45)
store double %50, double* %4
store double 1.000000e+00, double* %5
%51 = load i32, i32* %3
%52 = add nsw i32 %51, 1
store i32 %52, i32* %3
br label %53
53: ; preds = %62, %17
%54 = load i32, i32* %3
%55 = icmp sle i32 %54, 16
br i1 %55, label %56, label %65
56: ; preds = %53
%57 = load double, double* %6
%58 = fsub double %57, 1.000000e+00
store double %58, double* %6
%59 = load double, double* %6
%60 = load double, double* %5
%61 = fmul double %60, %59
store double %61, double* %5
br label %62
62: ; preds = %56
%63 = load i32, i32* %3
%64 = add nsw i32 %63, 1
store i32 %64, i32* %3
br label %53
65: ; preds = %53
%66 = load double, double* %5
%67 = call double @log(double %66)
%68 = load double, double* %4
%69 = fsub double %68, %67
store double %69, double* %4
%70 = load double, double* %4
ret double %70
}

LLVM IR (-O2):
define double @logGamma(double %0) {
%2 = fcmp olt double %0, 1.600000e+01
br i1 %2, label %5, label %3
3: ; preds = %1
%4 = tail call double @log(double %0)
br label %57
5: ; preds = %1, %5
%6 = phi double [ %8, %5 ], [ %0, %1 ]
%7 = phi i32 [ %9, %5 ], [ 16, %1 ]
%8 = fadd double %6, 1.000000e+00
%9 = add nsw i32 %7, -1
%10 = fcmp olt double %8, 1.600000e+01
br i1 %10, label %5, label %11
11: ; preds = %5
%12 = tail call double @log(double %8)
%13 = icmp slt i32 %7, 17
br i1 %13, label %14, label %57
14: ; preds = %11
%15 = sub i32 1, %7
%16 = and i32 %15, 7
%17 = icmp eq i32 %16, 0
br i1 %17, label %28, label %18
18: ; preds = %14, %18
%19 = phi double [ %24, %18 ], [ %8, %14 ]
%20 = phi double [ %25, %18 ], [ 1.000000e+00, %14 ]
%21 = phi i32 [ %23, %18 ], [ %9, %14 ]
%22 = phi i32 [ %26, %18 ], [ 0, %14 ]
%23 = add i32 %21, 1
%24 = fadd double %19, -1.000000e+00
%25 = fmul double %20, %24
%26 = add i32 %22, 1
%27 = icmp eq i32 %26, %16
br i1 %27, label %28, label %18
28: ; preds = %18, %14
%29 = phi double [ undef, %14 ], [ %25, %18 ]
%30 = phi double [ %8, %14 ], [ %24, %18 ]
%31 = phi double [ 1.000000e+00, %14 ], [ %25, %18 ]
%32 = phi i32 [ %9, %14 ], [ %23, %18 ]
%33 = add i32 %7, -10
%34 = icmp ult i32 %33, 7
br i1 %34, label %57, label %35
35: ; preds = %28, %35
%36 = phi double [ %54, %35 ], [ %30, %28 ]
%37 = phi double [ %55, %35 ], [ %31, %28 ]
%38 = phi i32 [ %53, %35 ], [ %32, %28 ]
%39 = fadd double %36, -1.000000e+00
%40 = fmul double %37, %39
%41 = fadd double %39, -1.000000e+00
%42 = fmul double %40, %41
%43 = fadd double %41, -1.000000e+00
%44 = fmul double %42, %43
%45 = fadd double %43, -1.000000e+00
%46 = fmul double %44, %45
%47 = fadd double %45, -1.000000e+00
%48 = fmul double %46, %47
%49 = fadd double %47, -1.000000e+00
%50 = fmul double %48, %49
%51 = fadd double %49, -1.000000e+00
%52 = fmul double %50, %51
%53 = add i32 %38, 8
%54 = fadd double %51, -1.000000e+00
%55 = fmul double %52, %54
%56 = icmp eq i32 %53, 16
br i1 %56, label %57, label %35
57: ; preds = %28, %35, %3, %11
%58 = phi double [ %12, %11 ], [ %4, %3 ], [ %12, %35 ], [ %12, %28 ]
%59 = phi double [ %8, %11 ], [ %0, %3 ], [ %8, %35 ], [ %8, %28 ]
%60 = phi double [ 1.000000e+00, %11 ], [ 1.000000e+00, %3 ], [ %29, %28 ], [ %55, %35 ]
%61 = fadd double %59, -5.000000e-01
%62 = fadd double %59, 0x400227E9D5D6BE3D
%63 = fdiv double 0x3FF8479272FA7B7C, %62
%64 = fadd double %59, %63
%65 = fdiv double 0x3FF02F32D00C11E1, %64
%66 = fadd double %59, %65
%67 = fdiv double 0x3FE0D1C4A85DD7FA, %66
%68 = fadd double %59, %67
%69 = fdiv double 0x3FD0270270270270, %68
%70 = fadd double %59, %69
%71 = fdiv double 0x3FA1111111111111, %70
%72 = fadd double %59, %71
%73 = fdiv double 0x3FB5555555555555, %72
%74 = fadd double %73, 0x3FED67F1C864BE9C
%75 = fsub double %74, %59
%76 = tail call double @llvm.fmuladd.f64(double %61, double %58, double %75)
%77 = tail call double @log(double %60)
%78 = fsub double %76, %77
ret double %78
}