#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);
double fabs(double);
double Ei3(double x) {
  double ei[] = {1.915047433355013959531e2,  4.403798995348382689974e2,
                 1.037878290717089587658e3,  2.492228976241877759138e3,
                 6.071406374098611507965e3,  1.495953266639752885229e4,
                 3.719768849068903560439e4,  9.319251363396537129882e4,
                 2.349558524907683035782e5,  5.955609986708370018502e5,
                 1.516637894042516884433e6,  3.877904330597443502996e6,
                 9.950907251046844760026e6,  2.561565266405658882048e7,
                 6.612718635548492136250e7,  1.711446713003636684975e8,
                 4.439663698302712208698e8,  1.154115391849182948287e9,
                 3.005950906525548689841e9,  7.842940991898186370453e9,
                 2.049649711988081236484e10, 5.364511859231469415605e10,
                 1.405991957584069047340e11, 3.689732094072741970640e11,
                 9.694555759683939661662e11, 2.550043566357786926147e12,
                 6.714640184076497558707e12, 1.769803724411626854310e13,
                 4.669055014466159544500e13, 1.232852079912097685431e14,
                 3.257988998672263996790e14, 8.616388199965786544948e14,
                 2.280446200301902595341e15, 6.039718263611241578359e15,
                 1.600664914324504111070e16, 4.244796092136850759368e16,
                 1.126348290166966760275e17, 2.990444718632336675058e17,
                 7.943916035704453771510e17, 2.111342388647824195000e18,
                 5.614329680810343111535e18, 1.493630213112993142255e19,
                 3.975442747903744836007e19, 1.058563689713169096306e20};
  double epsilon = 1.e-10;
  int k = (int)(x + 0.5);
  int j = 0;
  double xx = (double)k;
  double dx = x - xx;
  double xxj = xx;
  double edx = exp(dx);
  double Sm = 1.;
  double Sn = (edx - 1.) / xxj;
  double term = exp(100.);
  double factorial = 1.;
  double dxj = 1.;
  while (term > epsilon * fabs(Sn)) {
    j++;
    factorial *= (double)j;
    xxj *= xx;
    dxj *= (-dx);
    Sm += (dxj / factorial);
    term = (factorial * (edx * Sm - 1.)) / xxj;
    Sn += term;
  }
  return ei[k - 7] + Sn * exp(xx);
}


x86 assembly (clang, -O0):
<Ei3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1e0,%rsp
movsd  %xmm0,-0x8(%rbp)
lea    -0x170(%rbp),%rdi
lea    0xf02(%rip),%rsi
mov    $0x160,%edx
call   1030 <memcpy@plt>
movsd  0xec8(%rip),%xmm0
movsd  %xmm0,-0x178(%rbp)
ff
movsd  0xeb0(%rip),%xmm0
addsd  -0x8(%rbp),%xmm0
cvttsd2si %xmm0,%eax
mov    %eax,-0x17c(%rbp)
movl   $0x0,-0x180(%rbp)
cvtsi2sdl -0x17c(%rbp),%xmm0
ff
movsd  %xmm0,-0x188(%rbp)
ff
movsd  -0x8(%rbp),%xmm0
subsd  -0x188(%rbp),%xmm0
ff
movsd  %xmm0,-0x190(%rbp)
ff
movsd  -0x188(%rbp),%xmm0
ff
movsd  %xmm0,-0x198(%rbp)
ff
movsd  -0x190(%rbp),%xmm0
ff
call   1040 <exp@plt>
movsd  %xmm0,-0x1a0(%rbp)
ff
movsd  0xe35(%rip),%xmm0
movsd  %xmm0,-0x1a8(%rbp)
ff
movsd  -0x1a0(%rbp),%xmm0
ff
movsd  0xe1d(%rip),%xmm1
subsd  %xmm1,%xmm0
divsd  -0x198(%rbp),%xmm0
ff
movsd  %xmm0,-0x1b0(%rbp)
ff
movsd  0xe09(%rip),%xmm0
call   1040 <exp@plt>
movsd  %xmm0,-0x1b8(%rbp)
ff
movsd  0xdec(%rip),%xmm0
movsd  %xmm0,-0x1c0(%rbp)
ff
movsd  0xddc(%rip),%xmm0
movsd  %xmm0,-0x1c8(%rbp)
ff
movsd  -0x1b8(%rbp),%xmm0
ff
movsd  -0x178(%rbp),%xmm1
ff
movsd  -0x1b0(%rbp),%xmm2
ff
movaps 0xde5(%rip),%xmm3
pand   %xmm3,%xmm2
mulsd  %xmm2,%xmm1
ucomisd %xmm1,%xmm0
jbe    1344 <Ei3+0x224>
mov    -0x180(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x180(%rbp)
cvtsi2sdl -0x180(%rbp),%xmm0
ff
mulsd  -0x1c0(%rbp),%xmm0
ff
movsd  %xmm0,-0x1c0(%rbp)
ff
movsd  -0x188(%rbp),%xmm0
ff
mulsd  -0x198(%rbp),%xmm0
ff
movsd  %xmm0,-0x198(%rbp)
ff
movsd  -0x190(%rbp),%xmm0
ff
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  -0x1c8(%rbp),%xmm0
ff
movsd  %xmm0,-0x1c8(%rbp)
ff
movsd  -0x1c8(%rbp),%xmm0
ff
divsd  -0x1c0(%rbp),%xmm0
ff
addsd  -0x1a8(%rbp),%xmm0
ff
movsd  %xmm0,-0x1a8(%rbp)
ff
movsd  -0x1c0(%rbp),%xmm0
ff
movsd  -0x1a0(%rbp),%xmm1
ff
movsd  -0x1a8(%rbp),%xmm2
ff
mulsd  %xmm2,%xmm1
movsd  0xd11(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
divsd  -0x198(%rbp),%xmm0
ff
movsd  %xmm0,-0x1b8(%rbp)
ff
movsd  -0x1b8(%rbp),%xmm0
ff
addsd  -0x1b0(%rbp),%xmm0
ff
movsd  %xmm0,-0x1b0(%rbp)
ff
jmp    122c <Ei3+0x10c>
mov    -0x17c(%rbp),%eax
sub    $0x7,%eax
cltq
movsd  -0x170(%rbp,%rax,8),%xmm0
ff ff
movsd  %xmm0,-0x1d8(%rbp)
ff
movsd  -0x1b0(%rbp),%xmm0
ff
movsd  %xmm0,-0x1d0(%rbp)
ff
movsd  -0x188(%rbp),%xmm0
ff
call   1040 <exp@plt>
movsd  -0x1d8(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0x1d0(%rbp),%xmm0
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
add    $0x1e0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Ei3>:
push   %r14
push   %rbx
sub    $0x28,%rsp
movsd  0xee1(%rip),%xmm1
addsd  %xmm0,%xmm1
cvttsd2si %xmm1,%ebx
cvttpd2dq %xmm1,%xmm1
cvtdq2pd %xmm1,%xmm1
movapd %xmm1,0x10(%rsp)
subsd  %xmm1,%xmm0
movapd %xmm0,(%rsp)
call   1030 <exp@plt>
movapd 0x10(%rsp),%xmm11
movsd  0xeb6(%rip),%xmm4
addsd  %xmm0,%xmm4
divsd  %xmm11,%xmm4
movapd 0xecd(%rip),%xmm1
andpd  %xmm4,%xmm1
mulsd  0xea1(%rip),%xmm1
movsd  0xea1(%rip),%xmm2
ucomisd %xmm1,%xmm2
jbe    1221 <Ei3+0x111>
movapd (%rsp),%xmm12
xorpd  0xeb0(%rip),%xmm12
movsd  0xe88(%rip),%xmm1
mov    $0x1,%eax
movsd  0xe62(%rip),%xmm8
movapd 0xe81(%rip),%xmm9
movsd  0xe58(%rip),%xmm10
movapd %xmm1,%xmm5
movapd %xmm1,%xmm6
movapd %xmm11,%xmm7
cs nopw 0x0(%rax,%rax,1)
nop
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
mulsd  %xmm2,%xmm5
mulsd  %xmm12,%xmm1
movapd %xmm1,%xmm2
divsd  %xmm5,%xmm2
addsd  %xmm2,%xmm6
movapd %xmm0,%xmm2
mulsd  %xmm6,%xmm2
addsd  %xmm8,%xmm2
mulsd  %xmm11,%xmm7
mulsd  %xmm5,%xmm2
divsd  %xmm7,%xmm2
addsd  %xmm2,%xmm4
movapd %xmm4,%xmm3
andpd  %xmm9,%xmm3
mulsd  %xmm10,%xmm3
add    $0x1,%eax
ucomisd %xmm3,%xmm2
ja     11d0 <Ei3+0xc0>
movapd %xmm4,(%rsp)
movslq %ebx,%rbx
lea    0xe20(%rip),%r14
movapd %xmm11,%xmm0
call   1030 <exp@plt>
mulsd  (%rsp),%xmm0
addsd  -0x38(%r14,%rbx,8),%xmm0
add    $0x28,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
@__const.Ei3.ei = [44 x double] [double 0x4067F026DB7EDB47, double 0x407B86141188DE56, double 0x409037835EA4491F, double 0x40A378753C5FBCDA, double 0x40B7B7680822077A, double 0x40CD37C42E699A88, double 0x40E229B6081DA020, double 0x40F6C08837D83FB6, double 0x410CAE5ED1E6AE10, double 0x41222CD1FF51C8B1, double 0x4137245DE4DFF86B, double 0x414D96082A51045C, double 0x4162FAD768089365, double 0x41786DD24A9FF9CD, double 0x418F882A92D8087A, double 0x41A466EBBE99C944, double 0x41BA7663A1D48CA8, double 0x41D13299CFF65903, double 0x41E665657750D14B, double 0x41FD379C83FE5EF9, double 0x421316BEE77F85F4, double 0x4228FAFF1900A120, double 0x42405E2EBC373415, double 0x42557A2117CFD18C, double 0x426C3701C4740C9B, double 0x42828DD38708AE4C, double 0x42986D7EF8CC31FE, double 0x42B018A53920D445, double 0x42C53B7ED3EF4ACC, double 0x42DC0824C1D0EA71, double 0x42F284FF7B1DE5A6, double 0x43087D3F5E531D15, double 0x4320341B8365929D, double 0x433575177DA55F6A, double 0x434C6EFB361D1C79, double 0x4362D9C642050CF7, double 0x4379028C7BCE0876, double 0x439099AD7375CF32, double 0x43A60C7DE8BEBD19, double 0x43BD4CFEB752940B, double 0x43D37A86C651287F, double 0x43E9E90CF4DFFD1B, double 0x44013DA0C9504871, double 0x4416F4357AE9D01B]
define double @Ei3(double %0) {
%2 = alloca double
%3 = alloca [44 x double]
%4 = alloca double
%5 = alloca i32
%6 = alloca i32
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
store double %0, double* %2
%16 = bitcast [44 x double]* %3 to i8*
store double 1.000000e-10, double* %4
%17 = load double, double* %2
%18 = fadd double %17, 5.000000e-01
%19 = fptosi double %18 to i32
store i32 %19, i32* %5
store i32 0, i32* %6
%20 = load i32, i32* %5
%21 = sitofp i32 %20 to double
store double %21, double* %7
%22 = load double, double* %2
%23 = load double, double* %7
%24 = fsub double %22, %23
store double %24, double* %8
%25 = load double, double* %7
store double %25, double* %9
%26 = load double, double* %8
%27 = call double @exp(double %26)
store double %27, double* %10
store double 1.000000e+00, double* %11
%28 = load double, double* %10
%29 = fsub double %28, 1.000000e+00
%30 = load double, double* %9
%31 = fdiv double %29, %30
store double %31, double* %12
%32 = call double @exp(double 1.000000e+02)
store double %32, double* %13
store double 1.000000e+00, double* %14
store double 1.000000e+00, double* %15
br label %33
33: ; preds = %40, %1
%34 = load double, double* %13
%35 = load double, double* %4
%36 = load double, double* %12
%37 = call double @llvm.fabs.f64(double %36)
%38 = fmul double %35, %37
%39 = fcmp ogt double %34, %38
br i1 %39, label %40, label %69
40: ; preds = %33
%41 = load i32, i32* %6
%42 = add nsw i32 %41, 1
store i32 %42, i32* %6
%43 = load i32, i32* %6
%44 = sitofp i32 %43 to double
%45 = load double, double* %14
%46 = fmul double %45, %44
store double %46, double* %14
%47 = load double, double* %7
%48 = load double, double* %9
%49 = fmul double %48, %47
store double %49, double* %9
%50 = load double, double* %8
%51 = fneg double %50
%52 = load double, double* %15
%53 = fmul double %52, %51
store double %53, double* %15
%54 = load double, double* %15
%55 = load double, double* %14
%56 = fdiv double %54, %55
%57 = load double, double* %11
%58 = fadd double %57, %56
store double %58, double* %11
%59 = load double, double* %14
%60 = load double, double* %10
%61 = load double, double* %11
%62 = call double @llvm.fmuladd.f64(double %60, double %61, double -1.000000e+00)
%63 = fmul double %59, %62
%64 = load double, double* %9
%65 = fdiv double %63, %64
store double %65, double* %13
%66 = load double, double* %13
%67 = load double, double* %12
%68 = fadd double %67, %66
store double %68, double* %12
br label %33
69: ; preds = %33
%70 = load i32, i32* %5
%71 = sub nsw i32 %70, 7
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds [44 x double], [44 x double]* %3, i64 0, i64 %72
%74 = load double, double* %73
%75 = load double, double* %12
%76 = load double, double* %7
%77 = call double @exp(double %76)
%78 = call double @llvm.fmuladd.f64(double %75, double %77, double %74)
ret double %78
}

LLVM IR (-O2):
@__const.Ei3.ei = [44 x double] [double 0x4067F026DB7EDB47, double 0x407B86141188DE56, double 0x409037835EA4491F, double 0x40A378753C5FBCDA, double 0x40B7B7680822077A, double 0x40CD37C42E699A88, double 0x40E229B6081DA020, double 0x40F6C08837D83FB6, double 0x410CAE5ED1E6AE10, double 0x41222CD1FF51C8B1, double 0x4137245DE4DFF86B, double 0x414D96082A51045C, double 0x4162FAD768089365, double 0x41786DD24A9FF9CD, double 0x418F882A92D8087A, double 0x41A466EBBE99C944, double 0x41BA7663A1D48CA8, double 0x41D13299CFF65903, double 0x41E665657750D14B, double 0x41FD379C83FE5EF9, double 0x421316BEE77F85F4, double 0x4228FAFF1900A120, double 0x42405E2EBC373415, double 0x42557A2117CFD18C, double 0x426C3701C4740C9B, double 0x42828DD38708AE4C, double 0x42986D7EF8CC31FE, double 0x42B018A53920D445, double 0x42C53B7ED3EF4ACC, double 0x42DC0824C1D0EA71, double 0x42F284FF7B1DE5A6, double 0x43087D3F5E531D15, double 0x4320341B8365929D, double 0x433575177DA55F6A, double 0x434C6EFB361D1C79, double 0x4362D9C642050CF7, double 0x4379028C7BCE0876, double 0x439099AD7375CF32, double 0x43A60C7DE8BEBD19, double 0x43BD4CFEB752940B, double 0x43D37A86C651287F, double 0x43E9E90CF4DFFD1B, double 0x44013DA0C9504871, double 0x4416F4357AE9D01B]
define double @Ei3(double %0) {
%2 = fadd double %0, 5.000000e-01
%3 = fptosi double %2 to i32
%4 = sitofp i32 %3 to double
%5 = fsub double %0, %4
%6 = tail call double @exp(double %5)
%7 = fadd double %6, -1.000000e+00
%8 = fdiv double %7, %4
%9 = tail call double @llvm.fabs.f64(double %8)
%10 = fmul double %9, 1.000000e-10
%11 = fcmp olt double %10, 0x48F3494A9B171BF5
br i1 %11, label %12, label %35
12: ; preds = %1
%13 = fneg double %5
br label %14
14: ; preds = %12, %14
%15 = phi double [ 1.000000e+00, %12 ], [ %25, %14 ]
%16 = phi double [ 1.000000e+00, %12 ], [ %23, %14 ]
%17 = phi double [ %8, %12 ], [ %31, %14 ]
%18 = phi double [ 1.000000e+00, %12 ], [ %27, %14 ]
%19 = phi i32 [ 0, %12 ], [ %21, %14 ]
%20 = phi double [ %4, %12 ], [ %24, %14 ]
%21 = add nuw nsw i32 %19, 1
%22 = sitofp i32 %21 to double
%23 = fmul double %16, %22
%24 = fmul double %20, %4
%25 = fmul double %15, %13
%26 = fdiv double %25, %23
%27 = fadd double %18, %26
%28 = tail call double @llvm.fmuladd.f64(double %6, double %27, double -1.000000e+00)
%29 = fmul double %23, %28
%30 = fdiv double %29, %24
%31 = fadd double %17, %30
%32 = tail call double @llvm.fabs.f64(double %31)
%33 = fmul double %32, 1.000000e-10
%34 = fcmp ogt double %30, %33
br i1 %34, label %14, label %35
35: ; preds = %14, %1
%36 = phi double [ %8, %1 ], [ %31, %14 ]
%37 = add nsw i32 %3, -7
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds [44 x double], [44 x double]* @__const.Ei3.ei, i64 0, i64 %38
%40 = load double, double* %39
%41 = tail call double @exp(double %4)
%42 = tail call double @llvm.fmuladd.f64(double %36, double %41, double %40)
ret double %42
}