#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 log(double);
double rtlchsq(int, double);
int sqrt(double);
double zprob(double);
double critchi(int df, double p) {
  double minchisq = 0.0;
  double maxchisq = 100.0 * p;
  double chisqval, z, y;
  ;
  if (p <= 0.0)
    return (maxchisq);
  else if (p >= 1.0)
    return (0.0);
  if (df == 1) {
    z = zprob(0.5 * p);
    return z * z;
  }
  if (df == 2) {
    y = -log(p);
    return 2 * y;
  }
  chisqval = df / sqrt(p);
  while (maxchisq - minchisq > 0.000001) {
    if (rtlchsq(df, chisqval) < p)
      maxchisq = chisqval;
    else
      minchisq = chisqval;
    chisqval = (maxchisq + minchisq) * 0.5;
  }
  return (chisqval);
}


x86 assembly (clang, -O0):
<critchi>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %edi,-0xc(%rbp)
movsd  %xmm0,-0x18(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xea0(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
jb     1187 <critchi+0x47>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12cb <critchi+0x18b>
movsd  -0x18(%rbp),%xmm0
movsd  0xe74(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     11ab <critchi+0x6b>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12cb <critchi+0x18b>
jmp    11b0 <critchi+0x70>
cmpl   $0x1,-0xc(%rbp)
jne    11e5 <critchi+0xa5>
movsd  0xe56(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
call   1050 <zprob@plt>
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12cb <critchi+0x18b>
cmpl   $0x2,-0xc(%rbp)
jne    122c <critchi+0xec>
movsd  -0x18(%rbp),%xmm0
call   1040 <log@plt>
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xe03(%rip),%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12cb <critchi+0x18b>
mov    -0xc(%rbp),%eax
mov    %eax,-0x44(%rbp)
movsd  -0x18(%rbp),%xmm0
call   1060 <sqrt@plt>
mov    %eax,%ecx
mov    -0x44(%rbp),%eax
cltd
idiv   %ecx
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x28(%rbp),%xmm0
subsd  -0x20(%rbp),%xmm0
movsd  0xdb1(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12c1 <critchi+0x181>
mov    -0xc(%rbp),%edi
movsd  -0x30(%rbp),%xmm0
call   1030 <rtlchsq@plt>
movaps %xmm0,%xmm1
movsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1297 <critchi+0x157>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    12a1 <critchi+0x161>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x28(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  0xd65(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    124d <critchi+0x10d>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<critchi>:
push   %rbx
sub    $0x40,%rsp
movsd  0xeb3(%rip),%xmm1
mulsd  %xmm0,%xmm1
xorpd  %xmm2,%xmm2
ucomisd %xmm0,%xmm2
jae    1188 <critchi+0x48>
ucomisd 0xea5(%rip),%xmm0
jae    118c <critchi+0x4c>
mov    %edi,%ebx
cmp    $0x2,%edi
je     1196 <critchi+0x56>
cmp    $0x1,%ebx
jne    11a9 <critchi+0x69>
mulsd  0xe9f(%rip),%xmm0
call   1050 <zprob@plt>
movapd %xmm0,%xmm2
mulsd  %xmm0,%xmm2
jmp    118c <critchi+0x4c>
movapd %xmm1,%xmm2
movapd %xmm2,%xmm0
add    $0x40,%rsp
pop    %rbx
ret
call   1040 <log@plt>
movapd %xmm0,%xmm2
mulsd  0xe69(%rip),%xmm2
jmp    118c <critchi+0x4c>
movsd  %xmm0,0x28(%rsp)
movapd %xmm1,0x10(%rsp)
call   1060 <sqrt@plt>
movapd 0x10(%rsp),%xmm0
mov    %eax,%ecx
mov    %ebx,%eax
cltd
idiv   %ecx
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
ucomisd 0xe4a(%rip),%xmm0
jbe    118c <critchi+0x4c>
xorpd  %xmm1,%xmm1
movsd  %xmm1,0x8(%rsp)
jmp    122f <critchi+0xef>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
cmpltsd %xmm1,%xmm0
andpd  %xmm0,%xmm2
andnpd 0x10(%rsp),%xmm0
orpd   %xmm2,%xmm0
movapd %xmm0,%xmm2
movsd  0x8(%rsp),%xmm3
addsd  %xmm3,%xmm2
mulsd  0xdff(%rip),%xmm2
movapd %xmm0,%xmm1
subsd  %xmm3,%xmm1
ucomisd 0xdf7(%rip),%xmm1
jbe    118c <critchi+0x4c>
movapd %xmm0,0x10(%rsp)
movapd %xmm2,0x30(%rsp)
mov    %ebx,%edi
movapd %xmm2,%xmm0
call   1030 <rtlchsq@plt>
movapd 0x30(%rsp),%xmm2
movsd  0x28(%rsp),%xmm1
ucomisd %xmm0,%xmm1
ja     11f0 <critchi+0xb0>
movsd  %xmm2,0x8(%rsp)
jmp    11f0 <critchi+0xb0>

LLVM IR (-O0):
define double @critchi(i32 %0, double %1) {
%3 = alloca double
%4 = alloca i32
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
store i32 %0, i32* %4
store double %1, double* %5
store double 0.000000e+00, double* %6
%11 = load double, double* %5
%12 = fmul double 1.000000e+02, %11
store double %12, double* %7
%13 = load double, double* %5
%14 = fcmp ole double %13, 0.000000e+00
br i1 %14, label %15, label %17
15: ; preds = %2
%16 = load double, double* %7
store double %16, double* %3
br label %69
17: ; preds = %2
%18 = load double, double* %5
%19 = fcmp oge double %18, 1.000000e+00
br i1 %19, label %20, label %21
20: ; preds = %17
store double 0.000000e+00, double* %3
br label %69
21: ; preds = %17
br label %22
22: ; preds = %21
%23 = load i32, i32* %4
%24 = icmp eq i32 %23, 1
br i1 %24, label %25, label %32
25: ; preds = %22
%26 = load double, double* %5
%27 = fmul double 5.000000e-01, %26
%28 = call double @zprob(double %27)
store double %28, double* %9
%29 = load double, double* %9
%30 = load double, double* %9
%31 = fmul double %29, %30
store double %31, double* %3
br label %69
32: ; preds = %22
%33 = load i32, i32* %4
%34 = icmp eq i32 %33, 2
br i1 %34, label %35, label %41
35: ; preds = %32
%36 = load double, double* %5
%37 = call double @log(double %36)
%38 = fneg double %37
store double %38, double* %10
%39 = load double, double* %10
%40 = fmul double 2.000000e+00, %39
store double %40, double* %3
br label %69
41: ; preds = %32
%42 = load i32, i32* %4
%43 = load double, double* %5
%44 = call i32 @sqrt(double %43)
%45 = sdiv i32 %42, %44
%46 = sitofp i32 %45 to double
store double %46, double* %8
br label %47
47: ; preds = %62, %41
%48 = load double, double* %7
%49 = load double, double* %6
%50 = fsub double %48, %49
%51 = fcmp ogt double %50, 0x3EB0C6F7A0B5ED8D
br i1 %51, label %52, label %67
52: ; preds = %47
%53 = load i32, i32* %4
%54 = load double, double* %8
%55 = call double @rtlchsq(i32 %53, double %54)
%56 = load double, double* %5
%57 = fcmp olt double %55, %56
br i1 %57, label %58, label %60
58: ; preds = %52
%59 = load double, double* %8
store double %59, double* %7
br label %62
60: ; preds = %52
%61 = load double, double* %8
store double %61, double* %6
br label %62
62: ; preds = %60, %58
%63 = load double, double* %7
%64 = load double, double* %6
%65 = fadd double %63, %64
%66 = fmul double %65, 5.000000e-01
store double %66, double* %8
br label %47
67: ; preds = %47
%68 = load double, double* %8
store double %68, double* %3
br label %69
69: ; preds = %67, %35, %25, %20, %15
%70 = load double, double* %3
ret double %70
}

LLVM IR (-O2):
define double @critchi(i32 %0, double %1) {
%3 = fmul double %1, 1.000000e+02
%4 = fcmp ugt double %1, 0.000000e+00
br i1 %4, label %5, label %32
5: ; preds = %2
%6 = fcmp ult double %1, 1.000000e+00
br i1 %6, label %7, label %32
7: ; preds = %5
switch i32 %0, label %15 [
i32 1, label %8
i32 2, label %12
]
8: ; preds = %7
%9 = fmul double %1, 5.000000e-01
%10 = tail call double @zprob(double %9)
%11 = fmul double %10, %10
br label %32
12: ; preds = %7
%13 = tail call double @log(double %1)
%14 = fmul double %13, -2.000000e+00
br label %32
15: ; preds = %7
%16 = tail call i32 @sqrt(double %1)
%17 = sdiv i32 %0, %16
%18 = sitofp i32 %17 to double
%19 = fcmp ogt double %3, 0x3EB0C6F7A0B5ED8D
br i1 %19, label %20, label %32
20: ; preds = %15, %20
%21 = phi double [ %27, %20 ], [ 0.000000e+00, %15 ]
%22 = phi double [ %29, %20 ], [ %18, %15 ]
%23 = phi double [ %26, %20 ], [ %3, %15 ]
%24 = tail call double @rtlchsq(i32 %0, double %22)
%25 = fcmp olt double %24, %1
%26 = select i1 %25, double %22, double %23
%27 = select i1 %25, double %21, double %22
%28 = fadd double %26, %27
%29 = fmul double %28, 5.000000e-01
%30 = fsub double %26, %27
%31 = fcmp ogt double %30, 0x3EB0C6F7A0B5ED8D
br i1 %31, label %20, label %32
32: ; preds = %20, %15, %5, %2, %12, %8
%33 = phi double [ %11, %8 ], [ %14, %12 ], [ %3, %2 ], [ 0.000000e+00, %5 ], [ %18, %15 ], [ %29, %20 ]
ret double %33
}