#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 fabs(float);
scalar_t__ sqrt(double);
float bessi(int n, float x) {
  float bessi0(float x);
  void nrerror(char error_text[]);
  int j;
  float bi, bim, bip, tox, ans;
  if (n < 2)
    nrerror("Index n less than 2 in bessi");
  if (x == 0.0)
    return 0.0;
  else {
    tox = 2.0 / fabs(x);
    bip = ans = 0.0;
    bi = 1.0;
    for (j = 2 * (n + (int)sqrt(40.0 * n)); j > 0; j--) {
      bim = bip + j * tox * bi;
      bip = bi;
      bi = bim;
      if (fabs(bi) > 1.0e10) {
        ans *= 1.0e-10;
        bi *= 1.0e-10;
        bip *= 1.0e-10;
      }
      if (j == n)
        ans = bip;
    }
    ans *= bessi0(x) / bi;
    return x < 0.0 && (n & 1) ? -ans : ans;
  }
}


x86 assembly (clang, -O0):
<bessi>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x8(%rbp)
movss  %xmm0,-0xc(%rbp)
cmpl   $0x2,-0x8(%rbp)
jge    1166 <bessi+0x26>
lea    0xec3(%rip),%rdi
call   1030 <nrerror@plt>
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    118f <bessi+0x4f>
jp     118f <bessi+0x4f>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1344 <bessi+0x204>
movss  -0xc(%rbp),%xmm0
call   1040 <fabs@plt>
movaps %xmm0,%xmm1
movsd  0xe64(%rip),%xmm0
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  0xe57(%rip),%xmm0
movss  %xmm0,-0x14(%rbp)
mov    -0x8(%rbp),%eax
mov    %eax,-0x28(%rbp)
cvtsi2sdl -0x8(%rbp),%xmm1
movsd  0xe1f(%rip),%xmm0
mulsd  %xmm1,%xmm0
call   1060 <sqrt@plt>
mov    %rax,%rcx
mov    -0x28(%rbp),%eax
add    %ecx,%eax
shl    $0x1,%eax
mov    %eax,-0x10(%rbp)
cmpl   $0x0,-0x10(%rbp)
jle    12d6 <bessi+0x196>
movss  -0x1c(%rbp),%xmm1
cvtsi2ssl -0x10(%rbp),%xmm0
mulss  -0x20(%rbp),%xmm0
movss  -0x14(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x18(%rbp)
movss  -0x14(%rbp),%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x14(%rbp)
movss  -0x14(%rbp),%xmm0
call   1040 <fabs@plt>
movsd  0xdc7(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12ad <bessi+0x16d>
movss  -0x24(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xdb4(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
movss  -0x14(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd96(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x14(%rbp)
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd78(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x1c(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x8(%rbp),%eax
jne    12c3 <bessi+0x183>
movss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
jmp    12c8 <bessi+0x188>
mov    -0x10(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x10(%rbp)
jmp    11f8 <bessi+0xb8>
movss  -0xc(%rbp),%xmm0
call   1050 <bessi0@plt>
divss  -0x14(%rbp),%xmm0
mulss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
xorps  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
jbe    1330 <bessi+0x1f0>
mov    -0x8(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     1330 <bessi+0x1f0>
movss  -0x24(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x2c(%rbp)
jmp    133a <bessi+0x1fa>
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x2c(%rbp)
movss  -0x2c(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bessi>:
push   %rbp
push   %r14
push   %rbx
sub    $0x40,%rsp
movaps %xmm0,%xmm1
mov    %edi,%r14d
cmp    $0x1,%edi
jg     1169 <bessi+0x29>
lea    0xf06(%rip),%rdi
movaps %xmm1,0x20(%rsp)
call   1030 <nrerror@plt>
movaps 0x20(%rsp),%xmm1
xorps  %xmm0,%xmm0
ucomiss %xmm0,%xmm1
jne    1177 <bessi+0x37>
jnp    12dc <bessi+0x19c>
movaps %xmm1,0x20(%rsp)
movaps %xmm1,%xmm0
call   1040 <fabs@plt>
movsd  %xmm0,0x10(%rsp)
xorps  %xmm0,%xmm0
cvtsi2sd %r14d,%xmm0
mulsd  0xe6e(%rip),%xmm0
call   1060 <sqrt@plt>
mov    %eax,%ebx
add    %r14d,%ebx
jle    1287 <bessi+0x147>
movsd  0xe4e(%rip),%xmm0
divsd  0x10(%rsp),%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0xc(%rsp)
add    %ebx,%ebx
lea    (%r14,%rax,2),%ebp
movaps 0xe61(%rip),%xmm0
xorps  %xmm4,%xmm4
jmp    11f4 <bessi+0xb4>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
lea    -0x1(%rbx),%eax
movaps %xmm3,%xmm0
unpcklps %xmm1,%xmm0
cmp    $0x1,%ebx
mov    %eax,%ebx
jle    1292 <bessi+0x152>
movaps %xmm0,0x30(%rsp)
xorps  %xmm1,%xmm1
cvtsi2ss %ebx,%xmm1
mulss  0xc(%rsp),%xmm1
shufps $0x55,%xmm0,%xmm0
mulss  %xmm1,%xmm0
addss  %xmm4,%xmm0
movaps %xmm0,0x10(%rsp)
call   1040 <fabs@plt>
ucomisd 0xdec(%rip),%xmm0
jbe    1260 <bessi+0x120>
movaps 0x10(%rsp),%xmm0
cvtss2sd %xmm0,%xmm0
mulsd  0xde1(%rip),%xmm0
xorps  %xmm1,%xmm1
cvtsd2ss %xmm0,%xmm1
cvtps2pd 0x30(%rsp),%xmm0
mulpd  0xdf5(%rip),%xmm0
cvtpd2ps %xmm0,%xmm2
jmp    126b <bessi+0x12b>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movaps 0x10(%rsp),%xmm1
movapd 0x30(%rsp),%xmm2
movapd %xmm2,%xmm4
shufps $0x55,%xmm2,%xmm4
movaps %xmm4,%xmm3
sub    $0x1,%ebp
jb     11e0 <bessi+0xa0>
movaps %xmm2,%xmm3
jmp    11e0 <bessi+0xa0>
movss  0xd91(%rip),%xmm1
xorps  %xmm3,%xmm3
movaps %xmm1,0x10(%rsp)
movaps %xmm3,0x30(%rsp)
movaps 0x20(%rsp),%xmm0
call   1050 <bessi0@plt>
movaps 0x20(%rsp),%xmm2
divss  0x10(%rsp),%xmm0
mulss  0x30(%rsp),%xmm0
cmpnltss 0xd64(%rip),%xmm2
movaps %xmm2,%xmm1
andps  %xmm0,%xmm1
test   $0x1,%r14b
je     12d3 <bessi+0x193>
xorps  0xd7d(%rip),%xmm0
andnps %xmm0,%xmm2
orps   %xmm1,%xmm2
movaps %xmm2,%xmm0
add    $0x40,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
@.str = [29 x i8] c"Index n less than 2 in bessi\00"
define float @bessi(i32 %0, float %1) {
%3 = alloca float
%4 = alloca i32
%5 = alloca float
%6 = alloca i32
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float
%11 = alloca float
store i32 %0, i32* %4
store float %1, float* %5
%12 = load i32, i32* %4
%13 = icmp slt i32 %12, 2
br i1 %13, label %14, label %15
14: ; preds = %2
br label %15
15: ; preds = %14, %2
%16 = load float, float* %5
%17 = fpext float %16 to double
%18 = fcmp oeq double %17, 0.000000e+00
br i1 %18, label %19, label %20
19: ; preds = %15
store float 0.000000e+00, float* %3
br label %93
20: ; preds = %15
%21 = load float, float* %5
%22 = call double @fabs(float %21)
%23 = fdiv double 2.000000e+00, %22
%24 = fptrunc double %23 to float
store float %24, float* %10
store float 0.000000e+00, float* %11
store float 0.000000e+00, float* %9
store float 1.000000e+00, float* %7
%25 = load i32, i32* %4
%26 = load i32, i32* %4
%27 = sitofp i32 %26 to double
%28 = fmul double 4.000000e+01, %27
%29 = call i64 @sqrt(double %28)
%30 = trunc i64 %29 to i32
%31 = add nsw i32 %25, %30
%32 = mul nsw i32 2, %31
store i32 %32, i32* %6
br label %33
33: ; preds = %69, %20
%34 = load i32, i32* %6
%35 = icmp sgt i32 %34, 0
br i1 %35, label %36, label %72
36: ; preds = %33
%37 = load float, float* %9
%38 = load i32, i32* %6
%39 = sitofp i32 %38 to float
%40 = load float, float* %10
%41 = fmul float %39, %40
%42 = load float, float* %7
%43 = call float @llvm.fmuladd.f32(float %41, float %42, float %37)
store float %43, float* %8
%44 = load float, float* %7
store float %44, float* %9
%45 = load float, float* %8
store float %45, float* %7
%46 = load float, float* %7
%47 = call double @fabs(float %46)
%48 = fcmp ogt double %47, 1.000000e+10
br i1 %48, label %49, label %62
49: ; preds = %36
%50 = load float, float* %11
%51 = fpext float %50 to double
%52 = fmul double %51, 1.000000e-10
%53 = fptrunc double %52 to float
store float %53, float* %11
%54 = load float, float* %7
%55 = fpext float %54 to double
%56 = fmul double %55, 1.000000e-10
%57 = fptrunc double %56 to float
store float %57, float* %7
%58 = load float, float* %9
%59 = fpext float %58 to double
%60 = fmul double %59, 1.000000e-10
%61 = fptrunc double %60 to float
store float %61, float* %9
br label %62
62: ; preds = %49, %36
%63 = load i32, i32* %6
%64 = load i32, i32* %4
%65 = icmp eq i32 %63, %64
br i1 %65, label %66, label %68
66: ; preds = %62
%67 = load float, float* %9
store float %67, float* %11
br label %68
68: ; preds = %66, %62
br label %69
69: ; preds = %68
%70 = load i32, i32* %6
%71 = add nsw i32 %70, -1
store i32 %71, i32* %6
br label %33
72: ; preds = %33
%73 = load float, float* %5
%74 = call float @bessi0(float %73)
%75 = load float, float* %7
%76 = fdiv float %74, %75
%77 = load float, float* %11
%78 = fmul float %77, %76
store float %78, float* %11
%79 = load float, float* %5
%80 = fpext float %79 to double
%81 = fcmp olt double %80, 0.000000e+00
br i1 %81, label %82, label %89
82: ; preds = %72
%83 = load i32, i32* %4
%84 = and i32 %83, 1
%85 = icmp ne i32 %84, 0
br i1 %85, label %86, label %89
86: ; preds = %82
%87 = load float, float* %11
%88 = fneg float %87
br label %91
89: ; preds = %82, %72
%90 = load float, float* %11
br label %91
91: ; preds = %89, %86
%92 = phi float [ %88, %86 ], [ %90, %89 ]
store float %92, float* %3
br label %93
93: ; preds = %91, %19
%94 = load float, float* %3
ret float %94
}

LLVM IR (-O2):
@.str = [29 x i8] c"Index n less than 2 in bessi\00"
define float @bessi(i32 %0, float %1) {
%3 = icmp slt i32 %0, 2
br i1 %3, label %4, label %5
4: ; preds = %2
tail call void @nrerror(i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str, i64 0, i64 0))
br label %5
5: ; preds = %4, %2
%6 = fcmp oeq float %1, 0.000000e+00
br i1 %6, label %59, label %7
7: ; preds = %5
%8 = tail call double @fabs(float %1)
%9 = fdiv double 2.000000e+00, %8
%10 = fptrunc double %9 to float
%11 = sitofp i32 %0 to double
%12 = fmul double %11, 4.000000e+01
%13 = tail call i64 @sqrt(double %12)
%14 = trunc i64 %13 to i32
%15 = add nsw i32 %14, %0
%16 = icmp sgt i32 %15, 0
br i1 %16, label %17, label %47
17: ; preds = %7
%18 = shl nuw nsw i32 %15, 1
br label %19
19: ; preds = %17, %36
%20 = phi float [ %41, %36 ], [ 0.000000e+00, %17 ]
%21 = phi i32 [ %43, %36 ], [ %18, %17 ]
%22 = phi <2 x float> [ %46, %36 ], [ <float 0.000000e+00, float 1.000000e+00>, %17 ]
%23 = sitofp i32 %21 to float
%24 = fmul float %10, %23
%25 = extractelement <2 x float> %22, i64 1
%26 = tail call float @llvm.fmuladd.f32(float %24, float %25, float %20)
%27 = tail call double @fabs(float %26)
%28 = fcmp ogt double %27, 1.000000e+10
br i1 %28, label %29, label %36
29: ; preds = %19
%30 = fpext float %26 to double
%31 = fmul double %30, 1.000000e-10
%32 = fptrunc double %31 to float
%33 = fpext <2 x float> %22 to <2 x double>
%34 = fmul <2 x double> %33, <double 1.000000e-10, double 1.000000e-10>
%35 = fptrunc <2 x double> %34 to <2 x float>
br label %36
36: ; preds = %29, %19
%37 = phi float [ %32, %29 ], [ %26, %19 ]
%38 = phi <2 x float> [ %35, %29 ], [ %22, %19 ]
%39 = icmp eq i32 %21, %0
%40 = extractelement <2 x float> %38, i64 0
%41 = extractelement <2 x float> %38, i64 1
%42 = select i1 %39, float %41, float %40
%43 = add nsw i32 %21, -1
%44 = icmp sgt i32 %21, 1
%45 = insertelement <2 x float> poison, float %42, i64 0
%46 = insertelement <2 x float> %45, float %37, i64 1
br i1 %44, label %19, label %47
47: ; preds = %36, %7
%48 = phi float [ 1.000000e+00, %7 ], [ %37, %36 ]
%49 = phi float [ 0.000000e+00, %7 ], [ %42, %36 ]
%50 = tail call float @bessi0(float %1)
%51 = fdiv float %50, %48
%52 = fmul float %49, %51
%53 = fcmp uge float %1, 0.000000e+00
%54 = and i32 %0, 1
%55 = icmp eq i32 %54, 0
%56 = or i1 %53, %55
%57 = fneg float %52
%58 = select i1 %56, float %52, float %57
br label %59
59: ; preds = %5, %47
%60 = phi float [ %58, %47 ], [ 0.000000e+00, %5 ]
ret float %60
}