#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 exp(double);
scalar_t__ isinf(double);
double log(double);
int log1p(double);
double inverse_transform(double z, double lb, double ub, double *lp) {
  if (!isinf(lb) && isinf(ub)) {
    *lp += z;
    return exp(z) + lb;
  } else if (!isinf(ub) && isinf(lb)) {
    *lp += z;
    return ub - exp(z);
  } else if (isinf(ub) && isinf(lb)) {
    return z;
  }
  double inv_logit_x;
  if (z > 0) {
    double exp_minus_x = exp(-z);
    inv_logit_x = 1.0 / (1.0 + exp_minus_x);
    *lp += log(ub - lb) - z - 2 * log1p(exp_minus_x);
    if (!isinf(z) && inv_logit_x == 1)
      inv_logit_x = 1 - 1e-15;
  } else {
    double exp_x = exp(z);
    inv_logit_x = 1.0 - 1.0 / (1.0 + exp_x);
    *lp += log(ub - lb) + z - 2 * log1p(exp_x);
    if (!isinf(z) && inv_logit_x == 0)
      inv_logit_x = 1e-15;
  }
  return lb + (ub - lb) * inv_logit_x;
}


x86 assembly (clang, -O0):
<inverse_transform>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
mov    %rdi,-0x28(%rbp)
movsd  -0x18(%rbp),%xmm0
call   1060 <isinf@plt>
cmp    $0x0,%rax
jne    11ad <inverse_transform+0x6d>
movsd  -0x20(%rbp),%xmm0
call   1060 <isinf@plt>
cmp    $0x0,%rax
je     11ad <inverse_transform+0x6d>
movsd  -0x10(%rbp),%xmm0
mov    -0x28(%rbp),%rax
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
movsd  -0x10(%rbp),%xmm0
call   1030 <exp@plt>
addsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1400 <inverse_transform+0x2c0>
movsd  -0x20(%rbp),%xmm0
call   1060 <isinf@plt>
cmp    $0x0,%rax
jne    1210 <inverse_transform+0xd0>
movsd  -0x18(%rbp),%xmm0
call   1060 <isinf@plt>
cmp    $0x0,%rax
je     1210 <inverse_transform+0xd0>
movsd  -0x10(%rbp),%xmm0
mov    -0x28(%rbp),%rax
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1030 <exp@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1400 <inverse_transform+0x2c0>
movsd  -0x20(%rbp),%xmm0
call   1060 <isinf@plt>
cmp    $0x0,%rax
je     1247 <inverse_transform+0x107>
movsd  -0x18(%rbp),%xmm0
call   1060 <isinf@plt>
cmp    $0x0,%rax
je     1247 <inverse_transform+0x107>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1400 <inverse_transform+0x2c0>
jmp    124c <inverse_transform+0x10c>
jmp    1251 <inverse_transform+0x111>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1329 <inverse_transform+0x1e9>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1030 <exp@plt>
movsd  %xmm0,-0x38(%rbp)
movsd  0xd6f(%rip),%xmm1
addsd  -0x38(%rbp),%xmm1
movsd  0xd62(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x20(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
call   1040 <log@plt>
subsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x38(%rbp),%xmm0
call   1050 <log1p@plt>
movsd  -0x50(%rbp),%xmm0
shl    $0x1,%eax
cvtsi2sd %eax,%xmm1
subsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rax
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
movsd  -0x10(%rbp),%xmm0
call   1060 <isinf@plt>
cmp    $0x0,%rax
jne    1324 <inverse_transform+0x1e4>
movsd  -0x30(%rbp),%xmm0
movsd  0xcf9(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1324 <inverse_transform+0x1e4>
jp     1324 <inverse_transform+0x1e4>
movsd  0xcf1(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    13df <inverse_transform+0x29f>
movsd  -0x10(%rbp),%xmm0
call   1030 <exp@plt>
movsd  %xmm0,-0x40(%rbp)
movsd  0xcc0(%rip),%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  0xcb3(%rip),%xmm1
divsd  %xmm0,%xmm1
movsd  0xca7(%rip),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x20(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
call   1040 <log@plt>
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x40(%rbp),%xmm0
call   1050 <log1p@plt>
movsd  -0x58(%rbp),%xmm0
shl    $0x1,%eax
cvtsi2sd %eax,%xmm1
subsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rax
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
movsd  -0x10(%rbp),%xmm0
call   1060 <isinf@plt>
cmp    $0x0,%rax
jne    13da <inverse_transform+0x29a>
movsd  -0x30(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    13da <inverse_transform+0x29a>
jp     13da <inverse_transform+0x29a>
movsd  0xc33(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    13df <inverse_transform+0x29f>
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<inverse_transform>:
push   %rbx
sub    $0x40,%rsp
mov    %rdi,%rbx
movsd  %xmm2,(%rsp)
movaps %xmm0,0x10(%rsp)
movsd  %xmm1,0x8(%rsp)
movapd %xmm1,%xmm0
call   1060 <isinf@plt>
test   %rax,%rax
je     11a3 <inverse_transform+0x63>
movsd  (%rsp),%xmm0
call   1060 <isinf@plt>
test   %rax,%rax
je     1295 <inverse_transform+0x155>
movsd  (%rsp),%xmm0
call   1060 <isinf@plt>
test   %rax,%rax
je     11ce <inverse_transform+0x8e>
movsd  0x8(%rsp),%xmm0
call   1060 <isinf@plt>
test   %rax,%rax
je     11ce <inverse_transform+0x8e>
movapd 0x10(%rsp),%xmm0
jmp    1390 <inverse_transform+0x250>
movsd  (%rsp),%xmm0
call   1060 <isinf@plt>
test   %rax,%rax
je     1166 <inverse_transform+0x26>
movsd  (%rbx),%xmm1
movapd 0x10(%rsp),%xmm0
addsd  %xmm0,%xmm1
movsd  %xmm1,(%rbx)
call   1030 <exp@plt>
jmp    138a <inverse_transform+0x24a>
xorpd  %xmm0,%xmm0
movapd 0x10(%rsp),%xmm1
ucomisd %xmm0,%xmm1
jbe    12d2 <inverse_transform+0x192>
movapd 0xe36(%rip),%xmm0
xorpd  %xmm1,%xmm0
call   1030 <exp@plt>
movsd  %xmm0,0x28(%rsp)
movsd  0xdff(%rip),%xmm1
movapd %xmm0,%xmm2
addsd  %xmm1,%xmm2
divsd  %xmm2,%xmm1
movapd %xmm1,0x30(%rsp)
movsd  (%rsp),%xmm0
subsd  0x8(%rsp),%xmm0
movsd  %xmm0,(%rsp)
call   1040 <log@plt>
subsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x20(%rsp)
movsd  0x28(%rsp),%xmm0
call   1050 <log1p@plt>
add    %eax,%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movsd  0x20(%rsp),%xmm1
subsd  %xmm0,%xmm1
addsd  (%rbx),%xmm1
movsd  %xmm1,(%rbx)
movaps 0x10(%rsp),%xmm0
call   1060 <isinf@plt>
movapd 0x30(%rsp),%xmm2
movsd  0xd8e(%rip),%xmm0
cmpeqsd %xmm2,%xmm0
movapd %xmm0,%xmm1
andnpd %xmm2,%xmm1
test   %rax,%rax
jne    1379 <inverse_transform+0x239>
movsd  0xd80(%rip),%xmm2
jmp    1379 <inverse_transform+0x239>
movsd  0x8(%rsp),%xmm0
call   1060 <isinf@plt>
test   %rax,%rax
je     1179 <inverse_transform+0x39>
movsd  (%rbx),%xmm1
movapd 0x10(%rsp),%xmm0
addsd  %xmm0,%xmm1
movsd  %xmm1,(%rbx)
call   1030 <exp@plt>
movsd  (%rsp),%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
jmp    1390 <inverse_transform+0x250>
movapd %xmm1,%xmm0
call   1030 <exp@plt>
movsd  %xmm0,0x28(%rsp)
movsd  0xd17(%rip),%xmm2
movapd %xmm0,%xmm3
addsd  %xmm2,%xmm3
movapd %xmm2,%xmm1
divsd  %xmm3,%xmm1
subsd  %xmm1,%xmm2
movapd %xmm2,0x30(%rsp)
movsd  (%rsp),%xmm0
subsd  0x8(%rsp),%xmm0
movsd  %xmm0,(%rsp)
call   1040 <log@plt>
addsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x20(%rsp)
movsd  0x28(%rsp),%xmm0
call   1050 <log1p@plt>
add    %eax,%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movsd  0x20(%rsp),%xmm1
subsd  %xmm0,%xmm1
addsd  (%rbx),%xmm1
movsd  %xmm1,(%rbx)
movapd 0x10(%rsp),%xmm0
call   1060 <isinf@plt>
movapd 0x30(%rsp),%xmm2
xorpd  %xmm0,%xmm0
cmpeqsd %xmm2,%xmm0
movapd %xmm0,%xmm1
andnpd %xmm2,%xmm1
test   %rax,%rax
jne    1379 <inverse_transform+0x239>
movsd  0xc8f(%rip),%xmm2
andpd  %xmm2,%xmm0
orpd   %xmm0,%xmm1
movsd  (%rsp),%xmm0
mulsd  %xmm1,%xmm0
addsd  0x8(%rsp),%xmm0
add    $0x40,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define double @inverse_transform(double %0, double %1, double %2, double* %3) {
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double*
%10 = alloca double
%11 = alloca double
%12 = alloca double
store double %0, double* %6
store double %1, double* %7
store double %2, double* %8
store double* %3, double** %9
%13 = load double, double* %7
%14 = call i64 @isinf(double %13)
%15 = icmp ne i64 %14, 0
br i1 %15, label %29, label %16
16: ; preds = %4
%17 = load double, double* %8
%18 = call i64 @isinf(double %17)
%19 = icmp ne i64 %18, 0
br i1 %19, label %20, label %29
20: ; preds = %16
%21 = load double, double* %6
%22 = load double*, double** %9
%23 = load double, double* %22
%24 = fadd double %23, %21
store double %24, double* %22
%25 = load double, double* %6
%26 = call double @exp(double %25)
%27 = load double, double* %7
%28 = fadd double %26, %27
store double %28, double* %5
br label %126
29: ; preds = %16, %4
%30 = load double, double* %8
%31 = call i64 @isinf(double %30)
%32 = icmp ne i64 %31, 0
br i1 %32, label %46, label %33
33: ; preds = %29
%34 = load double, double* %7
%35 = call i64 @isinf(double %34)
%36 = icmp ne i64 %35, 0
br i1 %36, label %37, label %46
37: ; preds = %33
%38 = load double, double* %6
%39 = load double*, double** %9
%40 = load double, double* %39
%41 = fadd double %40, %38
store double %41, double* %39
%42 = load double, double* %8
%43 = load double, double* %6
%44 = call double @exp(double %43)
%45 = fsub double %42, %44
store double %45, double* %5
br label %126
46: ; preds = %33, %29
%47 = load double, double* %8
%48 = call i64 @isinf(double %47)
%49 = icmp ne i64 %48, 0
br i1 %49, label %50, label %56
50: ; preds = %46
%51 = load double, double* %7
%52 = call i64 @isinf(double %51)
%53 = icmp ne i64 %52, 0
br i1 %53, label %54, label %56
54: ; preds = %50
%55 = load double, double* %6
store double %55, double* %5
br label %126
56: ; preds = %50, %46
br label %57
57: ; preds = %56
br label %58
58: ; preds = %57
%59 = load double, double* %6
%60 = fcmp ogt double %59, 0.000000e+00
br i1 %60, label %61, label %90
61: ; preds = %58
%62 = load double, double* %6
%63 = fneg double %62
%64 = call double @exp(double %63)
store double %64, double* %11
%65 = load double, double* %11
%66 = fadd double 1.000000e+00, %65
%67 = fdiv double 1.000000e+00, %66
store double %67, double* %10
%68 = load double, double* %8
%69 = load double, double* %7
%70 = fsub double %68, %69
%71 = call double @log(double %70)
%72 = load double, double* %6
%73 = fsub double %71, %72
%74 = load double, double* %11
%75 = call i32 @log1p(double %74)
%76 = mul nsw i32 2, %75
%77 = sitofp i32 %76 to double
%78 = fsub double %73, %77
%79 = load double*, double** %9
%80 = load double, double* %79
%81 = fadd double %80, %78
store double %81, double* %79
%82 = load double, double* %6
%83 = call i64 @isinf(double %82)
%84 = icmp ne i64 %83, 0
br i1 %84, label %89, label %85
85: ; preds = %61
%86 = load double, double* %10
%87 = fcmp oeq double %86, 1.000000e+00
br i1 %87, label %88, label %89
88: ; preds = %85
store double 0x3FEFFFFFFFFFFFF7, double* %10
br label %89
89: ; preds = %88, %85, %61
br label %119
90: ; preds = %58
%91 = load double, double* %6
%92 = call double @exp(double %91)
store double %92, double* %12
%93 = load double, double* %12
%94 = fadd double 1.000000e+00, %93
%95 = fdiv double 1.000000e+00, %94
%96 = fsub double 1.000000e+00, %95
store double %96, double* %10
%97 = load double, double* %8
%98 = load double, double* %7
%99 = fsub double %97, %98
%100 = call double @log(double %99)
%101 = load double, double* %6
%102 = fadd double %100, %101
%103 = load double, double* %12
%104 = call i32 @log1p(double %103)
%105 = mul nsw i32 2, %104
%106 = sitofp i32 %105 to double
%107 = fsub double %102, %106
%108 = load double*, double** %9
%109 = load double, double* %108
%110 = fadd double %109, %107
store double %110, double* %108
%111 = load double, double* %6
%112 = call i64 @isinf(double %111)
%113 = icmp ne i64 %112, 0
br i1 %113, label %118, label %114
114: ; preds = %90
%115 = load double, double* %10
%116 = fcmp oeq double %115, 0.000000e+00
br i1 %116, label %117, label %118
117: ; preds = %114
store double 1.000000e-15, double* %10
br label %118
118: ; preds = %117, %114, %90
br label %119
119: ; preds = %118, %89
%120 = load double, double* %7
%121 = load double, double* %8
%122 = load double, double* %7
%123 = fsub double %121, %122
%124 = load double, double* %10
%125 = call double @llvm.fmuladd.f64(double %123, double %124, double %120)
store double %125, double* %5
br label %126
126: ; preds = %119, %54, %37, %20
%127 = load double, double* %5
ret double %127
}

LLVM IR (-O2):
define double @inverse_transform(double %0, double %1, double %2, double* nocapture %3) {
%5 = tail call i64 @isinf(double %1)
%6 = icmp eq i64 %5, 0
br i1 %6, label %7, label %15
7: ; preds = %4
%8 = tail call i64 @isinf(double %2)
%9 = icmp eq i64 %8, 0
br i1 %9, label %15, label %10
10: ; preds = %7
%11 = load double, double* %3
%12 = fadd double %11, %0
store double %12, double* %3
%13 = tail call double @exp(double %0)
%14 = fadd double %13, %1
br label %76
15: ; preds = %7, %4
%16 = tail call i64 @isinf(double %2)
%17 = icmp eq i64 %16, 0
br i1 %17, label %18, label %26
18: ; preds = %15
%19 = tail call i64 @isinf(double %1)
%20 = icmp eq i64 %19, 0
br i1 %20, label %26, label %21
21: ; preds = %18
%22 = load double, double* %3
%23 = fadd double %22, %0
store double %23, double* %3
%24 = tail call double @exp(double %0)
%25 = fsub double %2, %24
br label %76
26: ; preds = %18, %15
%27 = tail call i64 @isinf(double %2)
%28 = icmp eq i64 %27, 0
br i1 %28, label %32, label %29
29: ; preds = %26
%30 = tail call i64 @isinf(double %1)
%31 = icmp eq i64 %30, 0
br i1 %31, label %32, label %76
32: ; preds = %29, %26
%33 = fcmp ogt double %0, 0.000000e+00
br i1 %33, label %34, label %53
34: ; preds = %32
%35 = fneg double %0
%36 = tail call double @exp(double %35)
%37 = fadd double %36, 1.000000e+00
%38 = fdiv double 1.000000e+00, %37
%39 = fsub double %2, %1
%40 = tail call double @log(double %39)
%41 = fsub double %40, %0
%42 = tail call i32 @log1p(double %36)
%43 = shl nsw i32 %42, 1
%44 = sitofp i32 %43 to double
%45 = fsub double %41, %44
%46 = load double, double* %3
%47 = fadd double %46, %45
store double %47, double* %3
%48 = tail call i64 @isinf(double %0)
%49 = icmp eq i64 %48, 0
%50 = fcmp oeq double %38, 1.000000e+00
%51 = and i1 %50, %49
%52 = select i1 %51, double 0x3FEFFFFFFFFFFFF7, double %38
br label %72
53: ; preds = %32
%54 = tail call double @exp(double %0)
%55 = fadd double %54, 1.000000e+00
%56 = fdiv double 1.000000e+00, %55
%57 = fsub double 1.000000e+00, %56
%58 = fsub double %2, %1
%59 = tail call double @log(double %58)
%60 = fadd double %59, %0
%61 = tail call i32 @log1p(double %54)
%62 = shl nsw i32 %61, 1
%63 = sitofp i32 %62 to double
%64 = fsub double %60, %63
%65 = load double, double* %3
%66 = fadd double %65, %64
store double %66, double* %3
%67 = tail call i64 @isinf(double %0)
%68 = icmp eq i64 %67, 0
%69 = fcmp oeq double %57, 0.000000e+00
%70 = and i1 %69, %68
%71 = select i1 %70, double 1.000000e-15, double %57
br label %72
72: ; preds = %53, %34
%73 = phi double [ %58, %53 ], [ %39, %34 ]
%74 = phi double [ %71, %53 ], [ %52, %34 ]
%75 = tail call double @llvm.fmuladd.f64(double %73, double %74, double %1)
br label %76
76: ; preds = %29, %72, %21, %10
%77 = phi double [ %75, %72 ], [ %25, %21 ], [ %14, %10 ], [ %0, %29 ]
ret double %77
}