#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 lgamma(double z) {
  double x = 0;
  x += 0.1659470187408462e-06 / (z + 7);
  x += 0.9934937113930748e-05 / (z + 6);
  x -= 0.1385710331296526 / (z + 5);
  x += 12.50734324009056 / (z + 4);
  x -= 176.6150291498386 / (z + 3);
  x += 771.3234287757674 / (z + 2);
  x -= 1259.139216722289 / (z + 1);
  x += 676.5203681218835 / z;
  x += 0.9999999999995183;
  return log(x) - 5.58106146679532777 - z + (z - 0.5) * log(z + 6.5);
}


x86 assembly (clang, -O0):
<lgamma>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movsd  %xmm0,-0x8(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xf63(%rip),%xmm1
addsd  -0x8(%rbp),%xmm1
movsd  0xf4e(%rip),%xmm0
divsd  %xmm1,%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xf30(%rip),%xmm1
addsd  -0x8(%rbp),%xmm1
movsd  0xf1b(%rip),%xmm0
divsd  %xmm1,%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xefd(%rip),%xmm0
addsd  -0x8(%rbp),%xmm0
movsd  0xee8(%rip),%xmm1
divsd  %xmm0,%xmm1
movsd  -0x10(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xec6(%rip),%xmm1
addsd  -0x8(%rbp),%xmm1
movsd  0xeb1(%rip),%xmm0
divsd  %xmm1,%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xe93(%rip),%xmm0
addsd  -0x8(%rbp),%xmm0
movsd  0xe7e(%rip),%xmm1
divsd  %xmm0,%xmm1
movsd  -0x10(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xe5c(%rip),%xmm1
addsd  -0x8(%rbp),%xmm1
movsd  0xe47(%rip),%xmm0
divsd  %xmm1,%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xe29(%rip),%xmm0
addsd  -0x8(%rbp),%xmm0
movsd  0xe14(%rip),%xmm1
divsd  %xmm0,%xmm1
movsd  -0x10(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xdf2(%rip),%xmm0
divsd  -0x8(%rbp),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xdd3(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1030 <log@plt>
movsd  0xdaf(%rip),%xmm1
subsd  %xmm1,%xmm0
subsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  0xd8c(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xd73(%rip),%xmm0
addsd  -0x8(%rbp),%xmm0
call   1030 <log@plt>
movsd  -0x20(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x18(%rbp),%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<lgamma>:
sub    $0x28,%rsp
movapd %xmm0,%xmm4
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
movapd 0xed8(%rip),%xmm0
addpd  %xmm1,%xmm0
movapd 0xedc(%rip),%xmm2
divpd  %xmm0,%xmm2
movapd %xmm2,%xmm3
unpckhpd %xmm2,%xmm3
xorpd  %xmm0,%xmm0
addsd  %xmm3,%xmm0
addsd  %xmm2,%xmm0
movapd 0xecc(%rip),%xmm2
addpd  %xmm1,%xmm2
movapd 0xed0(%rip),%xmm3
divpd  %xmm2,%xmm3
movapd %xmm3,%xmm2
unpckhpd %xmm3,%xmm2
subsd  %xmm2,%xmm0
addpd  0xec8(%rip),%xmm1
addsd  %xmm3,%xmm0
movapd 0xecc(%rip),%xmm2
divpd  %xmm1,%xmm2
movapd %xmm2,%xmm1
unpckhpd %xmm2,%xmm1
subsd  %xmm1,%xmm0
addsd  %xmm2,%xmm0
movsd  0xed0(%rip),%xmm1
movapd %xmm4,0x10(%rsp)
addsd  %xmm4,%xmm1
unpcklpd %xmm1,%xmm4
movapd 0xeaa(%rip),%xmm1
divpd  %xmm4,%xmm1
movapd %xmm1,%xmm2
unpckhpd %xmm1,%xmm2
subsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
addsd  0xea6(%rip),%xmm0
call   1030 <log@plt>
addsd  0xea1(%rip),%xmm0
movapd 0x10(%rsp),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0xe91(%rip),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rsp)
addsd  0xe88(%rip),%xmm1
movapd %xmm1,%xmm0
call   1030 <log@plt>
mulsd  (%rsp),%xmm0
addsd  0x8(%rsp),%xmm0
add    $0x28,%rsp
ret

LLVM IR (-O0):
define double @lgamma(double %0) {
%2 = alloca double
%3 = alloca double
store double %0, double* %2
store double 0.000000e+00, double* %3
%4 = load double, double* %2
%5 = fadd double %4, 7.000000e+00
%6 = fdiv double 0x3E8645E569E1DBC8, %5
%7 = load double, double* %3
%8 = fadd double %7, %6
store double %8, double* %3
%9 = load double, double* %2
%10 = fadd double %9, 6.000000e+00
%11 = fdiv double 0x3EE4D5C75C187EE3, %10
%12 = load double, double* %3
%13 = fadd double %12, %11
store double %13, double* %3
%14 = load double, double* %2
%15 = fadd double %14, 5.000000e+00
%16 = fdiv double 0x3FC1BCB213BB7E41, %15
%17 = load double, double* %3
%18 = fsub double %17, %16
store double %18, double* %3
%19 = load double, double* %2
%20 = fadd double %19, 4.000000e+00
%21 = fdiv double 0x402903C27E40123E, %20
%22 = load double, double* %3
%23 = fadd double %22, %21
store double %23, double* %3
%24 = load double, double* %2
%25 = fadd double %24, 3.000000e+00
%26 = fdiv double 0x406613AE519C9497, %25
%27 = load double, double* %3
%28 = fsub double %27, %26
store double %28, double* %3
%29 = load double, double* %2
%30 = fadd double %29, 2.000000e+00
%31 = fdiv double 0x40881A9661D3740D, %30
%32 = load double, double* %3
%33 = fadd double %32, %31
store double %33, double* %3
%34 = load double, double* %2
%35 = fadd double %34, 1.000000e+00
%36 = fdiv double 0x4093AC8E8ED41526, %35
%37 = load double, double* %3
%38 = fsub double %37, %36
store double %38, double* %3
%39 = load double, double* %2
%40 = fdiv double 0x40852429B6C30AF7, %39
%41 = load double, double* %3
%42 = fadd double %41, %40
store double %42, double* %3
%43 = load double, double* %3
%44 = fadd double %43, 0x3FEFFFFFFFFFEF0D
store double %44, double* %3
%45 = load double, double* %3
%46 = call double @log(double %45)
%47 = fsub double %46, 0x40165301C6F3682A
%48 = load double, double* %2
%49 = fsub double %47, %48
%50 = load double, double* %2
%51 = fsub double %50, 5.000000e-01
%52 = load double, double* %2
%53 = fadd double %52, 6.500000e+00
%54 = call double @log(double %53)
%55 = call double @llvm.fmuladd.f64(double %51, double %54, double %49)
ret double %55
}

LLVM IR (-O2):
define double @lgamma(double %0) {
%2 = insertelement <2 x double> poison, double %0, i64 0
%3 = shufflevector <2 x double> %2, <2 x double> poison, <2 x i32> zeroinitializer
%4 = fadd <2 x double> %3, <double 6.000000e+00, double 7.000000e+00>
%5 = fdiv <2 x double> <double 0x3EE4D5C75C187EE3, double 0x3E8645E569E1DBC8>, %4
%6 = extractelement <2 x double> %5, i64 1
%7 = fadd double %6, 0.000000e+00
%8 = extractelement <2 x double> %5, i64 0
%9 = fadd double %8, %7
%10 = fadd <2 x double> %3, <double 4.000000e+00, double 5.000000e+00>
%11 = fdiv <2 x double> <double 0x402903C27E40123E, double 0x3FC1BCB213BB7E41>, %10
%12 = extractelement <2 x double> %11, i64 1
%13 = fsub double %9, %12
%14 = extractelement <2 x double> %11, i64 0
%15 = fadd double %14, %13
%16 = fadd <2 x double> %3, <double 2.000000e+00, double 3.000000e+00>
%17 = fdiv <2 x double> <double 0x40881A9661D3740D, double 0x406613AE519C9497>, %16
%18 = extractelement <2 x double> %17, i64 1
%19 = fsub double %15, %18
%20 = extractelement <2 x double> %17, i64 0
%21 = fadd double %20, %19
%22 = fadd double %0, 1.000000e+00
%23 = insertelement <2 x double> %2, double %22, i64 1
%24 = fdiv <2 x double> <double 0x40852429B6C30AF7, double 0x4093AC8E8ED41526>, %23
%25 = extractelement <2 x double> %24, i64 1
%26 = fsub double %21, %25
%27 = extractelement <2 x double> %24, i64 0
%28 = fadd double %27, %26
%29 = fadd double %28, 0x3FEFFFFFFFFFEF0D
%30 = tail call double @log(double %29)
%31 = fadd double %30, 0xC0165301C6F3682A
%32 = fsub double %31, %0
%33 = fadd double %0, -5.000000e-01
%34 = fadd double %0, 6.500000e+00
%35 = tail call double @log(double %34)
%36 = tail call double @llvm.fmuladd.f64(double %33, double %35, double %32)
ret double %36
}