#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 exp(double);
double log(double);
double Ei(double u) {
  double s1, s2;
  if (u > 60.0 || u <= 0.0)
    return (0.0);
  if (u < 1.0) {
    s1 = ((((0.00107857 * u - 0.00976004) * u + 0.05519968) * u - 0.24991055) *
              u +
          0.99999193) *
             u -
         0.57721566;
    return (s1 - log(u));
  } else {
    s1 = (((u + 8.57332875) * u + 18.05901697) * u + 8.63476088) * u +
         0.267773734;
    s2 = (((u + 9.57332875) * u + 25.63295615) * u + 21.09965308) * u +
         3.958496923;
    return ((1 / u) * (s1 / s2) * exp(-u));
  }
}


x86 assembly (clang, -O0):
<Ei>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  0xec6(%rip),%xmm1
ucomisd %xmm1,%xmm0
ja     1152 <Ei+0x32>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     115f <Ei+0x3f>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1307 <Ei+0x1e7>
movsd  0xea1(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1212 <Ei+0xf2>
movsd  -0x10(%rbp),%xmm0
movsd  0xef1(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xeed(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xec8(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xeab(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe8e(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe71(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1040 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x28(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1307 <Ei+0x1e7>
movsd  0xe2e(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe10(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xdf3(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xdd6(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xdbd(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xd9f(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xd82(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xd65(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xd4c(%rip),%xmm0
divsd  -0x10(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
divsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1030 <exp@plt>
movsd  -0x30(%rbp),%xmm0
cvtsi2sd %eax,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Ei>:
sub    $0x18,%rsp
ucomisd 0xed4(%rip),%xmm0
xorpd  %xmm2,%xmm2
ja     1250 <Ei+0x130>
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jae    1250 <Ei+0x130>
movsd  0xebc(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    11ae <Ei+0x8e>
movsd  0xef6(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xef2(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xeee(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xeea(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xee6(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xee2(%rip),%xmm1
movsd  %xmm1,(%rsp)
call   1040 <log@plt>
movsd  (%rsp),%xmm2
subsd  %xmm0,%xmm2
jmp    1250 <Ei+0x130>
movsd  0xe5a(%rip),%xmm1
addsd  %xmm0,%xmm1
mulsd  %xmm0,%xmm1
addsd  0xe52(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xe4e(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xe4a(%rip),%xmm1
movsd  0xe4a(%rip),%xmm2
addsd  %xmm0,%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe42(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe3e(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe3a(%rip),%xmm2
movapd 0xe6a(%rip),%xmm3
unpcklpd %xmm1,%xmm3
movapd %xmm0,%xmm1
unpcklpd %xmm2,%xmm1
divpd  %xmm1,%xmm3
movapd %xmm3,%xmm1
unpckhpd %xmm3,%xmm1
mulsd  %xmm3,%xmm1
movapd %xmm1,(%rsp)
xorpd  0xe51(%rip),%xmm0
call   1030 <exp@plt>
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
mulsd  (%rsp),%xmm2
movapd %xmm2,%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
define double @Ei(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca double
store double %0, double* %3
%6 = load double, double* %3
%7 = fcmp ogt double %6, 6.000000e+01
br i1 %7, label %11, label %8
8: ; preds = %1
%9 = load double, double* %3
%10 = fcmp ole double %9, 0.000000e+00
br i1 %10, label %11, label %12
11: ; preds = %8, %1
store double 0.000000e+00, double* %2
br label %58
12: ; preds = %8
%13 = load double, double* %3
%14 = fcmp olt double %13, 1.000000e+00
br i1 %14, label %15, label %30
15: ; preds = %12
%16 = load double, double* %3
%17 = call double @llvm.fmuladd.f64(double 1.078570e-03, double %16, double 0xBF83FD1264DC7891)
%18 = load double, double* %3
%19 = call double @llvm.fmuladd.f64(double %17, double %18, double 0x3FAC4321E8B30754)
%20 = load double, double* %3
%21 = call double @llvm.fmuladd.f64(double %19, double %20, double 0xBFCFFD11A396729E)
%22 = load double, double* %3
%23 = call double @llvm.fmuladd.f64(double %21, double %22, double 0x3FEFFFEF1373A53E)
%24 = load double, double* %3
%25 = call double @llvm.fmuladd.f64(double %23, double %24, double 0xBFE2788CF9CE0CBE)
store double %25, double* %4
%26 = load double, double* %4
%27 = load double, double* %3
%28 = call double @log(double %27)
%29 = fsub double %26, %28
store double %29, double* %2
br label %58
30: ; preds = %12
%31 = load double, double* %3
%32 = fadd double %31, 0x4021258B588E368F
%33 = load double, double* %3
%34 = call double @llvm.fmuladd.f64(double %32, double %33, double 0x40320F1BBC740F1B)
%35 = load double, double* %3
%36 = call double @llvm.fmuladd.f64(double %34, double %35, double 0x402144FF60C8C2A7)
%37 = load double, double* %3
%38 = call double @llvm.fmuladd.f64(double %36, double %37, double 0x3FD1233471907FD9)
store double %38, double* %4
%39 = load double, double* %3
%40 = fadd double %39, 0x4023258B588E368F
%41 = load double, double* %3
%42 = call double @llvm.fmuladd.f64(double %40, double %41, double 0x4039A2096A0C0D54)
%43 = load double, double* %3
%44 = call double @llvm.fmuladd.f64(double %42, double %43, double 0x40351982DD3F8BB1)
%45 = load double, double* %3
%46 = call double @llvm.fmuladd.f64(double %44, double %45, double 0x400FAB006F4CD023)
store double %46, double* %5
%47 = load double, double* %3
%48 = fdiv double 1.000000e+00, %47
%49 = load double, double* %4
%50 = load double, double* %5
%51 = fdiv double %49, %50
%52 = fmul double %48, %51
%53 = load double, double* %3
%54 = fneg double %53
%55 = call i32 @exp(double %54)
%56 = sitofp i32 %55 to double
%57 = fmul double %52, %56
store double %57, double* %2
br label %58
58: ; preds = %30, %15, %11
%59 = load double, double* %2
ret double %59
}

LLVM IR (-O2):
define double @Ei(double %0) {
%2 = fcmp ogt double %0, 6.000000e+01
%3 = fcmp ole double %0, 0.000000e+00
%4 = or i1 %2, %3
br i1 %4, label %35, label %5
5: ; preds = %1
%6 = fcmp olt double %0, 1.000000e+00
br i1 %6, label %7, label %15
7: ; preds = %5
%8 = tail call double @llvm.fmuladd.f64(double %0, double 1.078570e-03, double 0xBF83FD1264DC7891)
%9 = tail call double @llvm.fmuladd.f64(double %8, double %0, double 0x3FAC4321E8B30754)
%10 = tail call double @llvm.fmuladd.f64(double %9, double %0, double 0xBFCFFD11A396729E)
%11 = tail call double @llvm.fmuladd.f64(double %10, double %0, double 0x3FEFFFEF1373A53E)
%12 = tail call double @llvm.fmuladd.f64(double %11, double %0, double 0xBFE2788CF9CE0CBE)
%13 = tail call double @log(double %0)
%14 = fsub double %12, %13
br label %35
15: ; preds = %5
%16 = fadd double %0, 0x4021258B588E368F
%17 = tail call double @llvm.fmuladd.f64(double %16, double %0, double 0x40320F1BBC740F1B)
%18 = tail call double @llvm.fmuladd.f64(double %17, double %0, double 0x402144FF60C8C2A7)
%19 = tail call double @llvm.fmuladd.f64(double %18, double %0, double 0x3FD1233471907FD9)
%20 = fadd double %0, 0x4023258B588E368F
%21 = tail call double @llvm.fmuladd.f64(double %20, double %0, double 0x4039A2096A0C0D54)
%22 = tail call double @llvm.fmuladd.f64(double %21, double %0, double 0x40351982DD3F8BB1)
%23 = tail call double @llvm.fmuladd.f64(double %22, double %0, double 0x400FAB006F4CD023)
%24 = insertelement <2 x double> <double 1.000000e+00, double poison>, double %19, i64 1
%25 = insertelement <2 x double> poison, double %0, i64 0
%26 = insertelement <2 x double> %25, double %23, i64 1
%27 = fdiv <2 x double> %24, %26
%28 = shufflevector <2 x double> %27, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%29 = fmul <2 x double> %27, %28
%30 = extractelement <2 x double> %29, i64 0
%31 = fneg double %0
%32 = tail call i32 @exp(double %31)
%33 = sitofp i32 %32 to double
%34 = fmul double %30, %33
br label %35
35: ; preds = %1, %15, %7
%36 = phi double [ %14, %7 ], [ %34, %15 ], [ 0.000000e+00, %1 ]
ret double %36
}