#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 /*<<< orphan*/ ERANGE;
double HUGE_VAL;
int /*<<< orphan*/ errno;
int floor(double);
double ldexp(double, int);
double exp(double arg) {
  double fraction;
  double temp1, temp2, xsq;
  int ent;
  if (arg == 0.0) {
    return 1.0;
  }
  if (arg < -10000) {
    return 0.0;
  }
  if (arg > 10000) {
    errno = ERANGE;
    return HUGE_VAL;
  }
  arg *= 1.44269504088896;
  ent = floor(arg);
  fraction = arg - ent - 0.5;
  xsq = fraction * fraction;
  temp1 = ((0.60614853300611e2 * xsq + 0.30286971697440e5) * xsq +
           0.20803843466947e7) *
          fraction;
  temp2 = ((1.0 * xsq + 0.17492876890931e4) * xsq + 0.32772515180829e6) * xsq +
          0.60027203602388e7;
  return ldexp(1.41421356237310 * (temp2 + temp1) / (temp2 - temp1), ent);
}


x86 assembly (clang, -O0):
<exp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1157 <exp+0x37>
jp     1157 <exp+0x37>
movsd  0xf0b(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12af <exp+0x18f>
movsd  0xea1(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1177 <exp+0x57>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12af <exp+0x18f>
movsd  -0x10(%rbp),%xmm0
movsd  0xe84(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11b5 <exp+0x95>
mov    0x2e4b(%rip),%rax
mov    (%rax),%ecx
mov    0x2e32(%rip),%rax
mov    %ecx,(%rax)
mov    0x2e41(%rip),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12af <exp+0x18f>
movsd  0xe93(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1040 <floor@plt>
mov    %eax,-0x34(%rbp)
movsd  -0x10(%rbp),%xmm0
cvtsi2sdl -0x34(%rbp),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe5e(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  0xe29(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe25(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe00(%rip),%xmm1
addsd  %xmm1,%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  0xddd(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xdc0(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xda3(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm1
addsd  -0x20(%rbp),%xmm1
movsd  0xd80(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  -0x28(%rbp),%xmm1
subsd  -0x20(%rbp),%xmm1
divsd  %xmm1,%xmm0
mov    -0x34(%rbp),%edi
call   1030 <ldexp@plt>
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<exp>:
push   %rax
movapd %xmm0,%xmm2
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm2
jne    113b <exp+0x1b>
jp     113b <exp+0x1b>
movsd  0xec7(%rip),%xmm0
pop    %rax
ret
movsd  0xec5(%rip),%xmm1
ucomisd %xmm2,%xmm1
ja     1170 <exp+0x50>
ucomisd 0xebf(%rip),%xmm2
jbe    1172 <exp+0x52>
mov    0x2e86(%rip),%rax
mov    (%rax),%eax
mov    0x2e6d(%rip),%rcx
mov    %eax,(%rcx)
mov    0x2e7c(%rip),%rax
movsd  (%rax),%xmm0
pop    %rax
ret
mulsd  0xe9e(%rip),%xmm2
movsd  %xmm2,(%rsp)
movapd %xmm2,%xmm0
call   1040 <floor@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movsd  (%rsp),%xmm1
subsd  %xmm0,%xmm1
addsd  0xe80(%rip),%xmm1
movapd %xmm1,%xmm0
movapd %xmm1,%xmm2
mulsd  %xmm0,%xmm0
movsd  0xe74(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xe70(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0xe6c(%rip),%xmm1
mulsd  %xmm2,%xmm1
movsd  0xe68(%rip),%xmm2
addsd  %xmm0,%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe60(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe5c(%rip),%xmm2
movapd %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  0xe54(%rip),%xmm0
subsd  %xmm1,%xmm2
divsd  %xmm2,%xmm0
mov    %eax,%edi
pop    %rax
jmp    1030 <ldexp@plt>

LLVM IR (-O0):
@ERANGE = global i32 0
@errno = global i32 0
@HUGE_VAL = global double 0.000000e+00
define double @exp(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca i32
store double %0, double* %3
%9 = load double, double* %3
%10 = fcmp oeq double %9, 0.000000e+00
br i1 %10, label %11, label %12
11: ; preds = %1
store double 1.000000e+00, double* %2
br label %57
12: ; preds = %1
%13 = load double, double* %3
%14 = fcmp olt double %13, -1.000000e+04
br i1 %14, label %15, label %16
15: ; preds = %12
store double 0.000000e+00, double* %2
br label %57
16: ; preds = %12
%17 = load double, double* %3
%18 = fcmp ogt double %17, 1.000000e+04
br i1 %18, label %19, label %22
19: ; preds = %16
%20 = load i32, i32* @ERANGE
store i32 %20, i32* @errno
%21 = load double, double* @HUGE_VAL
store double %21, double* %2
br label %57
22: ; preds = %16
%23 = load double, double* %3
%24 = fmul double %23, 0x3FF71547652B82EF
store double %24, double* %3
%25 = load double, double* %3
%26 = call i32 @floor(double %25)
store i32 %26, i32* %8
%27 = load double, double* %3
%28 = load i32, i32* %8
%29 = sitofp i32 %28 to double
%30 = fsub double %27, %29
%31 = fsub double %30, 5.000000e-01
store double %31, double* %4
%32 = load double, double* %4
%33 = load double, double* %4
%34 = fmul double %32, %33
store double %34, double* %7
%35 = load double, double* %7
%36 = call double @llvm.fmuladd.f64(double 0x404E4EB38350FB20, double %35, double 0x40DD93BE304A759A)
%37 = load double, double* %7
%38 = call double @llvm.fmuladd.f64(double %36, double %37, double 0x413FBE8058C0FBDE)
%39 = load double, double* %4
%40 = fmul double %38, %39
store double %40, double* %5
%41 = load double, double* %7
%42 = call double @llvm.fmuladd.f64(double 1.000000e+00, double %41, double 0x409B552697F8391F)
%43 = load double, double* %7
%44 = call double @llvm.fmuladd.f64(double %42, double %43, double 0x411400B49B73A1E3)
%45 = load double, double* %7
%46 = call double @llvm.fmuladd.f64(double %44, double %45, double 0x4156E608170E270A)
store double %46, double* %6
%47 = load double, double* %6
%48 = load double, double* %5
%49 = fadd double %47, %48
%50 = fmul double 0x3FF6A09E667F3BE3, %49
%51 = load double, double* %6
%52 = load double, double* %5
%53 = fsub double %51, %52
%54 = fdiv double %50, %53
%55 = load i32, i32* %8
%56 = call double @ldexp(double %54, i32 %55)
store double %56, double* %2
br label %57
57: ; preds = %22, %19, %15, %11
%58 = load double, double* %2
ret double %58
}

LLVM IR (-O2):
@ERANGE = global i32 0
@errno = global i32 0
@HUGE_VAL = global double 0.000000e+00
define double @exp(double %0) {
%2 = fcmp oeq double %0, 0.000000e+00
br i1 %2, label %28, label %3
3: ; preds = %1
%4 = fcmp olt double %0, -1.000000e+04
br i1 %4, label %28, label %5
5: ; preds = %3
%6 = fcmp ogt double %0, 1.000000e+04
br i1 %6, label %7, label %10
7: ; preds = %5
%8 = load i32, i32* @ERANGE
store i32 %8, i32* @errno
%9 = load double, double* @HUGE_VAL
br label %28
10: ; preds = %5
%11 = fmul double %0, 0x3FF71547652B82EF
%12 = tail call i32 @floor(double %11)
%13 = sitofp i32 %12 to double
%14 = fsub double %11, %13
%15 = fadd double %14, -5.000000e-01
%16 = fmul double %15, %15
%17 = tail call double @llvm.fmuladd.f64(double %16, double 0x404E4EB38350FB20, double 0x40DD93BE304A759A)
%18 = tail call double @llvm.fmuladd.f64(double %17, double %16, double 0x413FBE8058C0FBDE)
%19 = fmul double %15, %18
%20 = fadd double %16, 0x409B552697F8391F
%21 = tail call double @llvm.fmuladd.f64(double %20, double %16, double 0x411400B49B73A1E3)
%22 = tail call double @llvm.fmuladd.f64(double %21, double %16, double 0x4156E608170E270A)
%23 = fadd double %22, %19
%24 = fmul double %23, 0x3FF6A09E667F3BE3
%25 = fsub double %22, %19
%26 = fdiv double %24, %25
%27 = tail call double @ldexp(double %26, i32 %12)
br label %28
28: ; preds = %3, %1, %10, %7
%29 = phi double [ %9, %7 ], [ %27, %10 ], [ 1.000000e+00, %1 ], [ 0.000000e+00, %3 ]
ret double %29
}