#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 */
int /*<<< orphan*/ EXIT_FAILURE;
int /*<<< orphan*/ exit(int /*<<< orphan*/);
double fabs(double);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *);
double gammafn(double);
double lngammacor(double);
double log(double);
double sin(double);
int /*<<< orphan*/ stderr;
double lngammafn(double x) {
  if (x <= 0 && x == (int)x) {
    fprintf(stderr, "x is 0 or a negative integer");
    exit(EXIT_FAILURE);
  }
  double y = fabs(x);
  if (y <= 10)
    return log(fabs(gammafn(x)));
  if (y > 2.5327372760800758e+305) {
    fprintf(stderr, "Overflow");
    exit(EXIT_FAILURE);
  }
  if (x > 0)
    return 0.918938533204672741780329736406 + (x - 0.5) * log(x) - x +
           lngammacor(x);
  double sinpiy = fabs(sin(3.141592653589793238462643383280 * y));
  if (sinpiy == 0) {
    fprintf(stderr, "UNEXPECTED ERROR: Should never happen!");
    exit(EXIT_FAILURE);
  }
  double ans = 0.225791352644727432363097614947 + (x - 0.5) * log(y) - x -
               log(sinpiy) - lngammacor(y);
  if (fabs((x - (int)(x - 0.5)) * ans / x) < 1.490116119384765696e-8) {
    fprintf(stderr,
            "Answer < 1/2 precision because x is too near a negative integer");
    exit(EXIT_FAILURE);
  }
  return ans;
}


x86 assembly (clang, -O0):
<lngammafn>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movsd  %xmm0,-0x10(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     11bc <lngammafn+0x5c>
movsd  -0x10(%rbp),%xmm0
cvttsd2si -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm1
ucomisd %xmm1,%xmm0
jne    11bc <lngammafn+0x5c>
jp     11bc <lngammafn+0x5c>
mov    0x2e40(%rip),%rax
mov    (%rax),%edi
lea    0xea7(%rip),%rsi
call   1050 <fprintf@plt>
mov    0x2e23(%rip),%rax
mov    (%rax),%edi
call   1080 <exit@plt>
movsd  -0x10(%rbp),%xmm0
movaps 0xe78(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xe27(%rip),%xmm0
ucomisd -0x18(%rbp),%xmm0
jb     1208 <lngammafn+0xa8>
movsd  -0x10(%rbp),%xmm0
call   1030 <gammafn@plt>
movaps 0xe4b(%rip),%xmm1
pand   %xmm1,%xmm0
call   1070 <log@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    1401 <lngammafn+0x2a1>
movsd  -0x18(%rbp),%xmm0
movsd  0xdf3(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1242 <lngammafn+0xe2>
mov    0x2dba(%rip),%rax
mov    (%rax),%edi
lea    0xe3e(%rip),%rsi
call   1050 <fprintf@plt>
mov    0x2d9d(%rip),%rax
mov    (%rax),%edi
call   1080 <exit@plt>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    12b6 <lngammafn+0x156>
movsd  -0x10(%rbp),%xmm0
movsd  0xdbf(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1070 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x38(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  0xda8(%rip),%xmm1
addsd  %xmm1,%xmm0
subsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1040 <lngammacor@plt>
movaps %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1401 <lngammafn+0x2a1>
movsd  0xd52(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
call   1060 <sin@plt>
movaps 0xd71(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1313 <lngammafn+0x1b3>
jp     1313 <lngammafn+0x1b3>
mov    0x2ce9(%rip),%rax
mov    (%rax),%edi
lea    0xd76(%rip),%rsi
call   1050 <fprintf@plt>
mov    0x2ccc(%rip),%rax
mov    (%rax),%edi
call   1080 <exit@plt>
movsd  -0x10(%rbp),%xmm0
movsd  0xd00(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x18(%rbp),%xmm0
call   1070 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  0xce1(%rip),%xmm1
addsd  %xmm1,%xmm0
subsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x20(%rbp),%xmm0
call   1070 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x18(%rbp),%xmm0
call   1040 <lngammacor@plt>
movaps %xmm0,%xmm1
movsd  -0x40(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x10(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
movsd  0xc83(%rip),%xmm2
subsd  %xmm2,%xmm0
cvttsd2si %xmm0,%eax
cvtsi2sd %eax,%xmm0
subsd  %xmm0,%xmm1
mulsd  -0x28(%rbp),%xmm1
divsd  -0x10(%rbp),%xmm1
movaps 0xc82(%rip),%xmm0
pand   %xmm0,%xmm1
movsd  0xc4e(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    13f7 <lngammafn+0x297>
mov    0x2c05(%rip),%rax
mov    (%rax),%edi
lea    0xcb9(%rip),%rsi
call   1050 <fprintf@plt>
mov    0x2be8(%rip),%rax
mov    (%rax),%edi
call   1080 <exit@plt>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<lngammafn>:
sub    $0x58,%rsp
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jb     1182 <lngammafn+0x22>
cvttpd2dq %xmm0,%xmm1
cvtdq2pd %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jne    1182 <lngammafn+0x22>
jnp    12fa <lngammafn+0x19a>
movapd 0xe76(%rip),%xmm2
andpd  %xmm0,%xmm2
movsd  0xe7a(%rip),%xmm1
ucomisd %xmm2,%xmm1
jae    1207 <lngammafn+0xa7>
ucomisd 0xe74(%rip),%xmm2
ja     130c <lngammafn+0x1ac>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
movapd %xmm0,0x10(%rsp)
jbe    121d <lngammafn+0xbd>
movsd  0xe66(%rip),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
call   1070 <log@plt>
mulsd  0x8(%rsp),%xmm0
addsd  0xe61(%rip),%xmm0
movapd 0x10(%rsp),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rsp)
movapd %xmm1,%xmm0
call   1040 <lngammacor@plt>
movapd %xmm0,%xmm2
addsd  0x8(%rsp),%xmm2
jmp    12f1 <lngammafn+0x191>
call   1030 <gammafn@plt>
andpd  0xdec(%rip),%xmm0
add    $0x58,%rsp
jmp    1070 <log@plt>
movsd  0xdfb(%rip),%xmm0
mulsd  %xmm2,%xmm0
movapd %xmm2,0x30(%rsp)
call   1060 <sin@plt>
ucomisd 0xe0c(%rip),%xmm0
jne    1244 <lngammafn+0xe4>
jnp    131e <lngammafn+0x1be>
andpd  0xdb4(%rip),%xmm0
movapd %xmm0,0x40(%rsp)
movsd  0xdce(%rip),%xmm1
addsd  0x10(%rsp),%xmm1
movapd %xmm1,0x20(%rsp)
movapd 0x30(%rsp),%xmm0
call   1070 <log@plt>
mulsd  0x20(%rsp),%xmm0
addsd  0xdb1(%rip),%xmm0
subsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
movapd 0x40(%rsp),%xmm0
call   1070 <log@plt>
movsd  0x8(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
movapd 0x30(%rsp),%xmm0
call   1040 <lngammacor@plt>
movsd  0x8(%rsp),%xmm2
cvttpd2dq 0x20(%rsp),%xmm1
cvtdq2pd %xmm1,%xmm1
subsd  %xmm0,%xmm2
movapd 0x10(%rsp),%xmm3
movapd %xmm3,%xmm0
subsd  %xmm1,%xmm0
mulsd  %xmm2,%xmm0
divsd  %xmm3,%xmm0
andpd  0xd1d(%rip),%xmm0
movsd  0xd4d(%rip),%xmm1
ucomisd %xmm0,%xmm1
ja     1330 <lngammafn+0x1d0>
movapd %xmm2,%xmm0
add    $0x58,%rsp
ret
mov    0x2cdf(%rip),%rax
mov    (%rax),%edi
lea    0xd46(%rip),%rsi
jmp    1340 <lngammafn+0x1e0>
mov    0x2ccd(%rip),%rax
mov    (%rax),%edi
lea    0xd51(%rip),%rsi
jmp    1340 <lngammafn+0x1e0>
mov    0x2cbb(%rip),%rax
mov    (%rax),%edi
lea    0xd48(%rip),%rsi
jmp    1340 <lngammafn+0x1e0>
mov    0x2ca9(%rip),%rax
mov    (%rax),%edi
lea    0xd5d(%rip),%rsi
call   1050 <fprintf@plt>
mov    0x2c8c(%rip),%rax
mov    (%rax),%edi
call   1080 <exit@plt>

LLVM IR (-O0):
@stderr = global i32 0
@.str = [29 x i8] c"x is 0 or a negative integer\00"
@EXIT_FAILURE = global i32 0
@.str.1 = [9 x i8] c"Overflow\00"
@.str.2 = [39 x i8] c"UNEXPECTED ERROR: Should never happen!\00"
@.str.3 = [64 x i8] c"Answer < 1/2 precision because x is too near a negative integer\00"
define double @lngammafn(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
store double %0, double* %3
%7 = load double, double* %3
%8 = fcmp ole double %7, 0.000000e+00
br i1 %8, label %9, label %20
9: ; preds = %1
%10 = load double, double* %3
%11 = load double, double* %3
%12 = fptosi double %11 to i32
%13 = sitofp i32 %12 to double
%14 = fcmp oeq double %10, %13
br i1 %14, label %15, label %20
15: ; preds = %9
%16 = load i32, i32* @stderr
%17 = call i32 @fprintf(i32 %16, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str, i64 0, i64 0))
%18 = load i32, i32* @EXIT_FAILURE
%19 = call i32 @exit(i32 %18)
unreachable
20: ; preds = %9, %1
%21 = load double, double* %3
%22 = call double @llvm.fabs.f64(double %21)
store double %22, double* %4
%23 = load double, double* %4
%24 = fcmp ole double %23, 1.000000e+01
br i1 %24, label %25, label %30
25: ; preds = %20
%26 = load double, double* %3
%27 = call double @gammafn(double %26)
%28 = call double @llvm.fabs.f64(double %27)
%29 = call double @log(double %28)
store double %29, double* %2
br label %97
30: ; preds = %20
%31 = load double, double* %4
%32 = fcmp ogt double %31, 0x7F571547652B82FE
br i1 %32, label %33, label %38
33: ; preds = %30
%34 = load i32, i32* @stderr
%35 = call i32 @fprintf(i32 %34, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0))
%36 = load i32, i32* @EXIT_FAILURE
%37 = call i32 @exit(i32 %36)
unreachable
38: ; preds = %30
%39 = load double, double* %3
%40 = fcmp ogt double %39, 0.000000e+00
br i1 %40, label %41, label %52
41: ; preds = %38
%42 = load double, double* %3
%43 = fsub double %42, 5.000000e-01
%44 = load double, double* %3
%45 = call double @log(double %44)
%46 = call double @llvm.fmuladd.f64(double %43, double %45, double 0x3FED67F1C864BEB5)
%47 = load double, double* %3
%48 = fsub double %46, %47
%49 = load double, double* %3
%50 = call double @lngammacor(double %49)
%51 = fadd double %48, %50
store double %51, double* %2
br label %97
52: ; preds = %38
%53 = load double, double* %4
%54 = fmul double 0x400921FB54442D18, %53
%55 = call double @sin(double %54)
%56 = call double @llvm.fabs.f64(double %55)
store double %56, double* %5
%57 = load double, double* %5
%58 = fcmp oeq double %57, 0.000000e+00
br i1 %58, label %59, label %64
59: ; preds = %52
%60 = load i32, i32* @stderr
%61 = call i32 @fprintf(i32 %60, i8* getelementptr inbounds ([39 x i8], [39 x i8]* @.str.2, i64 0, i64 0))
%62 = load i32, i32* @EXIT_FAILURE
%63 = call i32 @exit(i32 %62)
unreachable
64: ; preds = %52
%65 = load double, double* %3
%66 = fsub double %65, 5.000000e-01
%67 = load double, double* %4
%68 = call double @log(double %67)
%69 = call double @llvm.fmuladd.f64(double %66, double %68, double 0x3FCCE6BB25AA1316)
%70 = load double, double* %3
%71 = fsub double %69, %70
%72 = load double, double* %5
%73 = call double @log(double %72)
%74 = fsub double %71, %73
%75 = load double, double* %4
%76 = call double @lngammacor(double %75)
%77 = fsub double %74, %76
store double %77, double* %6
%78 = load double, double* %3
%79 = load double, double* %3
%80 = fsub double %79, 5.000000e-01
%81 = fptosi double %80 to i32
%82 = sitofp i32 %81 to double
%83 = fsub double %78, %82
%84 = load double, double* %6
%85 = fmul double %83, %84
%86 = load double, double* %3
%87 = fdiv double %85, %86
%88 = call double @llvm.fabs.f64(double %87)
%89 = fcmp olt double %88, 0x3E50000000000000
br i1 %89, label %90, label %95
90: ; preds = %64
%91 = load i32, i32* @stderr
%92 = call i32 @fprintf(i32 %91, i8* getelementptr inbounds ([64 x i8], [64 x i8]* @.str.3, i64 0, i64 0))
%93 = load i32, i32* @EXIT_FAILURE
%94 = call i32 @exit(i32 %93)
unreachable
95: ; preds = %64
%96 = load double, double* %6
store double %96, double* %2
br label %97
97: ; preds = %95, %41, %25
%98 = load double, double* %2
ret double %98
}

LLVM IR (-O2):
@stderr = global i32 0
@.str = [29 x i8] c"x is 0 or a negative integer\00"
@EXIT_FAILURE = global i32 0
@.str.1 = [9 x i8] c"Overflow\00"
@.str.2 = [39 x i8] c"UNEXPECTED ERROR: Should never happen!\00"
@.str.3 = [64 x i8] c"Answer < 1/2 precision because x is too near a negative integer\00"
define double @lngammafn(double %0) {
%2 = fcmp ugt double %0, 0.000000e+00
br i1 %2, label %12, label %3
3: ; preds = %1
%4 = fptosi double %0 to i32
%5 = sitofp i32 %4 to double
%6 = fcmp oeq double %5, %0
br i1 %6, label %7, label %12
7: ; preds = %3
%8 = load i32, i32* @stderr
%9 = tail call i32 @fprintf(i32 %8, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str, i64 0, i64 0))
%10 = load i32, i32* @EXIT_FAILURE
%11 = tail call i32 @exit(i32 %10)
unreachable
12: ; preds = %3, %1
%13 = tail call double @llvm.fabs.f64(double %0)
%14 = fcmp ugt double %13, 1.000000e+01
br i1 %14, label %19, label %15
15: ; preds = %12
%16 = tail call double @gammafn(double %0)
%17 = tail call double @llvm.fabs.f64(double %16)
%18 = tail call double @log(double %17)
br label %66
19: ; preds = %12
%20 = fcmp ogt double %13, 0x7F571547652B82FE
br i1 %20, label %21, label %26
21: ; preds = %19
%22 = load i32, i32* @stderr
%23 = tail call i32 @fprintf(i32 %22, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0))
%24 = load i32, i32* @EXIT_FAILURE
%25 = tail call i32 @exit(i32 %24)
unreachable
26: ; preds = %19
%27 = fcmp ogt double %0, 0.000000e+00
br i1 %27, label %28, label %35
28: ; preds = %26
%29 = fadd double %0, -5.000000e-01
%30 = tail call double @log(double %0)
%31 = tail call double @llvm.fmuladd.f64(double %29, double %30, double 0x3FED67F1C864BEB5)
%32 = fsub double %31, %0
%33 = tail call double @lngammacor(double %0)
%34 = fadd double %33, %32
br label %66
35: ; preds = %26
%36 = fmul double %13, 0x400921FB54442D18
%37 = tail call double @sin(double %36)
%38 = fcmp oeq double %37, 0.000000e+00
br i1 %38, label %39, label %44
39: ; preds = %35
%40 = load i32, i32* @stderr
%41 = tail call i32 @fprintf(i32 %40, i8* getelementptr inbounds ([39 x i8], [39 x i8]* @.str.2, i64 0, i64 0))
%42 = load i32, i32* @EXIT_FAILURE
%43 = tail call i32 @exit(i32 %42)
unreachable
44: ; preds = %35
%45 = tail call double @llvm.fabs.f64(double %37)
%46 = fadd double %0, -5.000000e-01
%47 = tail call double @log(double %13)
%48 = tail call double @llvm.fmuladd.f64(double %46, double %47, double 0x3FCCE6BB25AA1316)
%49 = fsub double %48, %0
%50 = tail call double @log(double %45)
%51 = fsub double %49, %50
%52 = tail call double @lngammacor(double %13)
%53 = fsub double %51, %52
%54 = fptosi double %46 to i32
%55 = sitofp i32 %54 to double
%56 = fsub double %0, %55
%57 = fmul double %56, %53
%58 = fdiv double %57, %0
%59 = tail call double @llvm.fabs.f64(double %58)
%60 = fcmp olt double %59, 0x3E50000000000000
br i1 %60, label %61, label %66
61: ; preds = %44
%62 = load i32, i32* @stderr
%63 = tail call i32 @fprintf(i32 %62, i8* getelementptr inbounds ([64 x i8], [64 x i8]* @.str.3, i64 0, i64 0))
%64 = load i32, i32* @EXIT_FAILURE
%65 = tail call i32 @exit(i32 %64)
unreachable
66: ; preds = %44, %28, %15
%67 = phi double [ %18, %15 ], [ %34, %28 ], [ %53, %44 ]
ret double %67
}