#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 ChiSqPN(unsigned long, double);
double exp(double);
double sqrt(double);
double ChiSqP(unsigned long degfree, double x2) {
  double p, t;
  unsigned long k, a;
  if (degfree >= 50)
    return ChiSqPN(degfree, x2);
  else {
    p = exp(-x2 / 2);
    if ((degfree & 1) > 0)
      p *= sqrt((x2 + x2) / 3.14159265358979323846264338327950288419716939);
    k = degfree;
    while (k >= 2) {
      p *= x2 / k;
      k -= 2;
    }
    t = p;
    a = degfree;
    while (t > (1e-7 * p)) {
      a += 2;
      t *= x2 / a;
      p += t;
    }
    return p;
  }
}


x86 assembly (clang, -O0):
<ChiSqP>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
cmpq   $0x32,-0x10(%rbp)
jb     1164 <ChiSqP+0x34>
mov    -0x10(%rbp),%rdi
movsd  -0x18(%rbp),%xmm0
call   1040 <ChiSqPN@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    12bd <ChiSqP+0x18d>
movsd  -0x18(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xe78(%rip),%xmm1
divsd  %xmm1,%xmm0
call   1030 <exp@plt>
movsd  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
and    $0x1,%rax
cmp    $0x0,%rax
jbe    11cd <ChiSqP+0x9d>
movsd  -0x18(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  0xe4e(%rip),%xmm1
divsd  %xmm1,%xmm0
call   1050 <sqrt@plt>
mulsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x30(%rbp)
cmpq   $0x2,-0x30(%rbp)
jb     122b <ChiSqP+0xfb>
movsd  -0x18(%rbp),%xmm0
movaps 0xe34(%rip),%xmm2
movq   -0x30(%rbp),%xmm1
punpckldq %xmm2,%xmm1
movapd 0xe33(%rip),%xmm2
subpd  %xmm2,%xmm1
movaps %xmm1,%xmm2
unpckhpd %xmm1,%xmm1
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x30(%rbp),%rax
sub    $0x2,%rax
mov    %rax,-0x30(%rbp)
jmp    11d5 <ChiSqP+0xa5>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xdc6(%rip),%xmm1
mulsd  -0x20(%rbp),%xmm1
ucomisd %xmm1,%xmm0
jbe    12b3 <ChiSqP+0x183>
mov    -0x38(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x38(%rbp)
movsd  -0x18(%rbp),%xmm0
movaps 0xdaf(%rip),%xmm2
movq   -0x38(%rbp),%xmm1
punpckldq %xmm2,%xmm1
movapd 0xdae(%rip),%xmm2
subpd  %xmm2,%xmm1
movaps %xmm1,%xmm2
unpckhpd %xmm1,%xmm1
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    123d <ChiSqP+0x10d>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ChiSqP>:
push   %rbx
sub    $0x10,%rsp
movapd %xmm0,%xmm1
mov    %rdi,%rbx
cmp    $0x32,%rdi
jb     1153 <ChiSqP+0x23>
mov    %rbx,%rdi
movapd %xmm1,%xmm0
add    $0x10,%rsp
pop    %rbx
jmp    1040 <ChiSqPN@plt>
movsd  0xea5(%rip),%xmm0
movsd  %xmm1,(%rsp)
mulsd  %xmm1,%xmm0
call   1030 <exp@plt>
movapd %xmm0,%xmm7
test   $0x1,%bl
je     11a8 <ChiSqP+0x78>
movsd  (%rsp),%xmm0
addsd  %xmm0,%xmm0
divsd  0xe85(%rip),%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     1193 <ChiSqP+0x63>
sqrtsd %xmm0,%xmm0
jmp    11a4 <ChiSqP+0x74>
movsd  %xmm7,0x8(%rsp)
call   1050 <sqrt@plt>
movsd  0x8(%rsp),%xmm7
mulsd  %xmm0,%xmm7
cmp    $0x2,%rbx
jb     11f7 <ChiSqP+0xc7>
lea    -0x2(%rbx),%rcx
test   $0x2,%cl
movsd  (%rsp),%xmm6
jne    1201 <ChiSqP+0xd1>
movq   %rbx,%xmm0
punpckldq 0xe57(%rip),%xmm0
subpd  0xe5f(%rip),%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
addsd  %xmm0,%xmm1
movapd %xmm6,%xmm0
divsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm7
mov    %rcx,%rax
cmp    $0x2,%rcx
jae    120a <ChiSqP+0xda>
jmp    1278 <ChiSqP+0x148>
movsd  (%rsp),%xmm6
jmp    1278 <ChiSqP+0x148>
mov    %rbx,%rax
cmp    $0x2,%rcx
jb     1278 <ChiSqP+0x148>
movdqa 0xe0e(%rip),%xmm0
movapd 0xe16(%rip),%xmm1
nopw   0x0(%rax,%rax,1)
movq   %rax,%xmm2
punpckldq %xmm0,%xmm2
subpd  %xmm1,%xmm2
movapd %xmm2,%xmm3
unpckhpd %xmm2,%xmm3
addsd  %xmm2,%xmm3
movapd %xmm6,%xmm2
divsd  %xmm3,%xmm2
mulsd  %xmm7,%xmm2
lea    -0x2(%rax),%rcx
movq   %rcx,%xmm3
punpckldq %xmm0,%xmm3
subpd  %xmm1,%xmm3
movapd %xmm3,%xmm4
unpckhpd %xmm3,%xmm4
addsd  %xmm3,%xmm4
movapd %xmm6,%xmm7
divsd  %xmm4,%xmm7
mulsd  %xmm2,%xmm7
add    $0xfffffffffffffffc,%rax
cmp    $0x1,%rax
ja     1220 <ChiSqP+0xf0>
movsd  0xd90(%rip),%xmm0
mulsd  %xmm7,%xmm0
ucomisd %xmm0,%xmm7
jbe    12ed <ChiSqP+0x1bd>
add    $0x2,%rbx
movdqa 0xd8a(%rip),%xmm1
movapd 0xd92(%rip),%xmm2
movsd  0xd6a(%rip),%xmm3
movapd %xmm7,%xmm0
nopw   0x0(%rax,%rax,1)
movq   %rbx,%xmm4
punpckldq %xmm1,%xmm4
subpd  %xmm2,%xmm4
movapd %xmm4,%xmm5
unpckhpd %xmm4,%xmm5
addsd  %xmm4,%xmm5
movapd %xmm6,%xmm4
divsd  %xmm5,%xmm4
mulsd  %xmm4,%xmm7
addsd  %xmm7,%xmm0
movapd %xmm0,%xmm4
mulsd  %xmm3,%xmm4
add    $0x2,%rbx
ucomisd %xmm4,%xmm7
ja     12b0 <ChiSqP+0x180>
jmp    12f1 <ChiSqP+0x1c1>
movapd %xmm7,%xmm0
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define double @ChiSqP(i64 %0, double %1) {
%3 = alloca double
%4 = alloca i64
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca i64
%9 = alloca i64
store i64 %0, i64* %4
store double %1, double* %5
%10 = load i64, i64* %4
%11 = icmp uge i64 %10, 50
br i1 %11, label %12, label %16
12: ; preds = %2
%13 = load i64, i64* %4
%14 = load double, double* %5
%15 = call double @ChiSqPN(i64 %13, double %14)
store double %15, double* %3
br label %68
16: ; preds = %2
%17 = load double, double* %5
%18 = fneg double %17
%19 = fdiv double %18, 2.000000e+00
%20 = call double @exp(double %19)
store double %20, double* %6
%21 = load i64, i64* %4
%22 = and i64 %21, 1
%23 = icmp ugt i64 %22, 0
br i1 %23, label %24, label %32
24: ; preds = %16
%25 = load double, double* %5
%26 = load double, double* %5
%27 = fadd double %25, %26
%28 = fdiv double %27, 0x400921FB54442D18
%29 = call double @sqrt(double %28)
%30 = load double, double* %6
%31 = fmul double %30, %29
store double %31, double* %6
br label %32
32: ; preds = %24, %16
%33 = load i64, i64* %4
store i64 %33, i64* %8
br label %34
34: ; preds = %37, %32
%35 = load i64, i64* %8
%36 = icmp uge i64 %35, 2
br i1 %36, label %37, label %46
37: ; preds = %34
%38 = load double, double* %5
%39 = load i64, i64* %8
%40 = uitofp i64 %39 to double
%41 = fdiv double %38, %40
%42 = load double, double* %6
%43 = fmul double %42, %41
store double %43, double* %6
%44 = load i64, i64* %8
%45 = sub i64 %44, 2
store i64 %45, i64* %8
br label %34
46: ; preds = %34
%47 = load double, double* %6
store double %47, double* %7
%48 = load i64, i64* %4
store i64 %48, i64* %9
br label %49
49: ; preds = %54, %46
%50 = load double, double* %7
%51 = load double, double* %6
%52 = fmul double 0x3E7AD7F29ABCAF48, %51
%53 = fcmp ogt double %50, %52
br i1 %53, label %54, label %66
54: ; preds = %49
%55 = load i64, i64* %9
%56 = add i64 %55, 2
store i64 %56, i64* %9
%57 = load double, double* %5
%58 = load i64, i64* %9
%59 = uitofp i64 %58 to double
%60 = fdiv double %57, %59
%61 = load double, double* %7
%62 = fmul double %61, %60
store double %62, double* %7
%63 = load double, double* %7
%64 = load double, double* %6
%65 = fadd double %64, %63
store double %65, double* %6
br label %49
66: ; preds = %49
%67 = load double, double* %6
store double %67, double* %3
br label %68
68: ; preds = %66, %12
%69 = load double, double* %3
ret double %69
}

LLVM IR (-O2):
define double @ChiSqP(i64 %0, double %1) {
%3 = icmp ugt i64 %0, 49
br i1 %3, label %4, label %6
4: ; preds = %2
%5 = tail call double @ChiSqPN(i64 %0, double %1)
br label %60
6: ; preds = %2
%7 = fmul double %1, -5.000000e-01
%8 = tail call double @exp(double %7)
%9 = and i64 %0, 1
%10 = icmp eq i64 %9, 0
br i1 %10, label %16, label %11
11: ; preds = %6
%12 = fadd double %1, %1
%13 = fdiv double %12, 0x400921FB54442D18
%14 = tail call double @sqrt(double %13)
%15 = fmul double %8, %14
br label %16
16: ; preds = %11, %6
%17 = phi double [ %15, %11 ], [ %8, %6 ]
%18 = icmp ugt i64 %0, 1
br i1 %18, label %19, label %33
19: ; preds = %16
%20 = add i64 %0, -2
%21 = and i64 %20, 2
%22 = icmp eq i64 %21, 0
br i1 %22, label %23, label %28
23: ; preds = %19
%24 = uitofp i64 %0 to double
%25 = fdiv double %1, %24
%26 = fmul double %17, %25
%27 = add i64 %0, -2
br label %28
28: ; preds = %23, %19
%29 = phi i64 [ %0, %19 ], [ %27, %23 ]
%30 = phi double [ %17, %19 ], [ %26, %23 ]
%31 = phi double [ undef, %19 ], [ %26, %23 ]
%32 = icmp ult i64 %20, 2
br i1 %32, label %33, label %37
33: ; preds = %28, %37, %16
%34 = phi double [ %17, %16 ], [ %31, %28 ], [ %46, %37 ]
%35 = fmul double %34, 0x3E7AD7F29ABCAF48
%36 = fcmp ogt double %34, %35
br i1 %36, label %49, label %60
37: ; preds = %28, %37
%38 = phi i64 [ %47, %37 ], [ %29, %28 ]
%39 = phi double [ %46, %37 ], [ %30, %28 ]
%40 = uitofp i64 %38 to double
%41 = fdiv double %1, %40
%42 = fmul double %39, %41
%43 = add i64 %38, -2
%44 = uitofp i64 %43 to double
%45 = fdiv double %1, %44
%46 = fmul double %42, %45
%47 = add i64 %38, -4
%48 = icmp ugt i64 %47, 1
br i1 %48, label %37, label %33
49: ; preds = %33, %49
%50 = phi i64 [ %53, %49 ], [ %0, %33 ]
%51 = phi double [ %56, %49 ], [ %34, %33 ]
%52 = phi double [ %57, %49 ], [ %34, %33 ]
%53 = add i64 %50, 2
%54 = uitofp i64 %53 to double
%55 = fdiv double %1, %54
%56 = fmul double %51, %55
%57 = fadd double %52, %56
%58 = fmul double %57, 0x3E7AD7F29ABCAF48
%59 = fcmp ogt double %56, %58
br i1 %59, label %49, label %60
60: ; preds = %49, %33, %4
%61 = phi double [ %5, %4 ], [ %34, %33 ], [ %57, %49 ]
ret double %61
}