#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 gamln1(double);
double log(double);
double gamln(double a) {
  static double d__ = .418938533204673;
  static double c0 = .0833333333333333;
  static double c1 = -.00277777777760991;
  static double c2 = 7.9365066682539e-4;
  static double c3 = -5.9520293135187e-4;
  static double c4 = 8.37308034031215e-4;
  static double c5 = -.00165322962780713;
  int i__1;
  double ret_val, r__1;
  int i__, n;
  double t, w;
  if (a > .8f) {
    goto L10;
  }
  ret_val = gamln1(a) - log(a);
  return ret_val;
L10:
  if (a > 2.25f) {
    goto L20;
  }
  t = a - 0.5 - 0.5;
  ret_val = gamln1(t);
  return ret_val;
L20:
  if (a >= 10.0) {
    goto L30;
  }
  n = a - 1.25;
  t = a;
  w = 1.0;
  i__1 = n;
  for (i__ = 1; i__ <= i__1; ++i__) {
    t += -1.0;
    w = t * w;
  }
  r__1 = t - 1.0;
  ret_val = gamln1(r__1) + log(w);
  return ret_val;
L30:
  r__1 = 1.0 / a;
  t = r__1 * r__1;
  w = (((((c5 * t + c4) * t + c3) * t + c2) * t + c1) * t + c0) / a;
  ret_val = d__ + w + (a - 0.5) * (log(a) - 1.0);
  return ret_val;
}


x86 assembly (clang, -O0):
<gamln>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  0xec6(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1149 <gamln+0x29>
jmp    1182 <gamln+0x62>
movsd  -0x10(%rbp),%xmm0
call   1040 <gamln1@plt>
movsd  %xmm0,-0x48(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1030 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13be <gamln+0x29e>
movsd  -0x10(%rbp),%xmm0
movsd  0xe79(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    119e <gamln+0x7e>
jmp    11de <gamln+0xbe>
movsd  -0x10(%rbp),%xmm0
movsd  0xe65(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe59(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
call   1040 <gamln1@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13be <gamln+0x29e>
movsd  -0x10(%rbp),%xmm0
movsd  0xe2d(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     11fa <gamln+0xda>
jmp    12c0 <gamln+0x1a0>
movsd  -0x10(%rbp),%xmm0
movsd  0xe21(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %eax,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0xdfc(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x30(%rbp),%eax
mov    %eax,-0x14(%rbp)
movl   $0x1,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     1271 <gamln+0x151>
movsd  0xde6(%rip),%xmm0
addsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1236 <gamln+0x116>
movsd  -0x38(%rbp),%xmm0
movsd  0xda2(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
call   1040 <gamln1@plt>
movsd  %xmm0,-0x50(%rbp)
movsd  -0x40(%rbp),%xmm0
call   1030 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13be <gamln+0x29e>
movsd  0xd58(%rip),%xmm0
divsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0x2d77(%rip),%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  0x2d62(%rip),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  0x2d45(%rip),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  0x2d28(%rip),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  0x2d0b(%rip),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  0x2cee(%rip),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
divsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0x2ccc(%rip),%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  0xc95(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1030 <log@plt>
movsd  -0x60(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x58(%rbp),%xmm0
movsd  0xc7d(%rip),%xmm3
subsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gamln>:
sub    $0x18,%rsp
ucomisd 0xed4(%rip),%xmm0
jbe    1178 <gamln+0x58>
ucomisd 0xed2(%rip),%xmm0
jbe    11a7 <gamln+0x87>
ucomisd 0xed8(%rip),%xmm0
jae    11c0 <gamln+0xa0>
movsd  0xf1e(%rip),%xmm1
addsd  %xmm0,%xmm1
cvttsd2si %xmm1,%ecx
test   %ecx,%ecx
jle    1250 <gamln+0x130>
lea    -0x1(%rcx),%edx
mov    %ecx,%eax
and    $0x7,%eax
cmp    $0x7,%edx
jae    125d <gamln+0x13d>
movsd  0xead(%rip),%xmm2
jmp    12b5 <gamln+0x195>
movsd  %xmm0,0x8(%rsp)
call   1040 <gamln1@plt>
movsd  %xmm0,0x10(%rsp)
movsd  0x8(%rsp),%xmm0
call   1030 <log@plt>
movsd  0x10(%rsp),%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
add    $0x18,%rsp
ret
movsd  0xe61(%rip),%xmm1
addsd  %xmm1,%xmm0
addsd  %xmm1,%xmm0
add    $0x18,%rsp
jmp    1040 <gamln1@plt>
movsd  0xe58(%rip),%xmm1
divsd  %xmm0,%xmm1
mulsd  %xmm1,%xmm1
movsd  0xe50(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe4c(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe48(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe44(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe40(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe3c(%rip),%xmm2
divsd  %xmm0,%xmm2
addsd  0xe38(%rip),%xmm2
movsd  %xmm2,0x10(%rsp)
movsd  0xde2(%rip),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
call   1030 <log@plt>
addsd  0xe1b(%rip),%xmm0
mulsd  0x8(%rsp),%xmm0
jmp    1301 <gamln+0x1e1>
movsd  0xdc8(%rip),%xmm2
jmp    12dd <gamln+0x1bd>
and    $0xfffffff8,%ecx
movsd  0xdb8(%rip),%xmm2
movsd  0xdf0(%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    1270 <gamln+0x150>
test   %eax,%eax
je     12dd <gamln+0x1bd>
movsd  0xd9f(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
addsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
add    $0xffffffff,%eax
jne    12d0 <gamln+0x1b0>
movsd  %xmm2,0x8(%rsp)
addsd  0xd75(%rip),%xmm0
call   1040 <gamln1@plt>
movsd  %xmm0,0x10(%rsp)
movsd  0x8(%rsp),%xmm0
call   1030 <log@plt>
addsd  0x10(%rsp),%xmm0
add    $0x18,%rsp
ret

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

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