double exp2(double x) {
  typedef union {
    double d;
    unsigned u[4];
  } DBL;
  double y, x2, p, q, re;
  int ix;
  DBL *xp, *yp;
  xp = (DBL *)&x;
  y = 0.0;
  yp = (DBL *)&y;
  if (xp->d > 1023.0 || xp->d < -1023.0)
    return (1E307);
  ix = (int)xp->d;
  yp->u[3] += ix + 1023 << 4;
  yp->u[3] &= ~0100017;
  if ((xp->d -= (double)ix) == 0.0)
    return (yp->d);
  if (xp->d < 0.0) {
    yp->u[3] -= 1 << 4;
    yp->u[3] &= ~0100017;
    xp->d++;
  }
  if (xp->d >= 0.5) {
    xp->d -= 0.5;
    re = 1.41421356237309504880;
  } else
    re = 1.0;
  x2 = xp->d * xp->d;
  p = xp->d * (7.2152891511493 + x2 * 0.0576900723731);
  q = 20.8189237930062 + x2;
  xp->d = (q + p) / (q - p);
  yp->d *= re * xp->d;
  return (yp->d);
}


x86 assembly (clang, -O0):
<exp2>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
lea    -0x10(%rbp),%rax
mov    %rax,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x18(%rbp)
lea    -0x18(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x48(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xecf(%rip),%xmm1
ucomisd %xmm1,%xmm0
ja     1151 <exp2+0x51>
mov    -0x48(%rbp),%rax
movsd  0xec1(%rip),%xmm0
ucomisd (%rax),%xmm0
jbe    1163 <exp2+0x63>
movsd  0xee7(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12fc <exp2+0x1fc>
mov    -0x48(%rbp),%rax
cvttsd2si (%rax),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x3c(%rbp),%ecx
add    $0x3ff,%ecx
shl    $0x4,%ecx
mov    -0x50(%rbp),%rax
add    0xc(%rax),%ecx
mov    %ecx,0xc(%rax)
mov    -0x50(%rbp),%rax
mov    0xc(%rax),%ecx
and    $0xffff7ff0,%ecx
mov    %ecx,0xc(%rax)
cvtsi2sdl -0x3c(%rbp),%xmm1
mov    -0x48(%rbp),%rax
movsd  (%rax),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11ce <exp2+0xce>
jp     11ce <exp2+0xce>
mov    -0x50(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12fc <exp2+0x1fc>
mov    -0x48(%rbp),%rax
xorps  %xmm0,%xmm0
ucomisd (%rax),%xmm0
jbe    1210 <exp2+0x110>
mov    -0x50(%rbp),%rax
mov    0xc(%rax),%ecx
sub    $0x10,%ecx
mov    %ecx,0xc(%rax)
mov    -0x50(%rbp),%rax
mov    0xc(%rax),%ecx
and    $0xffff7ff0,%ecx
mov    %ecx,0xc(%rax)
mov    -0x48(%rbp),%rax
movsd  0xe08(%rip),%xmm0
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
mov    -0x48(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xdf8(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1254 <exp2+0x154>
mov    -0x48(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xdde(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  0xdd6(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
jmp    1261 <exp2+0x161>
movsd  0xdb4(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x48(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x48(%rbp),%rax
mulsd  (%rax),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x48(%rbp),%rax
movsd  (%rax),%xmm0
movsd  -0x20(%rbp),%xmm1
movsd  0xda5(%rip),%xmm2
mulsd  %xmm2,%xmm1
movsd  0xda1(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xd7c(%rip),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm1
subsd  -0x28(%rbp),%xmm1
divsd  %xmm1,%xmm0
mov    -0x48(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x38(%rbp),%xmm0
mov    -0x48(%rbp),%rax
mulsd  (%rax),%xmm0
mov    -0x50(%rbp),%rax
mulsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
mov    -0x50(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<exp2>:
movapd %xmm0,%xmm1
ucomisd 0xef4(%rip),%xmm0
movsd  0xef4(%rip),%xmm0
ja     113c <exp2+0x3c>
movsd  0xef2(%rip),%xmm2
ucomisd %xmm1,%xmm2
ja     113c <exp2+0x3c>
cvttpd2dq %xmm1,%xmm0
cvtdq2pd %xmm0,%xmm0
subsd  %xmm0,%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jne    113d <exp2+0x3d>
jp     113d <exp2+0x3d>
ret
movsd  0xed3(%rip),%xmm3
addsd  %xmm1,%xmm3
xorpd  %xmm2,%xmm2
movapd %xmm1,%xmm0
cmpltsd %xmm2,%xmm0
andpd  %xmm0,%xmm3
andnpd %xmm1,%xmm0
orpd   %xmm3,%xmm0
xor    %eax,%eax
ucomisd 0xeb4(%rip),%xmm0
setb   %cl
jb     1179 <exp2+0x79>
addsd  0xeaf(%rip),%xmm0
movapd %xmm0,%xmm1
mulsd  %xmm0,%xmm1
movsd  0xea7(%rip),%xmm3
mulsd  %xmm1,%xmm3
addsd  0xea3(%rip),%xmm3
addsd  0xea3(%rip),%xmm1
mulsd  %xmm0,%xmm3
movapd %xmm1,%xmm0
addsd  %xmm3,%xmm0
subsd  %xmm3,%xmm1
divsd  %xmm1,%xmm0
mov    %cl,%al
lea    0xe8e(%rip),%rcx
mulsd  (%rcx,%rax,8),%xmm0
mulsd  %xmm2,%xmm0
ret

LLVM IR (-O0):
%union.DBL = type { double, [8 x i8] }
define double @exp2(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 i32
%10 = alloca %union.DBL*
%11 = alloca %union.DBL*
store double %0, double* %3
%12 = bitcast double* %3 to %union.DBL*
store %union.DBL* %12, %union.DBL** %10
store double 0.000000e+00, double* %4
%13 = bitcast double* %4 to %union.DBL*
store %union.DBL* %13, %union.DBL** %11
%14 = load %union.DBL*, %union.DBL** %10
%15 = bitcast %union.DBL* %14 to double*
%16 = load double, double* %15
%17 = fcmp ogt double %16, 1.023000e+03
br i1 %17, label %23, label %18
18: ; preds = %1
%19 = load %union.DBL*, %union.DBL** %10
%20 = bitcast %union.DBL* %19 to double*
%21 = load double, double* %20
%22 = fcmp olt double %21, -1.023000e+03
br i1 %22, label %23, label %24
23: ; preds = %18, %1
store double 0x7FAC7B1F3CAC7433, double* %2
br label %121
24: ; preds = %18
%25 = load %union.DBL*, %union.DBL** %10
%26 = bitcast %union.DBL* %25 to double*
%27 = load double, double* %26
%28 = fptosi double %27 to i32
store i32 %28, i32* %9
%29 = load i32, i32* %9
%30 = add nsw i32 %29, 1023
%31 = shl i32 %30, 4
%32 = load %union.DBL*, %union.DBL** %11
%33 = bitcast %union.DBL* %32 to [4 x i32]*
%34 = getelementptr inbounds [4 x i32], [4 x i32]* %33, i64 0, i64 3
%35 = load i32, i32* %34
%36 = add i32 %35, %31
store i32 %36, i32* %34
%37 = load %union.DBL*, %union.DBL** %11
%38 = bitcast %union.DBL* %37 to [4 x i32]*
%39 = getelementptr inbounds [4 x i32], [4 x i32]* %38, i64 0, i64 3
%40 = load i32, i32* %39
%41 = and i32 %40, -32784
store i32 %41, i32* %39
%42 = load i32, i32* %9
%43 = sitofp i32 %42 to double
%44 = load %union.DBL*, %union.DBL** %10
%45 = bitcast %union.DBL* %44 to double*
%46 = load double, double* %45
%47 = fsub double %46, %43
store double %47, double* %45
%48 = fcmp oeq double %47, 0.000000e+00
br i1 %48, label %49, label %53
49: ; preds = %24
%50 = load %union.DBL*, %union.DBL** %11
%51 = bitcast %union.DBL* %50 to double*
%52 = load double, double* %51
store double %52, double* %2
br label %121
53: ; preds = %24
%54 = load %union.DBL*, %union.DBL** %10
%55 = bitcast %union.DBL* %54 to double*
%56 = load double, double* %55
%57 = fcmp olt double %56, 0.000000e+00
br i1 %57, label %58, label %73
58: ; preds = %53
%59 = load %union.DBL*, %union.DBL** %11
%60 = bitcast %union.DBL* %59 to [4 x i32]*
%61 = getelementptr inbounds [4 x i32], [4 x i32]* %60, i64 0, i64 3
%62 = load i32, i32* %61
%63 = sub i32 %62, 16
store i32 %63, i32* %61
%64 = load %union.DBL*, %union.DBL** %11
%65 = bitcast %union.DBL* %64 to [4 x i32]*
%66 = getelementptr inbounds [4 x i32], [4 x i32]* %65, i64 0, i64 3
%67 = load i32, i32* %66
%68 = and i32 %67, -32784
store i32 %68, i32* %66
%69 = load %union.DBL*, %union.DBL** %10
%70 = bitcast %union.DBL* %69 to double*
%71 = load double, double* %70
%72 = fadd double %71, 1.000000e+00
store double %72, double* %70
br label %73
73: ; preds = %58, %53
%74 = load %union.DBL*, %union.DBL** %10
%75 = bitcast %union.DBL* %74 to double*
%76 = load double, double* %75
%77 = fcmp oge double %76, 5.000000e-01
br i1 %77, label %78, label %83
78: ; preds = %73
%79 = load %union.DBL*, %union.DBL** %10
%80 = bitcast %union.DBL* %79 to double*
%81 = load double, double* %80
%82 = fsub double %81, 5.000000e-01
store double %82, double* %80
store double 0x3FF6A09E667F3BCD, double* %8
br label %84
83: ; preds = %73
store double 1.000000e+00, double* %8
br label %84
84: ; preds = %83, %78
%85 = load %union.DBL*, %union.DBL** %10
%86 = bitcast %union.DBL* %85 to double*
%87 = load double, double* %86
%88 = load %union.DBL*, %union.DBL** %10
%89 = bitcast %union.DBL* %88 to double*
%90 = load double, double* %89
%91 = fmul double %87, %90
store double %91, double* %5
%92 = load %union.DBL*, %union.DBL** %10
%93 = bitcast %union.DBL* %92 to double*
%94 = load double, double* %93
%95 = load double, double* %5
%96 = call double @llvm.fmuladd.f64(double %95, double 0x3FAD898D9C4AECC3, double 0x401CDC74C25D7AB8)
%97 = fmul double %94, %96
store double %97, double* %6
%98 = load double, double* %5
%99 = fadd double 0x4034D1A4FD5CE0BE, %98
store double %99, double* %7
%100 = load double, double* %7
%101 = load double, double* %6
%102 = fadd double %100, %101
%103 = load double, double* %7
%104 = load double, double* %6
%105 = fsub double %103, %104
%106 = fdiv double %102, %105
%107 = load %union.DBL*, %union.DBL** %10
%108 = bitcast %union.DBL* %107 to double*
store double %106, double* %108
%109 = load double, double* %8
%110 = load %union.DBL*, %union.DBL** %10
%111 = bitcast %union.DBL* %110 to double*
%112 = load double, double* %111
%113 = fmul double %109, %112
%114 = load %union.DBL*, %union.DBL** %11
%115 = bitcast %union.DBL* %114 to double*
%116 = load double, double* %115
%117 = fmul double %116, %113
store double %117, double* %115
%118 = load %union.DBL*, %union.DBL** %11
%119 = bitcast %union.DBL* %118 to double*
%120 = load double, double* %119
store double %120, double* %2
br label %121
121: ; preds = %84, %49, %23
%122 = load double, double* %2
ret double %122
}

LLVM IR (-O2):
%union.DBL = type { double, [8 x i8] }
define double @exp2(double %0) {
%2 = fcmp ogt double %0, 1.023000e+03
%3 = fcmp olt double %0, -1.023000e+03
%4 = or i1 %2, %3
br i1 %4, label %27, label %5
5: ; preds = %1
%6 = fptosi double %0 to i32
%7 = sitofp i32 %6 to double
%8 = fsub double %0, %7
%9 = fcmp oeq double %8, 0.000000e+00
br i1 %9, label %27, label %10
10: ; preds = %5
%11 = fcmp olt double %8, 0.000000e+00
%12 = fadd double %8, 1.000000e+00
%13 = select i1 %11, double %12, double %8
%14 = fcmp ult double %13, 5.000000e-01
%15 = fadd double %13, -5.000000e-01
%16 = select i1 %14, double %13, double %15
%17 = select i1 %14, double 1.000000e+00, double 0x3FF6A09E667F3BCD
%18 = fmul double %16, %16
%19 = tail call double @llvm.fmuladd.f64(double %18, double 0x3FAD898D9C4AECC3, double 0x401CDC74C25D7AB8)
%20 = fmul double %16, %19
%21 = fadd double %18, 0x4034D1A4FD5CE0BE
%22 = fadd double %21, %20
%23 = fsub double %21, %20
%24 = fdiv double %22, %23
%25 = fmul double %17, %24
%26 = fmul double %25, 0.000000e+00
br label %27
27: ; preds = %5, %1, %10
%28 = phi double [ %26, %10 ], [ 0x7FAC7B1F3CAC7433, %1 ], [ 0.000000e+00, %5 ]
ret double %28
}