#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 */
long double sdtools_abs(long double);
double sdtools_exp(double x) {
  long double fact = 1.0;
  long double xpowi = 1.0;
  long double term;
  long double sum = 1.0;
  long double iterdiff = 0.0;
  long double lastterm = x + 2 * 0.000000000001;
  int n;
  n = 1;
  do {
    xpowi *= x;
    fact *= n;
    term = xpowi / fact;
    if (n > 10 && iterdiff < sdtools_abs(lastterm - term))
      return 0.0;
    iterdiff = sdtools_abs(lastterm - term);
    sum += term;
    lastterm = term;
    n++;
  } while (n < 255 && iterdiff >= 0.000000000001);
  return (double)sum;
}


x86 assembly (clang, -O0):
<sdtools_exp>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
movsd  %xmm0,-0x10(%rbp)
fld1
fld    %st(0)
fstpt  -0x20(%rbp)
fld    %st(0)
fstpt  -0x30(%rbp)
fstpt  -0x50(%rbp)
fldz
fstpt  -0x60(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  0xebf(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x80(%rbp)
fldl   -0x80(%rbp)
fstpt  -0x70(%rbp)
movl   $0x1,-0x74(%rbp)
fldl   -0x10(%rbp)
fldt   -0x30(%rbp)
fmulp  %st,%st(1)
fstpt  -0x30(%rbp)
mov    -0x74(%rbp),%eax
mov    %eax,-0x84(%rbp)
fildl  -0x84(%rbp)
fldt   -0x20(%rbp)
fmulp  %st,%st(1)
fstpt  -0x20(%rbp)
fldt   -0x30(%rbp)
fldt   -0x20(%rbp)
fdivrp %st,%st(1)
fstpt  -0x40(%rbp)
cmpl   $0xa,-0x74(%rbp)
jle    11d1 <sdtools_exp+0xc1>
fldt   -0x60(%rbp)
fstpt  -0x9c(%rbp)
fldt   -0x70(%rbp)
fldt   -0x40(%rbp)
fsubrp %st,%st(1)
mov    %rsp,%rax
fstpt  (%rax)
call   1030 <sdtools_abs@plt>
fldt   -0x9c(%rbp)
fld    %st(1)
fstp   %st(0)
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
jbe    11d1 <sdtools_exp+0xc1>
jmp    11c4 <sdtools_exp+0xb4>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1251 <sdtools_exp+0x141>
fldt   -0x70(%rbp)
fldt   -0x40(%rbp)
fsubrp %st,%st(1)
mov    %rsp,%rax
fstpt  (%rax)
call   1030 <sdtools_abs@plt>
fstpt  -0x60(%rbp)
fldt   -0x40(%rbp)
fldt   -0x50(%rbp)
faddp  %st,%st(1)
fstpt  -0x50(%rbp)
fldt   -0x40(%rbp)
fstpt  -0x70(%rbp)
mov    -0x74(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x74(%rbp)
xor    %eax,%eax
cmpl   $0xff,-0x74(%rbp)
mov    %al,-0x9d(%rbp)
jge    122d <sdtools_exp+0x11d>
fldt   -0x60(%rbp)
fldl   0xdea(%rip)
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
setae  %al
mov    %al,-0x9d(%rbp)
mov    -0x9d(%rbp),%al
test   $0x1,%al
jne    1157 <sdtools_exp+0x47>
fldt   -0x50(%rbp)
fstpl  -0x90(%rbp)
movsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sdtools_exp>:
push   %rbx
sub    $0x90,%rsp
movsd  0xee0(%rip),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x28(%rsp)
fldl   0x28(%rsp)
movsd  %xmm0,0x30(%rsp)
mov    $0x1,%ebx
fldz
fld1
fldl   0x30(%rsp)
fstpt  0x54(%rsp)
fld    %st(0)
fld    %st(1)
nopl   0x0(%rax)
fxch   %st(1)
fstpt  0x78(%rsp)
fld    %st(3)
fstp   %st(0)
mov    %ebx,0x1c(%rsp)
fimull 0x1c(%rsp)
fldt   0x54(%rsp)
fmulp  %st,%st(2)
fld    %st(1)
fstpt  0x84(%rsp)
fld    %st(0)
fstpt  0x6c(%rsp)
fdivrp %st,%st(1)
fld    %st(0)
fstpt  0x60(%rsp)
fsubrp %st,%st(2)
cmp    $0xb,%ebx
jb     11aa <sdtools_exp+0x9a>
fld    %st(1)
fstpt  (%rsp)
fstpt  0x3c(%rsp)
fstpt  0x48(%rsp)
call   1030 <sdtools_abs@plt>
fldt   0x3c(%rsp)
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
fldt   0x48(%rsp)
fldz
ja     1204 <sdtools_exp+0xf4>
fstp   %st(0)
fstpt  (%rsp)
call   1030 <sdtools_abs@plt>
fldt   0x78(%rsp)
fldt   0x60(%rsp)
fadd   %st,%st(1)
cmp    $0xfd,%ebx
fldt   0x84(%rsp)
fldt   0x6c(%rsp)
fxch   %st(2)
fxch   %st(4)
fxch   %st(3)
fxch   %st(1)
fxch   %st(2)
ja     11f0 <sdtools_exp+0xe0>
add    $0x1,%ebx
fldl   0xe24(%rip)
fxch   %st(4)
fucomi %st(4),%st
fstp   %st(4)
jae    1150 <sdtools_exp+0x40>
fstp   %st(2)
fstp   %st(1)
fstp   %st(2)
fstp   %st(0)
fstpl  0x20(%rsp)
movsd  0x20(%rsp),%xmm0
jmp    120c <sdtools_exp+0xfc>
fstp   %st(1)
fstp   %st(0)
xorpd  %xmm0,%xmm0
add    $0x90,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define double @sdtools_exp(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca x86_fp80
%5 = alloca x86_fp80
%6 = alloca x86_fp80
%7 = alloca x86_fp80
%8 = alloca x86_fp80
%9 = alloca x86_fp80
%10 = alloca i32
store double %0, double* %3
store x86_fp80 0xK3FFF8000000000000000, x86_fp80* %4
store x86_fp80 0xK3FFF8000000000000000, x86_fp80* %5
store x86_fp80 0xK3FFF8000000000000000, x86_fp80* %7
store x86_fp80 0xK00000000000000000000, x86_fp80* %8
%11 = load double, double* %3
%12 = fadd double %11, 2.000000e-12
%13 = fpext double %12 to x86_fp80
store x86_fp80 %13, x86_fp80* %9
store i32 1, i32* %10
br label %14
14: ; preds = %53, %1
%15 = load double, double* %3
%16 = fpext double %15 to x86_fp80
%17 = load x86_fp80, x86_fp80* %5
%18 = fmul x86_fp80 %17, %16
store x86_fp80 %18, x86_fp80* %5
%19 = load i32, i32* %10
%20 = sitofp i32 %19 to x86_fp80
%21 = load x86_fp80, x86_fp80* %4
%22 = fmul x86_fp80 %21, %20
store x86_fp80 %22, x86_fp80* %4
%23 = load x86_fp80, x86_fp80* %5
%24 = load x86_fp80, x86_fp80* %4
%25 = fdiv x86_fp80 %23, %24
store x86_fp80 %25, x86_fp80* %6
%26 = load i32, i32* %10
%27 = icmp sgt i32 %26, 10
br i1 %27, label %28, label %36
28: ; preds = %14
%29 = load x86_fp80, x86_fp80* %8
%30 = load x86_fp80, x86_fp80* %9
%31 = load x86_fp80, x86_fp80* %6
%32 = fsub x86_fp80 %30, %31
%33 = call x86_fp80 @sdtools_abs(x86_fp80 %32)
%34 = fcmp olt x86_fp80 %29, %33
br i1 %34, label %35, label %36
35: ; preds = %28
store double 0.000000e+00, double* %2
br label %58
36: ; preds = %28, %14
%37 = load x86_fp80, x86_fp80* %9
%38 = load x86_fp80, x86_fp80* %6
%39 = fsub x86_fp80 %37, %38
%40 = call x86_fp80 @sdtools_abs(x86_fp80 %39)
store x86_fp80 %40, x86_fp80* %8
%41 = load x86_fp80, x86_fp80* %6
%42 = load x86_fp80, x86_fp80* %7
%43 = fadd x86_fp80 %42, %41
store x86_fp80 %43, x86_fp80* %7
%44 = load x86_fp80, x86_fp80* %6
store x86_fp80 %44, x86_fp80* %9
%45 = load i32, i32* %10
%46 = add nsw i32 %45, 1
store i32 %46, i32* %10
br label %47
47: ; preds = %36
%48 = load i32, i32* %10
%49 = icmp slt i32 %48, 255
br i1 %49, label %50, label %53
50: ; preds = %47
%51 = load x86_fp80, x86_fp80* %8
%52 = fcmp oge x86_fp80 %51, 0xK3FD78CBCCC096F508800
br label %53
53: ; preds = %50, %47
%54 = phi i1 [ false, %47 ], [ %52, %50 ]
br i1 %54, label %14, label %55
55: ; preds = %53
%56 = load x86_fp80, x86_fp80* %7
%57 = fptrunc x86_fp80 %56 to double
store double %57, double* %2
br label %58
58: ; preds = %55, %35
%59 = load double, double* %2
ret double %59
}

LLVM IR (-O2):
define double @sdtools_exp(double %0) {
%2 = fadd double %0, 2.000000e-12
%3 = fpext double %2 to x86_fp80
%4 = fpext double %0 to x86_fp80
br label %5
5: ; preds = %21, %1
%6 = phi x86_fp80 [ 0xK3FFF8000000000000000, %1 ], [ %12, %21 ]
%7 = phi x86_fp80 [ 0xK3FFF8000000000000000, %1 ], [ %23, %21 ]
%8 = phi x86_fp80 [ 0xK3FFF8000000000000000, %1 ], [ %14, %21 ]
%9 = phi x86_fp80 [ 0xK00000000000000000000, %1 ], [ %22, %21 ]
%10 = phi x86_fp80 [ %3, %1 ], [ %15, %21 ]
%11 = phi i32 [ 1, %1 ], [ %24, %21 ]
%12 = fmul x86_fp80 %6, %4
%13 = sitofp i32 %11 to x86_fp80
%14 = fmul x86_fp80 %8, %13
%15 = fdiv x86_fp80 %12, %14
%16 = icmp ugt i32 %11, 10
%17 = fsub x86_fp80 %10, %15
br i1 %16, label %18, label %21
18: ; preds = %5
%19 = tail call x86_fp80 @sdtools_abs(x86_fp80 %17)
%20 = fcmp olt x86_fp80 %9, %19
br i1 %20, label %30, label %21
21: ; preds = %5, %18
%22 = tail call x86_fp80 @sdtools_abs(x86_fp80 %17)
%23 = fadd x86_fp80 %7, %15
%24 = add nuw nsw i32 %11, 1
%25 = icmp ult i32 %11, 254
%26 = fcmp oge x86_fp80 %22, 0xK3FD78CBCCC096F508800
%27 = select i1 %25, i1 %26, i1 false
br i1 %27, label %5, label %28
28: ; preds = %21
%29 = fptrunc x86_fp80 %23 to double
br label %30
30: ; preds = %18, %28
%31 = phi double [ %29, %28 ], [ 0.000000e+00, %18 ]
ret double %31
}