double exp(double x) {
  double y = x, ex_p1 = 0, ex_p2 = 0, ex_p3 = 0, ex_px = 0, ex_tmp = 1,
         dex_px = 1, tmp;
  int l;
  if (x == 0)
    return 1;
  if (x < 0)
    return 1 / exp(-x);
  for (l = 1, tmp = 1;
       ((ex_px - ex_tmp) > 1e-10 || (ex_px - ex_tmp) < -1e-10) &&
       dex_px > 1e-10;
       l++) {
    ex_tmp = ex_px;
    tmp *= y;
    tmp = tmp / l;
    ex_p1 += tmp;
    ex_p2 = ex_p1 + tmp * y / (l + 1);
    ex_p3 = ex_p2 + tmp * y * y / (l + 1) / (l + 2);
    dex_px = ex_p3 - ex_p2;
    ex_px = ex_p3 - dex_px * dex_px / (ex_p3 - 2 * ex_p2 + ex_p1);
  }
  return ex_px + 1;
}


x86 assembly (clang, -O0):
<exp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0xeb1(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xea4(%rip),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    118b <exp+0x7b>
jp     118b <exp+0x7b>
movsd  0xe7f(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1347 <exp+0x237>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    11d3 <exp+0xc3>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1030 <exp@plt>
movaps %xmm0,%xmm1
movsd  0xe3b(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1347 <exp+0x237>
movl   $0x1,-0x54(%rbp)
movsd  0xe1e(%rip),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  0xe0f(%rip),%xmm1
ucomisd %xmm1,%xmm0
ja     1224 <exp+0x114>
movsd  -0x38(%rbp),%xmm1
subsd  -0x40(%rbp),%xmm1
xor    %eax,%eax
movsd  0xdf9(%rip),%xmm0
ucomisd %xmm1,%xmm0
mov    %al,-0x55(%rbp)
jbe    123b <exp+0x12b>
movsd  -0x48(%rbp),%xmm0
movsd  0xdd7(%rip),%xmm1
ucomisd %xmm1,%xmm0
seta   %al
mov    %al,-0x55(%rbp)
mov    -0x55(%rbp),%al
test   $0x1,%al
jne    124b <exp+0x13b>
jmp    1335 <exp+0x225>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x18(%rbp),%xmm0
mulsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
cvtsi2sdl -0x54(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
mov    -0x54(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %eax,%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
mov    -0x54(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %eax,%xmm2
divsd  %xmm2,%xmm1
mov    -0x54(%rbp),%eax
add    $0x2,%eax
cvtsi2sd %eax,%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
mulsd  -0x48(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm3
addsd  %xmm3,%xmm3
subsd  %xmm3,%xmm2
addsd  -0x20(%rbp),%xmm2
divsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x54(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
jmp    11e7 <exp+0xd7>
movsd  0xcc3(%rip),%xmm0
addsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<exp>:
push   %rax
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    112b <exp+0x1b>
jp     112b <exp+0x1b>
movsd  0xeda(%rip),%xmm10
jmp    123e <exp+0x12e>
ucomisd %xmm0,%xmm1
jbe    1151 <exp+0x41>
xorpd  0xee7(%rip),%xmm0
call   1030 <exp@plt>
movsd  0xeb9(%rip),%xmm10
divsd  %xmm0,%xmm10
jmp    123e <exp+0x12e>
mov    $0x1,%eax
movsd  0xea1(%rip),%xmm10
xorpd  %xmm2,%xmm2
movsd  0xe9c(%rip),%xmm9
movsd  0xe9b(%rip),%xmm8
xorpd  %xmm4,%xmm4
movapd %xmm10,%xmm7
movapd %xmm10,%xmm5
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movapd %xmm10,%xmm1
movapd %xmm4,%xmm10
movapd %xmm4,%xmm6
subsd  %xmm1,%xmm6
ucomisd %xmm9,%xmm6
ja     11b4 <exp+0xa4>
ucomisd %xmm6,%xmm8
jbe    1235 <exp+0x125>
ucomisd %xmm9,%xmm7
jbe    1235 <exp+0x125>
mulsd  %xmm0,%xmm5
xorps  %xmm1,%xmm1
cvtsi2sd %eax,%xmm1
divsd  %xmm1,%xmm5
addsd  %xmm5,%xmm2
movapd %xmm5,%xmm4
mulsd  %xmm0,%xmm4
lea    0x1(%rax),%ecx
xorps  %xmm1,%xmm1
cvtsi2sd %ecx,%xmm1
movapd %xmm4,%xmm3
divsd  %xmm1,%xmm3
addsd  %xmm2,%xmm3
mulsd  %xmm0,%xmm4
divsd  %xmm1,%xmm4
add    $0x2,%eax
xorps  %xmm1,%xmm1
cvtsi2sd %eax,%xmm1
divsd  %xmm1,%xmm4
addsd  %xmm3,%xmm4
movapd %xmm4,%xmm7
subsd  %xmm3,%xmm7
movapd %xmm7,%xmm1
mulsd  %xmm7,%xmm1
addsd  %xmm3,%xmm3
movapd %xmm4,%xmm6
subsd  %xmm3,%xmm6
addsd  %xmm2,%xmm6
divsd  %xmm6,%xmm1
subsd  %xmm1,%xmm4
mov    %ecx,%eax
jmp    1190 <exp+0x80>
addsd  0xdc2(%rip),%xmm10
movapd %xmm10,%xmm0
pop    %rax
ret

LLVM IR (-O0):
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 double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca i32
store double %0, double* %3
%13 = load double, double* %3
store double %13, double* %4
store double 0.000000e+00, double* %5
store double 0.000000e+00, double* %6
store double 0.000000e+00, double* %7
store double 0.000000e+00, double* %8
store double 1.000000e+00, double* %9
store double 1.000000e+00, double* %10
%14 = load double, double* %3
%15 = fcmp oeq double %14, 0.000000e+00
br i1 %15, label %16, label %17
16: ; preds = %1
store double 1.000000e+00, double* %2
br label %97
17: ; preds = %1
%18 = load double, double* %3
%19 = fcmp olt double %18, 0.000000e+00
br i1 %19, label %20, label %25
20: ; preds = %17
%21 = load double, double* %3
%22 = fneg double %21
%23 = call double @exp(double %22)
%24 = fdiv double 1.000000e+00, %23
store double %24, double* %2
br label %97
25: ; preds = %17
store i32 1, i32* %12
store double 1.000000e+00, double* %11
br label %26
26: ; preds = %91, %25
%27 = load double, double* %8
%28 = load double, double* %9
%29 = fsub double %27, %28
%30 = fcmp ogt double %29, 1.000000e-10
br i1 %30, label %36, label %31
31: ; preds = %26
%32 = load double, double* %8
%33 = load double, double* %9
%34 = fsub double %32, %33
%35 = fcmp olt double %34, -1.000000e-10
br i1 %35, label %36, label %39
36: ; preds = %31, %26
%37 = load double, double* %10
%38 = fcmp ogt double %37, 1.000000e-10
br label %39
39: ; preds = %36, %31
%40 = phi i1 [ false, %31 ], [ %38, %36 ]
br i1 %40, label %41, label %94
41: ; preds = %39
%42 = load double, double* %8
store double %42, double* %9
%43 = load double, double* %4
%44 = load double, double* %11
%45 = fmul double %44, %43
store double %45, double* %11
%46 = load double, double* %11
%47 = load i32, i32* %12
%48 = sitofp i32 %47 to double
%49 = fdiv double %46, %48
store double %49, double* %11
%50 = load double, double* %11
%51 = load double, double* %5
%52 = fadd double %51, %50
store double %52, double* %5
%53 = load double, double* %5
%54 = load double, double* %11
%55 = load double, double* %4
%56 = fmul double %54, %55
%57 = load i32, i32* %12
%58 = add nsw i32 %57, 1
%59 = sitofp i32 %58 to double
%60 = fdiv double %56, %59
%61 = fadd double %53, %60
store double %61, double* %6
%62 = load double, double* %6
%63 = load double, double* %11
%64 = load double, double* %4
%65 = fmul double %63, %64
%66 = load double, double* %4
%67 = fmul double %65, %66
%68 = load i32, i32* %12
%69 = add nsw i32 %68, 1
%70 = sitofp i32 %69 to double
%71 = fdiv double %67, %70
%72 = load i32, i32* %12
%73 = add nsw i32 %72, 2
%74 = sitofp i32 %73 to double
%75 = fdiv double %71, %74
%76 = fadd double %62, %75
store double %76, double* %7
%77 = load double, double* %7
%78 = load double, double* %6
%79 = fsub double %77, %78
store double %79, double* %10
%80 = load double, double* %7
%81 = load double, double* %10
%82 = load double, double* %10
%83 = fmul double %81, %82
%84 = load double, double* %7
%85 = load double, double* %6
%86 = call double @llvm.fmuladd.f64(double -2.000000e+00, double %85, double %84)
%87 = load double, double* %5
%88 = fadd double %86, %87
%89 = fdiv double %83, %88
%90 = fsub double %80, %89
store double %90, double* %8
br label %91
91: ; preds = %41
%92 = load i32, i32* %12
%93 = add nsw i32 %92, 1
store i32 %93, i32* %12
br label %26
94: ; preds = %39
%95 = load double, double* %8
%96 = fadd double %95, 1.000000e+00
store double %96, double* %2
br label %97
97: ; preds = %94, %20, %16
%98 = load double, double* %2
ret double %98
}

LLVM IR (-O2):
define double @exp(double %0) {
%2 = fcmp oeq double %0, 0.000000e+00
br i1 %2, label %5, label %3
3: ; preds = %1
%4 = fcmp olt double %0, 0.000000e+00
br i1 %4, label %7, label %11
5: ; preds = %48, %1, %7
%6 = phi double [ %10, %7 ], [ %49, %48 ], [ 1.000000e+00, %1 ]
ret double %6
7: ; preds = %3
%8 = fneg double %0
%9 = tail call double @exp(double %8)
%10 = fdiv double 1.000000e+00, %9
br label %5
11: ; preds = %3, %26
%12 = phi double [ %30, %26 ], [ 0.000000e+00, %3 ]
%13 = phi double [ %47, %26 ], [ 0.000000e+00, %3 ]
%14 = phi double [ %13, %26 ], [ 1.000000e+00, %3 ]
%15 = phi double [ %42, %26 ], [ 1.000000e+00, %3 ]
%16 = phi double [ %29, %26 ], [ 1.000000e+00, %3 ]
%17 = phi i32 [ %32, %26 ], [ 1, %3 ]
%18 = fsub double %13, %14
%19 = fcmp ogt double %18, 1.000000e-10
br i1 %19, label %24, label %20
20: ; preds = %11
%21 = fcmp olt double %18, -1.000000e-10
%22 = fcmp ogt double %15, 1.000000e-10
%23 = select i1 %21, i1 %22, i1 false
br i1 %23, label %26, label %48
24: ; preds = %11
%25 = fcmp ogt double %15, 1.000000e-10
br i1 %25, label %26, label %48
26: ; preds = %20, %24
%27 = fmul double %16, %0
%28 = sitofp i32 %17 to double
%29 = fdiv double %27, %28
%30 = fadd double %12, %29
%31 = fmul double %29, %0
%32 = add nuw nsw i32 %17, 1
%33 = sitofp i32 %32 to double
%34 = fdiv double %31, %33
%35 = fadd double %30, %34
%36 = fmul double %31, %0
%37 = fdiv double %36, %33
%38 = add nuw nsw i32 %17, 2
%39 = sitofp i32 %38 to double
%40 = fdiv double %37, %39
%41 = fadd double %35, %40
%42 = fsub double %41, %35
%43 = fmul double %42, %42
%44 = tail call double @llvm.fmuladd.f64(double %35, double -2.000000e+00, double %41)
%45 = fadd double %30, %44
%46 = fdiv double %43, %45
%47 = fsub double %41, %46
br label %11
48: ; preds = %20, %24
%49 = fadd double %13, 1.000000e+00
br label %5
}