#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 */
float log(double);
float gammaln(float xx) {
  static float x, y, tmp, ser;
  static float cof[6] = {76.18009172947146,     -86.50532032941677,
                         24.01409824083091,     -1.231739572450155,
                         0.1208650973866179e-2, -0.5395239384953e-5};
  int j;
  y = x = xx;
  tmp = x + 5.5;
  tmp -= (x + 0.5) * log(tmp);
  ser = 1.000000000190015;
  for (j = 0; j <= 5; j++)
    ser += cof[j] / ++y;
  return -tmp + log(2.5066282746310005 * ser / x);
}


x86 assembly (clang, -O0):
<gammaln>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
movss  %xmm0,0x2f22(%rip)
movss  %xmm0,0x2f1e(%rip)
movss  0x2f12(%rip),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xeca(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0x2efe(%rip)
movss  0x2eee(%rip),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe9e(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movss  0x2ed9(%rip),%xmm0
cvtss2sd %xmm0,%xmm0
call   1030 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x10(%rbp),%xmm0
cvtss2sd %xmm1,%xmm2
movss  0x2ebc(%rip),%xmm1
cvtss2sd %xmm1,%xmm1
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0x2e8d(%rip)
movss  0xe31(%rip),%xmm0
movss  %xmm0,0x2e81(%rip)
movl   $0x0,-0x8(%rbp)
cmpl   $0x5,-0x8(%rbp)
jg     1232 <gammaln+0x122>
movslq -0x8(%rbp),%rcx
lea    0x2e3d(%rip),%rax
movss  (%rax,%rcx,4),%xmm0
movss  0xe00(%rip),%xmm1
addss  0x2e48(%rip),%xmm1
movss  %xmm1,0x2e40(%rip)
divss  %xmm1,%xmm0
addss  0x2e3c(%rip),%xmm0
movss  %xmm0,0x2e34(%rip)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    11de <gammaln+0xce>
movss  0x2e1a(%rip),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x14(%rbp)
movss  0x2e04(%rip),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xdb8(%rip),%xmm0
mulsd  %xmm1,%xmm0
movss  0x2de0(%rip),%xmm1
cvtss2sd %xmm1,%xmm1
divsd  %xmm1,%xmm0
call   1030 <log@plt>
movaps %xmm0,%xmm1
movss  -0x14(%rbp),%xmm0
addss  %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gammaln>:
push   %rax
movss  %xmm0,0x2f13(%rip)
movss  %xmm0,0x2f0f(%rip)
cvtss2sd %xmm0,%xmm1
addss  0xed3(%rip),%xmm0
movss  %xmm0,0x2eff(%rip)
addsd  0xecb(%rip),%xmm1
movsd  %xmm1,(%rsp)
cvtss2sd %xmm0,%xmm0
call   1030 <log@plt>
cvtss2sd %xmm0,%xmm0
mulsd  (%rsp),%xmm0
movss  0x2ed8(%rip),%xmm1
cvtss2sd %xmm1,%xmm1
subsd  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
movss  %xmm0,(%rsp)
movss  %xmm0,0x2ebc(%rip)
movss  0xe84(%rip),%xmm1
movss  0x2ea8(%rip),%xmm0
addss  %xmm1,%xmm0
movaps %xmm0,%xmm2
addss  %xmm1,%xmm2
unpcklps %xmm2,%xmm0
movaps 0xe83(%rip),%xmm3
divps  %xmm0,%xmm3
movaps %xmm3,%xmm0
addss  %xmm1,%xmm0
shufps $0x55,%xmm3,%xmm3
addss  %xmm0,%xmm3
addss  %xmm1,%xmm2
movaps %xmm2,%xmm0
addss  %xmm1,%xmm0
unpcklps %xmm0,%xmm2
movaps 0xe6c(%rip),%xmm4
divps  %xmm2,%xmm4
addss  %xmm4,%xmm3
shufps $0x55,%xmm4,%xmm4
addss  %xmm3,%xmm4
addss  %xmm1,%xmm0
addss  %xmm0,%xmm1
unpcklps %xmm1,%xmm0
movaps 0xe5b(%rip),%xmm2
divps  %xmm0,%xmm2
addss  %xmm2,%xmm4
shufps $0x55,%xmm2,%xmm2
addss  %xmm4,%xmm2
xorps  %xmm0,%xmm0
cvtss2sd %xmm2,%xmm0
mulsd  0xe0d(%rip),%xmm0
movss  %xmm1,0x2e25(%rip)
movss  0x2e19(%rip),%xmm1
cvtss2sd %xmm1,%xmm1
divsd  %xmm1,%xmm0
call   1030 <log@plt>
subss  (%rsp),%xmm0
pop    %rax
ret

LLVM IR (-O0):
@gammaln.x = internal global float 0.000000e+00
@gammaln.y = internal global float 0.000000e+00
@gammaln.tmp = internal global float 0.000000e+00
@gammaln.ser = internal global float 0.000000e+00
@gammaln.cof = internal global [6 x float] [float 0x40530B86A0000000, float 0xC055A05720000000, float 0x4038039C00000000, float 0xBFF3B53480000000, float 0x3F53CD7320000000, float 0xBED6A11820000000]
define float @gammaln(float %0) {
%2 = alloca float
%3 = alloca i32
store float %0, float* %2
%4 = load float, float* %2
store float %4, float* @gammaln.x
store float %4, float* @gammaln.y
%5 = load float, float* @gammaln.x
%6 = fpext float %5 to double
%7 = fadd double %6, 5.500000e+00
%8 = fptrunc double %7 to float
store float %8, float* @gammaln.tmp
%9 = load float, float* @gammaln.x
%10 = fpext float %9 to double
%11 = fadd double %10, 5.000000e-01
%12 = load float, float* @gammaln.tmp
%13 = fpext float %12 to double
%14 = call float @log(double %13)
%15 = fpext float %14 to double
%16 = load float, float* @gammaln.tmp
%17 = fpext float %16 to double
%18 = fneg double %11
%19 = call double @llvm.fmuladd.f64(double %18, double %15, double %17)
%20 = fptrunc double %19 to float
store float %20, float* @gammaln.tmp
store float 1.000000e+00, float* @gammaln.ser
store i32 0, i32* %3
br label %21
21: ; preds = %34, %1
%22 = load i32, i32* %3
%23 = icmp sle i32 %22, 5
br i1 %23, label %24, label %37
24: ; preds = %21
%25 = load i32, i32* %3
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds [6 x float], [6 x float]* @gammaln.cof, i64 0, i64 %26
%28 = load float, float* %27
%29 = load float, float* @gammaln.y
%30 = fadd float %29, 1.000000e+00
store float %30, float* @gammaln.y
%31 = fdiv float %28, %30
%32 = load float, float* @gammaln.ser
%33 = fadd float %32, %31
store float %33, float* @gammaln.ser
br label %34
34: ; preds = %24
%35 = load i32, i32* %3
%36 = add nsw i32 %35, 1
store i32 %36, i32* %3
br label %21
37: ; preds = %21
%38 = load float, float* @gammaln.tmp
%39 = fneg float %38
%40 = load float, float* @gammaln.ser
%41 = fpext float %40 to double
%42 = fmul double 0x40040D931FF62706, %41
%43 = load float, float* @gammaln.x
%44 = fpext float %43 to double
%45 = fdiv double %42, %44
%46 = call float @log(double %45)
%47 = fadd float %39, %46
ret float %47
}

LLVM IR (-O2):
@gammaln.x = internal unnamed_addr global float 0.000000e+00
@gammaln.y = internal unnamed_addr global float 0.000000e+00
@gammaln.tmp = internal unnamed_addr global float 0.000000e+00
define float @gammaln(float %0) {
store float %0, float* @gammaln.x
store float %0, float* @gammaln.y
%2 = fadd float %0, 5.500000e+00
store float %2, float* @gammaln.tmp
%3 = fpext float %0 to double
%4 = fadd double %3, 5.000000e-01
%5 = fpext float %2 to double
%6 = tail call float @log(double %5)
%7 = fpext float %6 to double
%8 = load float, float* @gammaln.tmp
%9 = fpext float %8 to double
%10 = fneg double %4
%11 = tail call double @llvm.fmuladd.f64(double %10, double %7, double %9)
%12 = fptrunc double %11 to float
store float %12, float* @gammaln.tmp
%13 = load float, float* @gammaln.y
%14 = fadd float %13, 1.000000e+00
%15 = fadd float %14, 1.000000e+00
%16 = insertelement <2 x float> poison, float %14, i64 0
%17 = insertelement <2 x float> %16, float %15, i64 1
%18 = fdiv <2 x float> <float 0x40530B86A0000000, float 0xC055A05720000000>, %17
%19 = extractelement <2 x float> %18, i64 0
%20 = fadd float %19, 1.000000e+00
%21 = extractelement <2 x float> %18, i64 1
%22 = fadd float %20, %21
%23 = fadd float %15, 1.000000e+00
%24 = fadd float %23, 1.000000e+00
%25 = insertelement <2 x float> poison, float %23, i64 0
%26 = insertelement <2 x float> %25, float %24, i64 1
%27 = fdiv <2 x float> <float 0x4038039C00000000, float 0xBFF3B53480000000>, %26
%28 = extractelement <2 x float> %27, i64 0
%29 = fadd float %22, %28
%30 = extractelement <2 x float> %27, i64 1
%31 = fadd float %29, %30
%32 = fadd float %24, 1.000000e+00
%33 = fadd float %32, 1.000000e+00
%34 = insertelement <2 x float> poison, float %32, i64 0
%35 = insertelement <2 x float> %34, float %33, i64 1
%36 = fdiv <2 x float> <float 0x3F53CD7320000000, float 0xBED6A11820000000>, %35
%37 = extractelement <2 x float> %36, i64 0
%38 = fadd float %31, %37
%39 = extractelement <2 x float> %36, i64 1
%40 = fadd float %38, %39
store float %33, float* @gammaln.y
%41 = fpext float %40 to double
%42 = fmul double %41, 0x40040D931FF62706
%43 = load float, float* @gammaln.x
%44 = fpext float %43 to double
%45 = fdiv double %42, %44
%46 = tail call float @log(double %45)
%47 = fsub float %46, %12
ret float %47
}