#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 cdflib_gamma_ln1(double *);
double log(double);
double pow(double, double);
double cdflib_gamma_log(double *a) {
  static const double c0 = .833333333333333e-01;
  static const double c1 = -.277777777760991e-02;
  static const double c2 = .793650666825390e-03;
  static const double c3 = -.595202931351870e-03;
  static const double c4 = .837308034031215e-03;
  static const double c5 = -.165322962780713e-02;
  static const double d = .418938533204673e0;
  double gamln, t, w;
  int i, n;
  double T1;
  if (*a > 0.8e0) {
    goto S10;
  }
  gamln = cdflib_gamma_ln1(a) - log(*a);
  return gamln;
S10:
  if (*a > 2.25e0) {
    goto S20;
  }
  t = *a - 0.5e0 - 0.5e0;
  gamln = cdflib_gamma_ln1(&t);
  return gamln;
S20:
  if (*a >= 10.0e0) {
    goto S40;
  }
  n = (int)(*a - 1.25e0);
  t = *a;
  w = 1.0e0;
  for (i = 1; i <= n; i++) {
    t -= 1.0e0;
    w = t * w;
  }
  T1 = t - 1.0e0;
  gamln = cdflib_gamma_ln1(&T1) + log(w);
  return gamln;
S40:
  t = pow(1.0e0 / *a, 2.0);
  w = (((((c5 * t + c4) * t + c3) * t + c2) * t + c1) * t + c0) / *a;
  gamln = d + w + (*a - 0.5e0) * (log(*a) - 1.0e0);
  return gamln;
}


x86 assembly (clang, -O0):
<cdflib_gamma_log>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xeb4(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    115b <cdflib_gamma_log+0x2b>
jmp    1196 <cdflib_gamma_log+0x66>
mov    -0x10(%rbp),%rdi
call   1030 <cdflib_gamma_ln1@plt>
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
call   1040 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x40(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13e7 <cdflib_gamma_log+0x2b7>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xe62(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11b5 <cdflib_gamma_log+0x85>
jmp    11f7 <cdflib_gamma_log+0xc7>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xe4b(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe3f(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
lea    -0x20(%rbp),%rdi
call   1030 <cdflib_gamma_ln1@plt>
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13e7 <cdflib_gamma_log+0x2b7>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xe11(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1216 <cdflib_gamma_log+0xe6>
jmp    12df <cdflib_gamma_log+0x1af>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xe02(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %eax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xdda(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
movl   $0x1,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x30(%rbp),%eax
jg     1291 <cdflib_gamma_log+0x161>
movsd  -0x20(%rbp),%xmm0
movsd  0xdb5(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1252 <cdflib_gamma_log+0x122>
movsd  -0x20(%rbp),%xmm0
movsd  0xd82(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
lea    -0x38(%rbp),%rdi
call   1030 <cdflib_gamma_ln1@plt>
movsd  %xmm0,-0x48(%rbp)
movsd  -0x28(%rbp),%xmm0
call   1040 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13e7 <cdflib_gamma_log+0x2b7>
mov    -0x10(%rbp),%rax
movsd  0xd35(%rip),%xmm0
divsd  (%rax),%xmm0
movsd  0xd71(%rip),%xmm1
call   1050 <pow@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xd4a(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xd46(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xd21(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xd04(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xce7(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xcca(%rip),%xmm1
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xca9(%rip),%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xc6f(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
call   1040 <log@plt>
movsd  -0x58(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x50(%rbp),%xmm0
movsd  0xc54(%rip),%xmm3
subsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<cdflib_gamma_log>:
push   %rbx
sub    $0x20,%rsp
movsd  (%rdi),%xmm0
ucomisd 0xecf(%rip),%xmm0
jbe    1181 <cdflib_gamma_log+0x61>
ucomisd 0xecd(%rip),%xmm0
jbe    11ab <cdflib_gamma_log+0x8b>
ucomisd 0xed3(%rip),%xmm0
jae    11d0 <cdflib_gamma_log+0xb0>
movsd  0xf15(%rip),%xmm1
addsd  %xmm0,%xmm1
cvttsd2si %xmm1,%ecx
test   %ecx,%ecx
jle    1260 <cdflib_gamma_log+0x140>
lea    -0x1(%rcx),%edx
mov    %ecx,%eax
and    $0x7,%eax
cmp    $0x7,%edx
jae    126d <cdflib_gamma_log+0x14d>
movsd  0xea4(%rip),%xmm2
jmp    12c5 <cdflib_gamma_log+0x1a5>
mov    %rdi,%rbx
call   1030 <cdflib_gamma_ln1@plt>
movsd  %xmm0,0x8(%rsp)
movsd  (%rbx),%xmm0
call   1040 <log@plt>
movsd  0x8(%rsp),%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
jmp    1322 <cdflib_gamma_log+0x202>
movsd  0xe5d(%rip),%xmm1
addsd  %xmm1,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x18(%rsp)
lea    0x18(%rsp),%rdi
call   1030 <cdflib_gamma_ln1@plt>
jmp    1322 <cdflib_gamma_log+0x202>
movsd  0xe48(%rip),%xmm1
divsd  %xmm0,%xmm1
mulsd  %xmm1,%xmm1
movsd  0xe40(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe3c(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe38(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe34(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe30(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe2c(%rip),%xmm2
divsd  %xmm0,%xmm2
addsd  0xe28(%rip),%xmm2
movsd  %xmm2,0x8(%rsp)
movsd  0xdd2(%rip),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rsp)
call   1040 <log@plt>
addsd  0xe0b(%rip),%xmm0
mulsd  0x10(%rsp),%xmm0
jmp    131c <cdflib_gamma_log+0x1fc>
movsd  0xdb8(%rip),%xmm2
jmp    12ed <cdflib_gamma_log+0x1cd>
and    $0xfffffff8,%ecx
movsd  0xda8(%rip),%xmm2
movsd  0xde0(%rip),%xmm1
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
add    $0xfffffff8,%ecx
jne    1280 <cdflib_gamma_log+0x160>
test   %eax,%eax
je     12ed <cdflib_gamma_log+0x1cd>
movsd  0xd8f(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
add    $0xffffffff,%eax
jne    12e0 <cdflib_gamma_log+0x1c0>
movsd  %xmm2,0x10(%rsp)
addsd  0xd65(%rip),%xmm0
movsd  %xmm0,0x18(%rsp)
lea    0x18(%rsp),%rdi
call   1030 <cdflib_gamma_ln1@plt>
movsd  %xmm0,0x8(%rsp)
movsd  0x10(%rsp),%xmm0
call   1040 <log@plt>
addsd  0x8(%rsp),%xmm0
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@cdflib_gamma_log.c0 = internal constant double 0x3FB5555555555553
@cdflib_gamma_log.c1 = internal constant double 0xBF66C16C16BB8412
@cdflib_gamma_log.c2 = internal constant double 0x3F4A019FD4488960
@cdflib_gamma_log.c3 = internal constant double 0xBF4380EC8FF430DF
@cdflib_gamma_log.c4 = internal constant double 0x3F4B6FD94FB94A6B
@cdflib_gamma_log.c5 = internal constant double 0xBF5B1625CBCA1838
@cdflib_gamma_log.d = internal constant double 0x3FDACFE390C97D6E
define double @cdflib_gamma_log(double* %0) {
%2 = alloca double
%3 = alloca double*
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca i32
%8 = alloca i32
%9 = alloca double
store double* %0, double** %3
%10 = load double*, double** %3
%11 = load double, double* %10
%12 = fcmp ogt double %11, 8.000000e-01
br i1 %12, label %13, label %14
13: ; preds = %1
br label %22
14: ; preds = %1
%15 = load double*, double** %3
%16 = call double @cdflib_gamma_ln1(double* %15)
%17 = load double*, double** %3
%18 = load double, double* %17
%19 = call double @log(double %18)
%20 = fsub double %16, %19
store double %20, double* %4
%21 = load double, double* %4
store double %21, double* %2
br label %96
22: ; preds = %13
%23 = load double*, double** %3
%24 = load double, double* %23
%25 = fcmp ogt double %24, 2.250000e+00
br i1 %25, label %26, label %27
26: ; preds = %22
br label %34
27: ; preds = %22
%28 = load double*, double** %3
%29 = load double, double* %28
%30 = fsub double %29, 5.000000e-01
%31 = fsub double %30, 5.000000e-01
store double %31, double* %5
%32 = call double @cdflib_gamma_ln1(double* %5)
store double %32, double* %4
%33 = load double, double* %4
store double %33, double* %2
br label %96
34: ; preds = %26
%35 = load double*, double** %3
%36 = load double, double* %35
%37 = fcmp oge double %36, 1.000000e+01
br i1 %37, label %38, label %39
38: ; preds = %34
br label %67
39: ; preds = %34
%40 = load double*, double** %3
%41 = load double, double* %40
%42 = fsub double %41, 1.250000e+00
%43 = fptosi double %42 to i32
store i32 %43, i32* %8
%44 = load double*, double** %3
%45 = load double, double* %44
store double %45, double* %5
store double 1.000000e+00, double* %6
store i32 1, i32* %7
br label %46
46: ; preds = %56, %39
%47 = load i32, i32* %7
%48 = load i32, i32* %8
%49 = icmp sle i32 %47, %48
br i1 %49, label %50, label %59
50: ; preds = %46
%51 = load double, double* %5
%52 = fsub double %51, 1.000000e+00
store double %52, double* %5
%53 = load double, double* %5
%54 = load double, double* %6
%55 = fmul double %53, %54
store double %55, double* %6
br label %56
56: ; preds = %50
%57 = load i32, i32* %7
%58 = add nsw i32 %57, 1
store i32 %58, i32* %7
br label %46
59: ; preds = %46
%60 = load double, double* %5
%61 = fsub double %60, 1.000000e+00
store double %61, double* %9
%62 = call double @cdflib_gamma_ln1(double* %9)
%63 = load double, double* %6
%64 = call double @log(double %63)
%65 = fadd double %62, %64
store double %65, double* %4
%66 = load double, double* %4
store double %66, double* %2
br label %96
67: ; preds = %38
%68 = load double*, double** %3
%69 = load double, double* %68
%70 = fdiv double 1.000000e+00, %69
%71 = call double @pow(double %70, double 2.000000e+00)
store double %71, double* %5
%72 = load double, double* %5
%73 = call double @llvm.fmuladd.f64(double 0xBF5B1625CBCA1838, double %72, double 0x3F4B6FD94FB94A6B)
%74 = load double, double* %5
%75 = call double @llvm.fmuladd.f64(double %73, double %74, double 0xBF4380EC8FF430DF)
%76 = load double, double* %5
%77 = call double @llvm.fmuladd.f64(double %75, double %76, double 0x3F4A019FD4488960)
%78 = load double, double* %5
%79 = call double @llvm.fmuladd.f64(double %77, double %78, double 0xBF66C16C16BB8412)
%80 = load double, double* %5
%81 = call double @llvm.fmuladd.f64(double %79, double %80, double 0x3FB5555555555553)
%82 = load double*, double** %3
%83 = load double, double* %82
%84 = fdiv double %81, %83
store double %84, double* %6
%85 = load double, double* %6
%86 = fadd double 0x3FDACFE390C97D6E, %85
%87 = load double*, double** %3
%88 = load double, double* %87
%89 = fsub double %88, 5.000000e-01
%90 = load double*, double** %3
%91 = load double, double* %90
%92 = call double @log(double %91)
%93 = fsub double %92, 1.000000e+00
%94 = call double @llvm.fmuladd.f64(double %89, double %93, double %86)
store double %94, double* %4
%95 = load double, double* %4
store double %95, double* %2
br label %96
96: ; preds = %67, %59, %27, %14
%97 = load double, double* %2
ret double %97
}

LLVM IR (-O2):
define double @cdflib_gamma_log(double* %0) {
%2 = alloca double
%3 = alloca double
%4 = bitcast double* %2 to i8*
%5 = bitcast double* %3 to i8*
%6 = load double, double* %0
%7 = fcmp ogt double %6, 8.000000e-01
br i1 %7, label %13, label %8
8: ; preds = %1
%9 = tail call double @cdflib_gamma_ln1(double* %0)
%10 = load double, double* %0
%11 = tail call double @log(double %10)
%12 = fsub double %9, %11
br label %88
13: ; preds = %1
%14 = fcmp ogt double %6, 2.250000e+00
br i1 %14, label %19, label %15
15: ; preds = %13
%16 = fadd double %6, -5.000000e-01
%17 = fadd double %16, -5.000000e-01
store double %17, double* %2
%18 = call double @cdflib_gamma_ln1(double* %2)
br label %88
19: ; preds = %13
%20 = fcmp ult double %6, 1.000000e+01
br i1 %20, label %21, label %74
21: ; preds = %19
%22 = fadd double %6, -1.250000e+00
%23 = fptosi double %22 to i32
%24 = icmp slt i32 %23, 1
br i1 %24, label %67, label %25
25: ; preds = %21
%26 = add i32 %23, -1
%27 = and i32 %23, 7
%28 = icmp ult i32 %26, 7
br i1 %28, label %53, label %29
29: ; preds = %25
%30 = and i32 %23, -8
br label %31
31: ; preds = %31, %29
%32 = phi double [ 1.000000e+00, %29 ], [ %50, %31 ]
%33 = phi double [ %6, %29 ], [ %49, %31 ]
%34 = phi i32 [ 0, %29 ], [ %51, %31 ]
%35 = fadd double %33, -1.000000e+00
%36 = fmul double %32, %35
%37 = fadd double %35, -1.000000e+00
%38 = fmul double %36, %37
%39 = fadd double %37, -1.000000e+00
%40 = fmul double %38, %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 = add i32 %34, 8
%52 = icmp eq i32 %51, %30
br i1 %52, label %53, label %31
53: ; preds = %31, %25
%54 = phi double [ undef, %25 ], [ %49, %31 ]
%55 = phi double [ undef, %25 ], [ %50, %31 ]
%56 = phi double [ 1.000000e+00, %25 ], [ %50, %31 ]
%57 = phi double [ %6, %25 ], [ %49, %31 ]
%58 = icmp eq i32 %27, 0
br i1 %58, label %67, label %59
59: ; preds = %53, %59
%60 = phi double [ %64, %59 ], [ %56, %53 ]
%61 = phi double [ %63, %59 ], [ %57, %53 ]
%62 = phi i32 [ %65, %59 ], [ 0, %53 ]
%63 = fadd double %61, -1.000000e+00
%64 = fmul double %60, %63
%65 = add i32 %62, 1
%66 = icmp eq i32 %65, %27
br i1 %66, label %67, label %59
67: ; preds = %53, %59, %21
%68 = phi double [ %6, %21 ], [ %54, %53 ], [ %63, %59 ]
%69 = phi double [ 1.000000e+00, %21 ], [ %55, %53 ], [ %64, %59 ]
%70 = fadd double %68, -1.000000e+00
store double %70, double* %3
%71 = call double @cdflib_gamma_ln1(double* %3)
%72 = call double @log(double %69)
%73 = fadd double %71, %72
br label %88
74: ; preds = %19
%75 = fdiv double 1.000000e+00, %6
%76 = fmul double %75, %75
%77 = tail call double @llvm.fmuladd.f64(double %76, double 0xBF5B1625CBCA1838, double 0x3F4B6FD94FB94A6B)
%78 = tail call double @llvm.fmuladd.f64(double %77, double %76, double 0xBF4380EC8FF430DF)
%79 = tail call double @llvm.fmuladd.f64(double %78, double %76, double 0x3F4A019FD4488960)
%80 = tail call double @llvm.fmuladd.f64(double %79, double %76, double 0xBF66C16C16BB8412)
%81 = tail call double @llvm.fmuladd.f64(double %80, double %76, double 0x3FB5555555555553)
%82 = fdiv double %81, %6
%83 = fadd double %82, 0x3FDACFE390C97D6E
%84 = fadd double %6, -5.000000e-01
%85 = tail call double @log(double %6)
%86 = fadd double %85, -1.000000e+00
%87 = tail call double @llvm.fmuladd.f64(double %84, double %86, double %83)
br label %88
88: ; preds = %74, %67, %15, %8
%89 = phi double [ %87, %74 ], [ %73, %67 ], [ %18, %15 ], [ %12, %8 ]
ret double %89
}