#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 eps(double);
double erfcinv(int);
int /*<<< orphan*/ exit(int);
double exp(double);
double fabs(double);
double gammacdf(double, double, double);
int /*<<< orphan*/ gammapdf(double, double, double);
double log(double);
int /*<<< orphan*/ printf(char *);
double r8_max(int /*<<< orphan*/, double);
double sqrt(int);
double gammainv(double p, double k, double th) {
  double oup, x, xi, del, mu, sigma2, cvar;
  int m;
  if (p < 0. || p > 1.0) {
    printf("Probablity Values can only take values between 0.0 and 1.0");
    exit(1);
  }
  if (k <= 0. || th <= 0.) {
    printf("Gamma Distribution parameters must be positive and real.");
    exit(1);
  }
  if (p == 0.) {
    oup = 0.0;
  }
  if (p == 1.) {
    oup = 1.79e+308;
  }
  if (p > 0.0 && p < 1.0) {
    sigma2 = log(1 + k) - log(k);
    mu = log(k) - 0.5 * sigma2;
    xi = exp(mu - sqrt(2. * sigma2) * erfcinv(2 * p));
    del = 1.0;
    cvar = eps(2.2251e-308);
    m = 0;
    while ((fabs(del) > cvar * xi) && (m < 1000)) {
      del = (gammacdf(xi, k, 1.0) - p) /
            r8_max(gammapdf(xi, k, 1.0), 2.2251e-308);
      m++;
      x = xi - del;
      if (x <= 0.) {
        x = xi / 10.;
        del = xi - x;
      }
      xi = x;
    }
    oup = xi * th;
  }
  return oup;
}


x86 assembly (clang, -O0):
<gammainv>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
movsd  %xmm2,-0x18(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x8(%rbp),%xmm0
ja     11df <gammainv+0x3f>
movsd  -0x8(%rbp),%xmm0
movsd  0xe2b(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11f5 <gammainv+0x55>
lea    0xe5a(%rip),%rdi
call   1070 <printf@plt>
mov    $0x1,%edi
call   10c0 <exit@plt>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jae    1211 <gammainv+0x71>
xorps  %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
jb     1227 <gammainv+0x87>
lea    0xe63(%rip),%rdi
call   1070 <printf@plt>
mov    $0x1,%edi
call   10c0 <exit@plt>
movsd  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1247 <gammainv+0xa7>
jp     1247 <gammainv+0xa7>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  0xdac(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1271 <gammainv+0xd1>
jp     1271 <gammainv+0xd1>
movsd  0xd9c(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    148d <gammainv+0x2ed>
movsd  0xd75(%rip),%xmm0
ucomisd -0x8(%rbp),%xmm0
jbe    148d <gammainv+0x2ed>
movsd  0xd62(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
call   10a0 <log@plt>
movsd  %xmm0,-0x70(%rbp)
movsd  -0x10(%rbp),%xmm0
call   10a0 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x70(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x10(%rbp),%xmm0
call   10a0 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
movsd  0xd3e(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  0xd17(%rip),%xmm0
mulsd  -0x48(%rbp),%xmm0
cvttsd2si %xmm0,%edi
call   10b0 <sqrt@plt>
movsd  %xmm0,-0x60(%rbp)
movsd  0xcfc(%rip),%xmm0
mulsd  -0x8(%rbp),%xmm0
cvttsd2si %xmm0,%edi
call   1040 <erfcinv@plt>
movsd  -0x68(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x60(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
call   1090 <exp@plt>
movsd  %xmm0,-0x30(%rbp)
movsd  0xc98(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0xc9b(%rip),%xmm0
call   1050 <eps@plt>
movsd  %xmm0,-0x50(%rbp)
movl   $0x0,-0x54(%rbp)
movsd  -0x38(%rbp),%xmm0
movaps 0xc9e(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  -0x50(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
xor    %eax,%eax
ucomisd %xmm1,%xmm0
mov    %al,-0x71(%rbp)
jbe    13bc <gammainv+0x21c>
cmpl   $0x3e8,-0x54(%rbp)
setl   %al
mov    %al,-0x71(%rbp)
mov    -0x71(%rbp),%al
test   $0x1,%al
jne    13cc <gammainv+0x22c>
jmp    147e <gammainv+0x2de>
movsd  -0x30(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
movsd  0xc22(%rip),%xmm2
call   1030 <gammacdf@plt>
subsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
movsd  0xc01(%rip),%xmm2
call   1060 <gammapdf@plt>
mov    %eax,%edi
movsd  0xc02(%rip),%xmm0
call   1080 <r8_max@plt>
movaps %xmm0,%xmm1
movsd  -0x80(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x54(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x28(%rbp),%xmm0
jb     146f <gammainv+0x2cf>
movsd  -0x30(%rbp),%xmm0
movsd  0xbd1(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    1386 <gammainv+0x1e6>
movsd  -0x30(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gammainv>:
push   %rbx
sub    $0x50,%rsp
movsd  %xmm1,0x10(%rsp)
movapd %xmm0,%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
ja     13d2 <gammainv+0x232>
ucomisd 0xe3b(%rip),%xmm1
ja     13d2 <gammainv+0x232>
xorpd  %xmm0,%xmm0
ucomisd 0x10(%rsp),%xmm0
jae    13db <gammainv+0x23b>
ucomisd %xmm2,%xmm0
jae    13db <gammainv+0x23b>
movsd  0xe13(%rip),%xmm0
cmpeqsd %xmm1,%xmm0
movsd  0xe0e(%rip),%xmm3
andpd  %xmm0,%xmm3
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jbe    13c8 <gammainv+0x228>
movsd  0xdec(%rip),%xmm4
ucomisd %xmm1,%xmm4
jbe    13c8 <gammainv+0x228>
movsd  %xmm2,0x30(%rsp)
movsd  0x10(%rsp),%xmm0
addsd  %xmm4,%xmm0
movsd  %xmm1,0x18(%rsp)
call   10a0 <log@plt>
movsd  %xmm0,0x8(%rsp)
movsd  0x10(%rsp),%xmm0
call   10a0 <log@plt>
movsd  0x8(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0x10(%rsp),%xmm0
call   10a0 <log@plt>
movsd  0xda3(%rip),%xmm1
movsd  0x8(%rsp),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,0x20(%rsp)
addsd  %xmm2,%xmm2
cvttsd2si %xmm2,%edi
call   10b0 <sqrt@plt>
movsd  %xmm0,0x8(%rsp)
movsd  0x18(%rsp),%xmm0
addsd  %xmm0,%xmm0
cvttsd2si %xmm0,%edi
call   1040 <erfcinv@plt>
mulsd  0x8(%rsp),%xmm0
movsd  0x20(%rsp),%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
call   1090 <exp@plt>
movsd  %xmm0,0x8(%rsp)
movsd  0xd4a(%rip),%xmm0
call   1050 <eps@plt>
movsd  0x8(%rsp),%xmm2
movapd %xmm2,%xmm1
movsd  %xmm0,0x38(%rsp)
mulsd  %xmm0,%xmm1
movsd  0xd11(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    13be <gammainv+0x21e>
xor    %ebx,%ebx
movapd %xmm2,%xmm3
nop
movsd  %xmm2,0x8(%rsp)
movapd %xmm3,0x20(%rsp)
movapd %xmm2,%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0xce2(%rip),%xmm2
call   1030 <gammacdf@plt>
subsd  0x18(%rsp),%xmm0
movapd %xmm0,0x40(%rsp)
movsd  0x8(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0xcbd(%rip),%xmm2
call   1060 <gammapdf@plt>
mov    %eax,%edi
movsd  0xcc6(%rip),%xmm0
call   1080 <r8_max@plt>
movapd 0x40(%rsp),%xmm1
movapd 0x20(%rsp),%xmm3
divsd  %xmm0,%xmm1
subsd  %xmm1,%xmm3
xorpd  %xmm0,%xmm0
ucomisd %xmm3,%xmm0
jb     138f <gammainv+0x1ef>
movsd  0x8(%rsp),%xmm0
movapd %xmm0,%xmm3
divsd  0xc99(%rip),%xmm3
subsd  %xmm3,%xmm0
movapd %xmm0,%xmm1
andpd  0xc99(%rip),%xmm1
movsd  0x38(%rsp),%xmm0
mulsd  %xmm3,%xmm0
ucomisd %xmm0,%xmm1
jbe    13c2 <gammainv+0x222>
lea    0x1(%rbx),%eax
movapd %xmm3,%xmm2
cmp    $0x3e7,%ebx
mov    %eax,%ebx
jb     1300 <gammainv+0x160>
jmp    13c2 <gammainv+0x222>
movapd %xmm2,%xmm3
mulsd  0x30(%rsp),%xmm3
movapd %xmm3,%xmm0
add    $0x50,%rsp
pop    %rbx
ret
lea    0xc67(%rip),%rdi
jmp    13e2 <gammainv+0x242>
lea    0xc99(%rip),%rdi
call   1070 <printf@plt>
mov    $0x1,%edi
call   10c0 <exit@plt>

LLVM IR (-O0):
@.str = [59 x i8] c"Probablity Values can only take values between 0.0 and 1.0\00"
@.str.1 = [57 x i8] c"Gamma Distribution parameters must be positive and real.\00"
define double @gammainv(double %0, double %1, double %2) {
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca i32
store double %0, double* %4
store double %1, double* %5
store double %2, double* %6
%15 = load double, double* %4
%16 = fcmp olt double %15, 0.000000e+00
br i1 %16, label %20, label %17
17: ; preds = %3
%18 = load double, double* %4
%19 = fcmp ogt double %18, 1.000000e+00
br i1 %19, label %20, label %23
20: ; preds = %17, %3
%21 = call i32 @printf(i8* getelementptr inbounds ([59 x i8], [59 x i8]* @.str, i64 0, i64 0))
%22 = call i32 @exit(i32 1)
unreachable
23: ; preds = %17
%24 = load double, double* %5
%25 = fcmp ole double %24, 0.000000e+00
br i1 %25, label %29, label %26
26: ; preds = %23
%27 = load double, double* %6
%28 = fcmp ole double %27, 0.000000e+00
br i1 %28, label %29, label %32
29: ; preds = %26, %23
%30 = call i32 @printf(i8* getelementptr inbounds ([57 x i8], [57 x i8]* @.str.1, i64 0, i64 0))
%31 = call i32 @exit(i32 1)
unreachable
32: ; preds = %26
%33 = load double, double* %4
%34 = fcmp oeq double %33, 0.000000e+00
br i1 %34, label %35, label %36
35: ; preds = %32
store double 0.000000e+00, double* %7
br label %36
36: ; preds = %35, %32
%37 = load double, double* %4
%38 = fcmp oeq double %37, 1.000000e+00
br i1 %38, label %39, label %40
39: ; preds = %36
store double 1.790000e+308, double* %7
br label %40
40: ; preds = %39, %36
%41 = load double, double* %4
%42 = fcmp ogt double %41, 0.000000e+00
br i1 %42, label %43, label %112
43: ; preds = %40
%44 = load double, double* %4
%45 = fcmp olt double %44, 1.000000e+00
br i1 %45, label %46, label %112
46: ; preds = %43
%47 = load double, double* %5
%48 = fadd double 1.000000e+00, %47
%49 = call double @log(double %48)
%50 = load double, double* %5
%51 = call double @log(double %50)
%52 = fsub double %49, %51
store double %52, double* %12
%53 = load double, double* %5
%54 = call double @log(double %53)
%55 = load double, double* %12
%56 = call double @llvm.fmuladd.f64(double -5.000000e-01, double %55, double %54)
store double %56, double* %11
%57 = load double, double* %11
%58 = load double, double* %12
%59 = fmul double 2.000000e+00, %58
%60 = fptosi double %59 to i32
%61 = call double @sqrt(i32 %60)
%62 = load double, double* %4
%63 = fmul double 2.000000e+00, %62
%64 = fptosi double %63 to i32
%65 = call double @erfcinv(i32 %64)
%66 = fneg double %61
%67 = call double @llvm.fmuladd.f64(double %66, double %65, double %57)
%68 = call double @exp(double %67)
store double %68, double* %9
store double 1.000000e+00, double* %10
%69 = call double @eps(double 2.225100e-308)
store double %69, double* %13
store i32 0, i32* %14
br label %70
70: ; preds = %106, %46
%71 = load double, double* %10
%72 = call double @llvm.fabs.f64(double %71)
%73 = load double, double* %13
%74 = load double, double* %9
%75 = fmul double %73, %74
%76 = fcmp ogt double %72, %75
br i1 %76, label %77, label %80
77: ; preds = %70
%78 = load i32, i32* %14
%79 = icmp slt i32 %78, 1000
br label %80
80: ; preds = %77, %70
%81 = phi i1 [ false, %70 ], [ %79, %77 ]
br i1 %81, label %82, label %108
82: ; preds = %80
%83 = load double, double* %9
%84 = load double, double* %5
%85 = call double @gammacdf(double %83, double %84, double 1.000000e+00)
%86 = load double, double* %4
%87 = fsub double %85, %86
%88 = load double, double* %9
%89 = load double, double* %5
%90 = call i32 @gammapdf(double %88, double %89, double 1.000000e+00)
%91 = call double @r8_max(i32 %90, double 2.225100e-308)
%92 = fdiv double %87, %91
store double %92, double* %10
%93 = load i32, i32* %14
%94 = add nsw i32 %93, 1
store i32 %94, i32* %14
%95 = load double, double* %9
%96 = load double, double* %10
%97 = fsub double %95, %96
store double %97, double* %8
%98 = load double, double* %8
%99 = fcmp ole double %98, 0.000000e+00
br i1 %99, label %100, label %106
100: ; preds = %82
%101 = load double, double* %9
%102 = fdiv double %101, 1.000000e+01
store double %102, double* %8
%103 = load double, double* %9
%104 = load double, double* %8
%105 = fsub double %103, %104
store double %105, double* %10
br label %106
106: ; preds = %100, %82
%107 = load double, double* %8
store double %107, double* %9
br label %70
108: ; preds = %80
%109 = load double, double* %9
%110 = load double, double* %6
%111 = fmul double %109, %110
store double %111, double* %7
br label %112
112: ; preds = %108, %43, %40
%113 = load double, double* %7
ret double %113
}

LLVM IR (-O2):
@.str = [59 x i8] c"Probablity Values can only take values between 0.0 and 1.0\00"
@.str.1 = [57 x i8] c"Gamma Distribution parameters must be positive and real.\00"
define double @gammainv(double %0, double %1, double %2) {
%4 = fcmp olt double %0, 0.000000e+00
%5 = fcmp ogt double %0, 1.000000e+00
%6 = or i1 %4, %5
br i1 %6, label %7, label %10
7: ; preds = %3
%8 = tail call i32 @printf(i8* dereferenceable(1) getelementptr inbounds ([59 x i8], [59 x i8]* @.str, i64 0, i64 0))
%9 = tail call i32 @exit(i32 1)
unreachable
10: ; preds = %3
%11 = fcmp ole double %1, 0.000000e+00
%12 = fcmp ole double %2, 0.000000e+00
%13 = or i1 %11, %12
br i1 %13, label %14, label %17
14: ; preds = %10
%15 = tail call i32 @printf(i8* dereferenceable(1) getelementptr inbounds ([57 x i8], [57 x i8]* @.str.1, i64 0, i64 0))
%16 = tail call i32 @exit(i32 1)
unreachable
17: ; preds = %10
%18 = fcmp oeq double %0, 1.000000e+00
%19 = select i1 %18, double 1.790000e+308, double 0.000000e+00
%20 = fcmp ogt double %0, 0.000000e+00
%21 = fcmp olt double %0, 1.000000e+00
%22 = and i1 %20, %21
br i1 %22, label %23, label %67
23: ; preds = %17
%24 = fadd double %1, 1.000000e+00
%25 = tail call double @log(double %24)
%26 = tail call double @log(double %1)
%27 = fsub double %25, %26
%28 = tail call double @log(double %1)
%29 = tail call double @llvm.fmuladd.f64(double %27, double -5.000000e-01, double %28)
%30 = fmul double %27, 2.000000e+00
%31 = fptosi double %30 to i32
%32 = tail call double @sqrt(i32 %31)
%33 = fmul double %0, 2.000000e+00
%34 = fptosi double %33 to i32
%35 = tail call double @erfcinv(i32 %34)
%36 = fneg double %32
%37 = tail call double @llvm.fmuladd.f64(double %36, double %35, double %29)
%38 = tail call double @exp(double %37)
%39 = tail call double @eps(double 2.225100e-308)
%40 = fmul double %39, %38
%41 = fcmp olt double %40, 1.000000e+00
br i1 %41, label %42, label %64
42: ; preds = %23, %56
%43 = phi i32 [ %50, %56 ], [ 0, %23 ]
%44 = phi double [ %58, %56 ], [ %38, %23 ]
%45 = tail call double @gammacdf(double %44, double %1, double 1.000000e+00)
%46 = fsub double %45, %0
%47 = tail call i32 @gammapdf(double %44, double %1, double 1.000000e+00)
%48 = tail call double @r8_max(i32 %47, double 2.225100e-308)
%49 = fdiv double %46, %48
%50 = add nuw nsw i32 %43, 1
%51 = fsub double %44, %49
%52 = fcmp ugt double %51, 0.000000e+00
br i1 %52, label %56, label %53
53: ; preds = %42
%54 = fdiv double %44, 1.000000e+01
%55 = fsub double %44, %54
br label %56
56: ; preds = %53, %42
%57 = phi double [ %55, %53 ], [ %49, %42 ]
%58 = phi double [ %54, %53 ], [ %51, %42 ]
%59 = tail call double @llvm.fabs.f64(double %57)
%60 = fmul double %39, %58
%61 = fcmp ogt double %59, %60
%62 = icmp ult i32 %43, 999
%63 = select i1 %61, i1 %62, i1 false
br i1 %63, label %42, label %64
64: ; preds = %56, %23
%65 = phi double [ %38, %23 ], [ %58, %56 ]
%66 = fmul double %65, %2
br label %67
67: ; preds = %64, %17
%68 = phi double [ %66, %64 ], [ %19, %17 ]
ret double %68
}