#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 bessi0(double);
double exp(double);
double log(double);
double sqrt(double);
double bessk0(double x) {
  double y, ans;
  static double P[7] = {-0.57721566, 0.42278420, 0.23069756, 0.3488590e-1,
                        0.262698e-2, 0.10750e-3, 0.74e-5};
  static double Q[7] = {1.25331414,  -0.7832358e-1, 0.2189568e-1, -0.1062446e-1,
                        0.587872e-2, -0.251540e-2,  0.53208e-3};
  if (x <= 2.0) {
    y = x * x / 4.0;
    ans = (-log(x / 2.0) * bessi0(x)) +
          (P[0] +
           y * (P[1] +
                y * (P[2] + y * (P[3] + y * (P[4] + y * (P[5] + y * P[6]))))));
  } else {
    y = 2.0 / x;
    ans = (exp(-x) / sqrt(x)) *
          (Q[0] +
           y * (Q[1] +
                y * (Q[2] + y * (Q[3] + y * (Q[4] + y * (Q[5] + y * Q[6]))))));
  }
  return ans;
}


x86 assembly (clang, -O0):
<bessk0>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  0xeab(%rip),%xmm0
ucomisd -0x8(%rbp),%xmm0
jb     1265 <bessk0+0x125>
movsd  -0x8(%rbp),%xmm0
mulsd  -0x8(%rbp),%xmm0
movsd  0xe96(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  0xe78(%rip),%xmm1
divsd  %xmm1,%xmm0
call   1050 <log@plt>
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x8(%rbp),%xmm0
call   1030 <bessi0@plt>
movaps %xmm0,%xmm2
movsd  -0x20(%rbp),%xmm0
movsd  0x2e89(%rip),%xmm3
movsd  -0x10(%rbp),%xmm1
movsd  0x2e84(%rip),%xmm5
movsd  -0x10(%rbp),%xmm4
movsd  0x2e7f(%rip),%xmm7
movsd  -0x10(%rbp),%xmm6
movsd  0x2e79(%rip),%xmm9
movsd  -0x10(%rbp),%xmm8
movsd  0x2e72(%rip),%xmm11
movsd  -0x10(%rbp),%xmm10
movsd  0x2e6b(%rip),%xmm13
movsd  -0x10(%rbp),%xmm12
movsd  0x2e64(%rip),%xmm14
mulsd  %xmm14,%xmm12
addsd  %xmm13,%xmm12
mulsd  %xmm12,%xmm10
addsd  %xmm11,%xmm10
mulsd  %xmm10,%xmm8
addsd  %xmm9,%xmm8
mulsd  %xmm8,%xmm6
addsd  %xmm7,%xmm6
mulsd  %xmm6,%xmm4
addsd  %xmm5,%xmm4
mulsd  %xmm4,%xmm1
addsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    134e <bessk0+0x20e>
movsd  0xd93(%rip),%xmm0
divsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x8(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1040 <exp@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
call   1060 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  -0x28(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  0x2dd5(%rip),%xmm2
movsd  -0x10(%rbp),%xmm1
movsd  0x2dd0(%rip),%xmm4
movsd  -0x10(%rbp),%xmm3
movsd  0x2dcb(%rip),%xmm6
movsd  -0x10(%rbp),%xmm5
movsd  0x2dc5(%rip),%xmm8
movsd  -0x10(%rbp),%xmm7
movsd  0x2dbf(%rip),%xmm10
movsd  -0x10(%rbp),%xmm9
movsd  0x2db8(%rip),%xmm12
movsd  -0x10(%rbp),%xmm11
movsd  0x2db1(%rip),%xmm13
mulsd  %xmm13,%xmm11
addsd  %xmm12,%xmm11
mulsd  %xmm11,%xmm9
addsd  %xmm10,%xmm9
mulsd  %xmm9,%xmm7
addsd  %xmm8,%xmm7
mulsd  %xmm7,%xmm5
addsd  %xmm6,%xmm5
mulsd  %xmm5,%xmm3
addsd  %xmm4,%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bessk0>:
sub    $0x38,%rsp
movapd %xmm0,%xmm1
movsd  0xeb0(%rip),%xmm0
ucomisd %xmm1,%xmm0
movapd %xmm1,0x10(%rsp)
jae    119b <bessk0+0x5b>
divsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rsp)
movapd 0xf22(%rip),%xmm0
xorpd  %xmm1,%xmm0
call   1040 <exp@plt>
movapd 0x10(%rsp),%xmm1
movapd %xmm0,%xmm3
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jb     1235 <bessk0+0xf5>
xorps  %xmm0,%xmm0
sqrtsd %xmm1,%xmm0
jmp    124a <bessk0+0x10a>
movapd %xmm1,%xmm0
mulsd  %xmm1,%xmm0
mulsd  0xe5d(%rip),%xmm0
movapd %xmm0,0x20(%rsp)
movsd  0xe57(%rip),%xmm0
mulsd  %xmm1,%xmm0
call   1050 <log@plt>
movsd  %xmm0,0x8(%rsp)
movapd 0x10(%rsp),%xmm0
call   1030 <bessi0@plt>
movsd  0xe3d(%rip),%xmm1
movapd 0x20(%rsp),%xmm2
mulsd  %xmm2,%xmm1
addsd  0xe33(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xe2f(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xe2b(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xe27(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xe23(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xe1f(%rip),%xmm1
mulsd  0x8(%rsp),%xmm0
subsd  %xmm0,%xmm1
jmp    12a8 <bessk0+0x168>
movapd %xmm1,%xmm0
movsd  %xmm3,0x10(%rsp)
call   1060 <sqrt@plt>
movsd  0x10(%rsp),%xmm3
movsd  0xdfe(%rip),%xmm1
movsd  0x8(%rsp),%xmm2
mulsd  %xmm2,%xmm1
addsd  0xdf4(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xdf0(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xdec(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xde8(%rip),%xmm1
divsd  %xmm0,%xmm3
mulsd  %xmm2,%xmm1
addsd  0xde0(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0xddc(%rip),%xmm1
mulsd  %xmm3,%xmm1
movapd %xmm1,%xmm0
add    $0x38,%rsp
ret

LLVM IR (-O0):
@bessk0.P = internal global [7 x double] [double 0xBFE2788CF9CE0CBE, double 0x3FDB0EE57610FE55, double 0x3FCD877F65BBC695, double 3.488590e-02, double 2.626980e-03, double 1.075000e-04, double 7.400000e-06]
@bessk0.Q = internal global [7 x double] [double 0x3FF40D9320AEA13E, double 0xBFB40D039E9B0B34, double 0x3F966BD236183FE8, double 0xBF85C246E1E6BA5F, double 5.878720e-03, double -2.515400e-03, double 5.320800e-04]
define double @bessk0(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca double
store double %0, double* %2
%5 = load double, double* %2
%6 = fcmp ole double %5, 2.000000e+00
br i1 %6, label %7, label %38
7: ; preds = %1
%8 = load double, double* %2
%9 = load double, double* %2
%10 = fmul double %8, %9
%11 = fdiv double %10, 4.000000e+00
store double %11, double* %3
%12 = load double, double* %2
%13 = fdiv double %12, 2.000000e+00
%14 = call double @log(double %13)
%15 = fneg double %14
%16 = load double, double* %2
%17 = call double @bessi0(double %16)
%18 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.P, i64 0, i64 0)
%19 = load double, double* %3
%20 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.P, i64 0, i64 1)
%21 = load double, double* %3
%22 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.P, i64 0, i64 2)
%23 = load double, double* %3
%24 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.P, i64 0, i64 3)
%25 = load double, double* %3
%26 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.P, i64 0, i64 4)
%27 = load double, double* %3
%28 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.P, i64 0, i64 5)
%29 = load double, double* %3
%30 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.P, i64 0, i64 6)
%31 = call double @llvm.fmuladd.f64(double %29, double %30, double %28)
%32 = call double @llvm.fmuladd.f64(double %27, double %31, double %26)
%33 = call double @llvm.fmuladd.f64(double %25, double %32, double %24)
%34 = call double @llvm.fmuladd.f64(double %23, double %33, double %22)
%35 = call double @llvm.fmuladd.f64(double %21, double %34, double %20)
%36 = call double @llvm.fmuladd.f64(double %19, double %35, double %18)
%37 = call double @llvm.fmuladd.f64(double %15, double %17, double %36)
store double %37, double* %4
br label %67
38: ; preds = %1
%39 = load double, double* %2
%40 = fdiv double 2.000000e+00, %39
store double %40, double* %3
%41 = load double, double* %2
%42 = fneg double %41
%43 = call double @exp(double %42)
%44 = load double, double* %2
%45 = call double @sqrt(double %44)
%46 = fdiv double %43, %45
%47 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.Q, i64 0, i64 0)
%48 = load double, double* %3
%49 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.Q, i64 0, i64 1)
%50 = load double, double* %3
%51 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.Q, i64 0, i64 2)
%52 = load double, double* %3
%53 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.Q, i64 0, i64 3)
%54 = load double, double* %3
%55 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.Q, i64 0, i64 4)
%56 = load double, double* %3
%57 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.Q, i64 0, i64 5)
%58 = load double, double* %3
%59 = load double, double* getelementptr inbounds ([7 x double], [7 x double]* @bessk0.Q, i64 0, i64 6)
%60 = call double @llvm.fmuladd.f64(double %58, double %59, double %57)
%61 = call double @llvm.fmuladd.f64(double %56, double %60, double %55)
%62 = call double @llvm.fmuladd.f64(double %54, double %61, double %53)
%63 = call double @llvm.fmuladd.f64(double %52, double %62, double %51)
%64 = call double @llvm.fmuladd.f64(double %50, double %63, double %49)
%65 = call double @llvm.fmuladd.f64(double %48, double %64, double %47)
%66 = fmul double %46, %65
store double %66, double* %4
br label %67
67: ; preds = %38, %7
%68 = load double, double* %4
ret double %68
}

LLVM IR (-O2):
define double @bessk0(double %0) {
%2 = fcmp ugt double %0, 2.000000e+00
br i1 %2, label %17, label %3
3: ; preds = %1
%4 = fmul double %0, %0
%5 = fmul double %4, 2.500000e-01
%6 = fmul double %0, 5.000000e-01
%7 = tail call double @log(double %6)
%8 = fneg double %7
%9 = tail call double @bessi0(double %0)
%10 = tail call double @llvm.fmuladd.f64(double %5, double 7.400000e-06, double 1.075000e-04)
%11 = tail call double @llvm.fmuladd.f64(double %5, double %10, double 2.626980e-03)
%12 = tail call double @llvm.fmuladd.f64(double %5, double %11, double 3.488590e-02)
%13 = tail call double @llvm.fmuladd.f64(double %5, double %12, double 0x3FCD877F65BBC695)
%14 = tail call double @llvm.fmuladd.f64(double %5, double %13, double 0x3FDB0EE57610FE55)
%15 = tail call double @llvm.fmuladd.f64(double %5, double %14, double 0xBFE2788CF9CE0CBE)
%16 = tail call double @llvm.fmuladd.f64(double %8, double %9, double %15)
br label %30
17: ; preds = %1
%18 = fdiv double 2.000000e+00, %0
%19 = fneg double %0
%20 = tail call double @exp(double %19)
%21 = tail call double @sqrt(double %0)
%22 = fdiv double %20, %21
%23 = tail call double @llvm.fmuladd.f64(double %18, double 5.320800e-04, double -2.515400e-03)
%24 = tail call double @llvm.fmuladd.f64(double %18, double %23, double 5.878720e-03)
%25 = tail call double @llvm.fmuladd.f64(double %18, double %24, double 0xBF85C246E1E6BA5F)
%26 = tail call double @llvm.fmuladd.f64(double %18, double %25, double 0x3F966BD236183FE8)
%27 = tail call double @llvm.fmuladd.f64(double %18, double %26, double 0xBFB40D039E9B0B34)
%28 = tail call double @llvm.fmuladd.f64(double %18, double %27, double 0x3FF40D9320AEA13E)
%29 = fmul double %28, %22
br label %30
30: ; preds = %17, %3
%31 = phi double [ %16, %3 ], [ %29, %17 ]
ret double %31
}