#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*/ assert(int);
scalar_t__ besseli0(double);
int fabs(scalar_t__);
double factorial(int);
void init_test(void) {
  assert(factorial(0) == 1.0);
  assert(factorial(2) == 2.0);
  assert(factorial(0) == 1.0);
  assert(factorial(5) == 120.0);
  assert(factorial(8) == 40320.0);
  assert(fabs(besseli0(0.0) - 1.0) < 1e-8);
  assert(fabs(besseli0(0.5) - 1.06348337074132) < 1e-8);
  assert(fabs(besseli0(1.0) - 1.26606587775201) < 1e-14);
  assert(fabs(besseli0(2.0) - 2.27958530233607) < 1e-14);
  assert(fabs(besseli0(3.5) - 7.37820343222548) < 1e-14);
}


x86 assembly (clang, -O0):
<init_test>:
push   %rbp
mov    %rsp,%rbp
xor    %edi,%edi
call   1030 <factorial@plt>
movsd  0xedd(%rip),%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
mov    $0x2,%edi
call   1030 <factorial@plt>
movsd  0xea5(%rip),%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
xor    %edi,%edi
call   1030 <factorial@plt>
movsd  0xe90(%rip),%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
mov    $0x5,%edi
call   1030 <factorial@plt>
movsd  0xe90(%rip),%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
mov    $0x8,%edi
call   1030 <factorial@plt>
movsd  0xe60(%rip),%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
xorps  %xmm0,%xmm0
call   1060 <besseli0@plt>
cvtsi2sd %rax,%xmm0
movsd  0xe15(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
cvtsi2sd %eax,%xmm1
movsd  0xe03(%rip),%xmm0
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
movsd  0xdfa(%rip),%xmm0
call   1060 <besseli0@plt>
cvtsi2sd %rax,%xmm0
movsd  0xde0(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
cvtsi2sd %eax,%xmm1
movsd  0xdbe(%rip),%xmm0
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
movsd  0xd9d(%rip),%xmm0
call   1060 <besseli0@plt>
cvtsi2sd %rax,%xmm0
movsd  0xd83(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
cvtsi2sd %eax,%xmm1
movsd  0xd41(%rip),%xmm0
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
movsd  0xd48(%rip),%xmm0
call   1060 <besseli0@plt>
cvtsi2sd %rax,%xmm0
movsd  0xd2e(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
cvtsi2sd %eax,%xmm1
movsd  0xcfc(%rip),%xmm0
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
movsd  0xcf3(%rip),%xmm0
call   1060 <besseli0@plt>
cvtsi2sd %rax,%xmm0
movsd  0xcd9(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
cvtsi2sd %eax,%xmm1
movsd  0xcb7(%rip),%xmm0
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
pop    %rbp
ret

x86 assembly (clang, -O2):
<init_test>:
push   %rax
xor    %edi,%edi
call   1030 <factorial@plt>
cmpeqsd 0xeaf(%rip),%xmm0
movq   %xmm0,%rdi
and    $0x1,%edi
call   1050 <assert@plt>
mov    $0x2,%edi
call   1030 <factorial@plt>
cmpeqsd 0xe97(%rip),%xmm0
movq   %xmm0,%rdi
and    $0x1,%edi
call   1050 <assert@plt>
xor    %edi,%edi
call   1030 <factorial@plt>
cmpeqsd 0xe72(%rip),%xmm0
movq   %xmm0,%rdi
and    $0x1,%edi
call   1050 <assert@plt>
mov    $0x5,%edi
call   1030 <factorial@plt>
cmpeqsd 0xe62(%rip),%xmm0
movq   %xmm0,%rdi
and    $0x1,%edi
call   1050 <assert@plt>
mov    $0x8,%edi
call   1030 <factorial@plt>
cmpeqsd 0xe4a(%rip),%xmm0
movq   %xmm0,%rdi
and    $0x1,%edi
call   1050 <assert@plt>
xorpd  %xmm0,%xmm0
call   1060 <besseli0@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0xe2c(%rip),%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
xor    %edi,%edi
test   %eax,%eax
setle  %dil
call   1050 <assert@plt>
movsd  0xe15(%rip),%xmm0
call   1060 <besseli0@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0xe08(%rip),%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
xor    %edi,%edi
test   %eax,%eax
setle  %dil
call   1050 <assert@plt>
movsd  0xdb9(%rip),%xmm0
call   1060 <besseli0@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0xddc(%rip),%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
xor    %edi,%edi
test   %eax,%eax
setle  %dil
call   1050 <assert@plt>
movsd  0xd8d(%rip),%xmm0
call   1060 <besseli0@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0xdb0(%rip),%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
xor    %edi,%edi
test   %eax,%eax
setle  %dil
call   1050 <assert@plt>
movsd  0xd99(%rip),%xmm0
call   1060 <besseli0@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0xd8c(%rip),%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <fabs@plt>
xor    %edi,%edi
test   %eax,%eax
setle  %dil
pop    %rax
jmp    1050 <assert@plt>

LLVM IR (-O0):
define void @init_test() {
%1 = call double @factorial(i32 0)
%2 = fcmp oeq double %1, 1.000000e+00
%3 = zext i1 %2 to i32
%4 = call i32 @assert(i32 %3)
%5 = call double @factorial(i32 2)
%6 = fcmp oeq double %5, 2.000000e+00
%7 = zext i1 %6 to i32
%8 = call i32 @assert(i32 %7)
%9 = call double @factorial(i32 0)
%10 = fcmp oeq double %9, 1.000000e+00
%11 = zext i1 %10 to i32
%12 = call i32 @assert(i32 %11)
%13 = call double @factorial(i32 5)
%14 = fcmp oeq double %13, 1.200000e+02
%15 = zext i1 %14 to i32
%16 = call i32 @assert(i32 %15)
%17 = call double @factorial(i32 8)
%18 = fcmp oeq double %17, 4.032000e+04
%19 = zext i1 %18 to i32
%20 = call i32 @assert(i32 %19)
%21 = call i64 @besseli0(double 0.000000e+00)
%22 = sitofp i64 %21 to double
%23 = fsub double %22, 1.000000e+00
%24 = fptosi double %23 to i64
%25 = call i32 @fabs(i64 %24)
%26 = sitofp i32 %25 to double
%27 = fcmp olt double %26, 1.000000e-08
%28 = zext i1 %27 to i32
%29 = call i32 @assert(i32 %28)
%30 = call i64 @besseli0(double 5.000000e-01)
%31 = sitofp i64 %30 to double
%32 = fsub double %31, 0x3FF104072392C7F0
%33 = fptosi double %32 to i64
%34 = call i32 @fabs(i64 %33)
%35 = sitofp i32 %34 to double
%36 = fcmp olt double %35, 1.000000e-08
%37 = zext i1 %36 to i32
%38 = call i32 @assert(i32 %37)
%39 = call i64 @besseli0(double 1.000000e+00)
%40 = sitofp i64 %39 to double
%41 = fsub double %40, 0x3FF441CE4B386C34
%42 = fptosi double %41 to i64
%43 = call i32 @fabs(i64 %42)
%44 = sitofp i32 %43 to double
%45 = fcmp olt double %44, 0x3D06849B86A12B9B
%46 = zext i1 %45 to i32
%47 = call i32 @assert(i32 %46)
%48 = call i64 @besseli0(double 2.000000e+00)
%49 = sitofp i64 %48 to double
%50 = fsub double %49, 0x40023C97380FCE38
%51 = fptosi double %50 to i64
%52 = call i32 @fabs(i64 %51)
%53 = sitofp i32 %52 to double
%54 = fcmp olt double %53, 0x3D06849B86A12B9B
%55 = zext i1 %54 to i32
%56 = call i32 @assert(i32 %55)
%57 = call i64 @besseli0(double 3.500000e+00)
%58 = sitofp i64 %57 to double
%59 = fsub double %58, 0x401D8347C2B292D5
%60 = fptosi double %59 to i64
%61 = call i32 @fabs(i64 %60)
%62 = sitofp i32 %61 to double
%63 = fcmp olt double %62, 0x3D06849B86A12B9B
%64 = zext i1 %63 to i32
%65 = call i32 @assert(i32 %64)
ret void
}

LLVM IR (-O2):
define void @init_test() {
%1 = tail call double @factorial(i32 0)
%2 = fcmp oeq double %1, 1.000000e+00
%3 = zext i1 %2 to i32
%4 = tail call i32 @assert(i32 %3)
%5 = tail call double @factorial(i32 2)
%6 = fcmp oeq double %5, 2.000000e+00
%7 = zext i1 %6 to i32
%8 = tail call i32 @assert(i32 %7)
%9 = tail call double @factorial(i32 0)
%10 = fcmp oeq double %9, 1.000000e+00
%11 = zext i1 %10 to i32
%12 = tail call i32 @assert(i32 %11)
%13 = tail call double @factorial(i32 5)
%14 = fcmp oeq double %13, 1.200000e+02
%15 = zext i1 %14 to i32
%16 = tail call i32 @assert(i32 %15)
%17 = tail call double @factorial(i32 8)
%18 = fcmp oeq double %17, 4.032000e+04
%19 = zext i1 %18 to i32
%20 = tail call i32 @assert(i32 %19)
%21 = tail call i64 @besseli0(double 0.000000e+00)
%22 = sitofp i64 %21 to double
%23 = fadd double %22, -1.000000e+00
%24 = fptosi double %23 to i64
%25 = tail call i32 @fabs(i64 %24)
%26 = icmp slt i32 %25, 1
%27 = zext i1 %26 to i32
%28 = tail call i32 @assert(i32 %27)
%29 = tail call i64 @besseli0(double 5.000000e-01)
%30 = sitofp i64 %29 to double
%31 = fadd double %30, 0xBFF104072392C7F0
%32 = fptosi double %31 to i64
%33 = tail call i32 @fabs(i64 %32)
%34 = icmp slt i32 %33, 1
%35 = zext i1 %34 to i32
%36 = tail call i32 @assert(i32 %35)
%37 = tail call i64 @besseli0(double 1.000000e+00)
%38 = sitofp i64 %37 to double
%39 = fadd double %38, 0xBFF441CE4B386C34
%40 = fptosi double %39 to i64
%41 = tail call i32 @fabs(i64 %40)
%42 = icmp slt i32 %41, 1
%43 = zext i1 %42 to i32
%44 = tail call i32 @assert(i32 %43)
%45 = tail call i64 @besseli0(double 2.000000e+00)
%46 = sitofp i64 %45 to double
%47 = fadd double %46, 0xC0023C97380FCE38
%48 = fptosi double %47 to i64
%49 = tail call i32 @fabs(i64 %48)
%50 = icmp slt i32 %49, 1
%51 = zext i1 %50 to i32
%52 = tail call i32 @assert(i32 %51)
%53 = tail call i64 @besseli0(double 3.500000e+00)
%54 = sitofp i64 %53 to double
%55 = fadd double %54, 0xC01D8347C2B292D5
%56 = fptosi double %55 to i64
%57 = tail call i32 @fabs(i64 %56)
%58 = icmp slt i32 %57, 1
%59 = zext i1 %58 to i32
%60 = tail call i32 @assert(i32 %59)
ret void
}