#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);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *);
double sqrt(double);
int /*<<< orphan*/ stderr;
double besi0(double x) {
  int i;
  double w, wx375;
  static double a[6] = {1.0,       3.5156229, 3.0899424,
                        1.2067492, 0.2659732, 0.0360768};
  static double b[8] = {0.39894228,  0.013285917,  0.002253187, -0.001575649,
                        0.009162808, -0.020577063, 0.026355372, -0.016476329};
  if (x < 0.) {
    fprintf(stderr, "Error : x < 0  in besi0()\n");
    return 0.;
  }
  if (x <= 3.75) {
    wx375 = x * x / 14.0625;
    w = 0.0045813;
    for (i = 5; i >= 0; i--)
      w = w * wx375 + a[i];
    return w;
  }
  wx375 = 3.75 / x;
  w = 0.003923767;
  for (i = 7; i >= 0; i--)
    w = w * wx375 + b[i];
  return w / sqrt(x) * exp(x);
}


x86 assembly (clang, -O0):
<besi0>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x10(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    116d <besi0+0x3d>
mov    0x2e8e(%rip),%rax
mov    (%rax),%edi
lea    0xec5(%rip),%rsi
call   1030 <fprintf@plt>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12a2 <besi0+0x172>
movsd  0xe8b(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     11fd <besi0+0xcd>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  0xe86(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xe6d(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
movl   $0x5,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jl     11ee <besi0+0xbe>
movsd  -0x20(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm2
movslq -0x14(%rbp),%rcx
lea    0x2e72(%rip),%rax
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    11af <besi0+0x7f>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12a2 <besi0+0x172>
movsd  0xdfb(%rip),%xmm0
divsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xdf1(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
movl   $0x7,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jl     1262 <besi0+0x132>
movsd  -0x20(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm2
movslq -0x14(%rbp),%rcx
lea    0x2e2e(%rip),%rax
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    1223 <besi0+0xf3>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1050 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  -0x38(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1040 <exp@plt>
movaps %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<besi0>:
sub    $0x18,%rsp
movapd %xmm0,%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
jbe    1160 <besi0+0x30>
mov    0x2e97(%rip),%rax
mov    (%rax),%edi
lea    0xf3e(%rip),%rsi
call   1030 <fprintf@plt>
xorpd  %xmm0,%xmm0
add    $0x18,%rsp
ret
movsd  0xe98(%rip),%xmm0
ucomisd %xmm1,%xmm0
jae    11f7 <besi0+0xc7>
divsd  %xmm1,%xmm0
movsd  0xeca(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xec6(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xec2(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xebe(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xeba(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xeb6(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xeb2(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xeae(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xeaa(%rip),%xmm2
movsd  %xmm2,0x8(%rsp)
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jb     1258 <besi0+0x128>
xorps  %xmm0,%xmm0
sqrtsd %xmm1,%xmm0
jmp    126d <besi0+0x13d>
mulsd  %xmm1,%xmm1
divsd  0xe05(%rip),%xmm1
movsd  0xe05(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xe01(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xdfd(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xdf9(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xdf5(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xdf1(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xded(%rip),%xmm0
add    $0x18,%rsp
ret
movapd %xmm1,%xmm0
movsd  %xmm1,0x10(%rsp)
call   1050 <sqrt@plt>
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
divsd  %xmm0,%xmm2
movsd  %xmm2,0x8(%rsp)
movapd %xmm1,%xmm0
call   1040 <exp@plt>
mulsd  0x8(%rsp),%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
@besi0.a = internal global [6 x double] [double 1.000000e+00, double 0x400C1FFEE6248CA7, double 0x4008B833B89430A4, double 0x3FF34ED83FC7962C, double 0x3FD105B474E732AA, double 3.607680e-02]
@besi0.b = internal global [8 x double] [double 0x3FD988453365DE00, double 0x3F8B35A5981955AB, double 0x3F6275468F41B817, double 0xBF59D0C03B32CAC7, double 0x3F82C3F34598A1B3, double 0xBF9512275287EACE, double 0x3F9AFCE7134172B3, double 0xBF90DF2BB8DA406D]
@stderr = global i32 0
@.str = [27 x i8] c"Error : x < 0 in besi0()\0A\00"
define double @besi0(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca i32
%5 = alloca double
%6 = alloca double
store double %0, double* %3
%7 = load double, double* %3
%8 = fcmp olt double %7, 0.000000e+00
br i1 %8, label %9, label %12
9: ; preds = %1
%10 = load i32, i32* @stderr
%11 = call i32 @fprintf(i32 %10, i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0))
store double 0.000000e+00, double* %2
br label %61
12: ; preds = %1
%13 = load double, double* %3
%14 = fcmp ole double %13, 3.750000e+00
br i1 %14, label %15, label %36
15: ; preds = %12
%16 = load double, double* %3
%17 = load double, double* %3
%18 = fmul double %16, %17
%19 = fdiv double %18, 1.406250e+01
store double %19, double* %6
store double 4.581300e-03, double* %5
store i32 5, i32* %4
br label %20
20: ; preds = %31, %15
%21 = load i32, i32* %4
%22 = icmp sge i32 %21, 0
br i1 %22, label %23, label %34
23: ; preds = %20
%24 = load double, double* %5
%25 = load double, double* %6
%26 = load i32, i32* %4
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds [6 x double], [6 x double]* @besi0.a, i64 0, i64 %27
%29 = load double, double* %28
%30 = call double @llvm.fmuladd.f64(double %24, double %25, double %29)
store double %30, double* %5
br label %31
31: ; preds = %23
%32 = load i32, i32* %4
%33 = add nsw i32 %32, -1
store i32 %33, i32* %4
br label %20
34: ; preds = %20
%35 = load double, double* %5
store double %35, double* %2
br label %61
36: ; preds = %12
%37 = load double, double* %3
%38 = fdiv double 3.750000e+00, %37
store double %38, double* %6
store double 0x3F70125E2F12F0A6, double* %5
store i32 7, i32* %4
br label %39
39: ; preds = %50, %36
%40 = load i32, i32* %4
%41 = icmp sge i32 %40, 0
br i1 %41, label %42, label %53
42: ; preds = %39
%43 = load double, double* %5
%44 = load double, double* %6
%45 = load i32, i32* %4
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds [8 x double], [8 x double]* @besi0.b, i64 0, i64 %46
%48 = load double, double* %47
%49 = call double @llvm.fmuladd.f64(double %43, double %44, double %48)
store double %49, double* %5
br label %50
50: ; preds = %42
%51 = load i32, i32* %4
%52 = add nsw i32 %51, -1
store i32 %52, i32* %4
br label %39
53: ; preds = %39
%54 = load double, double* %5
%55 = load double, double* %3
%56 = call double @sqrt(double %55)
%57 = fdiv double %54, %56
%58 = load double, double* %3
%59 = call double @exp(double %58)
%60 = fmul double %57, %59
store double %60, double* %2
br label %61
61: ; preds = %53, %34, %9
%62 = load double, double* %2
ret double %62
}

LLVM IR (-O2):
@stderr = global i32 0
@.str = [27 x i8] c"Error : x < 0 in besi0()\0A\00"
define double @besi0(double %0) {
%2 = fcmp olt double %0, 0.000000e+00
br i1 %2, label %3, label %6
3: ; preds = %1
%4 = load i32, i32* @stderr
%5 = tail call i32 @fprintf(i32 %4, i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0))
br label %31
6: ; preds = %1
%7 = fcmp ugt double %0, 3.750000e+00
br i1 %7, label %17, label %8
8: ; preds = %6
%9 = fmul double %0, %0
%10 = fdiv double %9, 1.406250e+01
%11 = tail call double @llvm.fmuladd.f64(double %10, double 4.581300e-03, double 3.607680e-02)
%12 = tail call double @llvm.fmuladd.f64(double %11, double %10, double 0x3FD105B474E732AA)
%13 = tail call double @llvm.fmuladd.f64(double %12, double %10, double 0x3FF34ED83FC7962C)
%14 = tail call double @llvm.fmuladd.f64(double %13, double %10, double 0x4008B833B89430A4)
%15 = tail call double @llvm.fmuladd.f64(double %14, double %10, double 0x400C1FFEE6248CA7)
%16 = tail call double @llvm.fmuladd.f64(double %15, double %10, double 1.000000e+00)
br label %31
17: ; preds = %6
%18 = fdiv double 3.750000e+00, %0
%19 = tail call double @llvm.fmuladd.f64(double %18, double 0x3F70125E2F12F0A6, double 0xBF90DF2BB8DA406D)
%20 = tail call double @llvm.fmuladd.f64(double %19, double %18, double 0x3F9AFCE7134172B3)
%21 = tail call double @llvm.fmuladd.f64(double %20, double %18, double 0xBF9512275287EACE)
%22 = tail call double @llvm.fmuladd.f64(double %21, double %18, double 0x3F82C3F34598A1B3)
%23 = tail call double @llvm.fmuladd.f64(double %22, double %18, double 0xBF59D0C03B32CAC7)
%24 = tail call double @llvm.fmuladd.f64(double %23, double %18, double 0x3F6275468F41B817)
%25 = tail call double @llvm.fmuladd.f64(double %24, double %18, double 0x3F8B35A5981955AB)
%26 = tail call double @llvm.fmuladd.f64(double %25, double %18, double 0x3FD988453365DE00)
%27 = tail call double @sqrt(double %0)
%28 = fdiv double %26, %27
%29 = tail call double @exp(double %0)
%30 = fmul double %28, %29
br label %31
31: ; preds = %8, %17, %3
%32 = phi double [ 0.000000e+00, %3 ], [ %30, %17 ], [ %16, %8 ]
ret double %32
}