double exp(x)
double x;
{
  int exp;
  char sign;
  static double coeff[] = {
      1.0000000000e+00, 6.9314718056e-01, 2.4022650695e-01, 5.5504108945e-02,
      9.6181261779e-03, 1.3333710529e-03, 1.5399104432e-04, 1.5327675257e-05,
      1.2485143336e-06, 1.3908092221e-07,
  };
  if (x == 0.0)
    return 1.0;
  sign = x < 0.0;
  if (sign)
    x = -x;
  x *= 1.4426950409;
  exp = (int)floor(x);
  x -= (double)exp;
  x = ldexp(eval_poly(x, coeff, sizeof coeff / sizeof coeff[0] - 1), exp);
  if (sign)
    return 1.0 / x;
  return x;
}


x86 assembly (clang, -O0):
<exp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1167 <exp+0x37>
jp     1167 <exp+0x37>
movsd  0xeab(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    122f <exp+0xff>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%eax
mov    %al,-0x15(%rbp)
cmpb   $0x0,-0x15(%rbp)
je     11a5 <exp+0x75>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xe53(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1050 <floor@plt>
cvttsd2si %xmm0,%eax
mov    %eax,-0x14(%rbp)
cvtsi2sdl -0x14(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
lea    0x2e59(%rip),%rdi
mov    $0x9,%esi
mov    $0x1,%al
call   1040 <eval_poly@plt>
cvtsi2sd %eax,%xmm0
mov    -0x14(%rbp),%edi
call   1030 <ldexp@plt>
movsd  %xmm0,-0x10(%rbp)
cmpb   $0x0,-0x15(%rbp)
je     1225 <exp+0xf5>
movsd  0xdf2(%rip),%xmm0
divsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    122f <exp+0xff>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<exp>:
push   %rbx
sub    $0x20,%rsp
xorpd  %xmm2,%xmm2
ucomisd %xmm2,%xmm0
jne    114e <exp+0x1e>
jp     114e <exp+0x1e>
movsd  0xeb7(%rip),%xmm0
jmp    11d9 <exp+0xa9>
movapd %xmm0,%xmm1
movapd 0xec6(%rip),%xmm3
xorpd  %xmm0,%xmm3
cmpltsd %xmm2,%xmm0
andpd  %xmm0,%xmm3
andnpd %xmm1,%xmm0
orpd   %xmm3,%xmm0
mulsd  0xe91(%rip),%xmm0
movapd %xmm0,(%rsp)
movapd %xmm1,0x10(%rsp)
call   1050 <floor@plt>
cvttsd2si %xmm0,%ebx
cvttpd2dq %xmm0,%xmm0
cvtdq2pd %xmm0,%xmm1
movapd (%rsp),%xmm0
subsd  %xmm1,%xmm0
lea    0x2e9d(%rip),%rdi
mov    $0x9,%esi
mov    $0x1,%al
call   1040 <eval_poly@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
mov    %ebx,%edi
call   1030 <ldexp@plt>
xorpd  %xmm1,%xmm1
ucomisd 0x10(%rsp),%xmm1
jbe    11d9 <exp+0xa9>
movsd  0xe2f(%rip),%xmm1
divsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@exp.coeff = internal global [10 x double] [double 1.000000e+00, double 0x3FE62E42FEFA3BDC, double 0x3FCEBFBDFF7DC4BF, double 0x3FAC6B08D96CBF2D, double 0x3F83B2AB0B10246D, double 0x3F55D89044336C2F, double 0x3F242F14FF9B3E42, double 0x3EF0127DD2BFE194, double 0x3EB4F25406F9153B, double 0x3E82AAC8BAB83B03]
define double @exp(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca i32
%5 = alloca i8
store double %0, double* %3
%6 = load double, double* %3
%7 = fcmp oeq double %6, 0.000000e+00
br i1 %7, label %8, label %9
8: ; preds = %1
store double 1.000000e+00, double* %2
br label %41
9: ; preds = %1
%10 = load double, double* %3
%11 = fcmp olt double %10, 0.000000e+00
%12 = zext i1 %11 to i32
%13 = trunc i32 %12 to i8
store i8 %13, i8* %5
%14 = load i8, i8* %5
%15 = icmp ne i8 %14, 0
br i1 %15, label %16, label %19
16: ; preds = %9
%17 = load double, double* %3
%18 = fneg double %17
store double %18, double* %3
br label %19
19: ; preds = %16, %9
%20 = load double, double* %3
%21 = fmul double %20, 0x3FF71547652C4526
store double %21, double* %3
%22 = load double, double* %3
%23 = call double @llvm.floor.f64(double %22)
%24 = fptosi double %23 to i32
store i32 %24, i32* %4
%25 = load i32, i32* %4
%26 = sitofp i32 %25 to double
%27 = load double, double* %3
%28 = fsub double %27, %26
store double %28, double* %3
%29 = load double, double* %3
%30 = call i32 (double, double*, i64, ...) bitcast (i32 (...)* @eval_poly to i32 (double, double*, i64, ...)*)(double %29, double* getelementptr inbounds ([10 x double], [10 x double]* @exp.coeff, i64 0, i64 0), i64 9)
%31 = sitofp i32 %30 to double
%32 = load i32, i32* %4
%33 = call double @ldexp(double %31, i32 %32)
store double %33, double* %3
%34 = load i8, i8* %5
%35 = icmp ne i8 %34, 0
br i1 %35, label %36, label %39
36: ; preds = %19
%37 = load double, double* %3
%38 = fdiv double 1.000000e+00, %37
store double %38, double* %2
br label %41
39: ; preds = %19
%40 = load double, double* %3
store double %40, double* %2
br label %41
41: ; preds = %39, %36, %8
%42 = load double, double* %2
ret double %42
}

LLVM IR (-O2):
@exp.coeff = internal global [10 x double] [double 1.000000e+00, double 0x3FE62E42FEFA3BDC, double 0x3FCEBFBDFF7DC4BF, double 0x3FAC6B08D96CBF2D, double 0x3F83B2AB0B10246D, double 0x3F55D89044336C2F, double 0x3F242F14FF9B3E42, double 0x3EF0127DD2BFE194, double 0x3EB4F25406F9153B, double 0x3E82AAC8BAB83B03]
define double @exp(double %0) {
%2 = fcmp oeq double %0, 0.000000e+00
br i1 %2, label %17, label %3
3: ; preds = %1
%4 = fcmp olt double %0, 0.000000e+00
%5 = fneg double %0
%6 = select i1 %4, double %5, double %0
%7 = fmul double %6, 0x3FF71547652C4526
%8 = tail call double @llvm.floor.f64(double %7)
%9 = fptosi double %8 to i32
%10 = sitofp i32 %9 to double
%11 = fsub double %7, %10
%12 = tail call i32 (double, double*, i64, ...) bitcast (i32 (...)* @eval_poly to i32 (double, double*, i64, ...)*)(double %11, double* getelementptr inbounds ([10 x double], [10 x double]* @exp.coeff, i64 0, i64 0), i64 9)
%13 = sitofp i32 %12 to double
%14 = tail call double @ldexp(double %13, i32 %9)
br i1 %4, label %15, label %17
15: ; preds = %3
%16 = fdiv double 1.000000e+00, %14
br label %17
17: ; preds = %3, %1, %15
%18 = phi double [ %16, %15 ], [ 1.000000e+00, %1 ], [ %14, %3 ]
ret double %18
}