#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 */
double __builtin_inf();
int /*<<< orphan*/ dd(double, double);
int /*<<< orphan*/ ddmul_d2_d2_d(int /*<<< orphan*/, double);
double expk(int /*<<< orphan*/);
scalar_t__ xisminf(double);
double xexp2(double a) {
  double u = expk(
      ddmul_d2_d2_d(dd(0.69314718055994528623, 2.3190468138462995584e-17), a));
  if (a > 1023)
    u = __builtin_inf();
  if (xisminf(a))
    u = 0;
  return u;
}


x86 assembly (clang, -O0):
<xexp2>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  0xeb3(%rip),%xmm0
movsd  0xeb3(%rip),%xmm1
call   1050 <dd@plt>
mov    %eax,%edi
movsd  -0x8(%rbp),%xmm0
call   1030 <ddmul_d2_d2_d@plt>
mov    %eax,%edi
call   1060 <expk@plt>
movsd  %xmm0,-0x10(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  0xe79(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    119e <xexp2+0x5e>
movsd  0xe7f(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x8(%rbp),%xmm0
call   1040 <xisminf@plt>
cmp    $0x0,%rax
je     11ba <xexp2+0x7a>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<xexp2>:
sub    $0x28,%rsp
movsd  %xmm0,0x8(%rsp)
movsd  0xeae(%rip),%xmm0
movsd  0xeae(%rip),%xmm1
call   1050 <dd@plt>
mov    %eax,%edi
movsd  0x8(%rsp),%xmm0
call   1030 <ddmul_d2_d2_d@plt>
mov    %eax,%edi
call   1060 <expk@plt>
movaps %xmm0,0x10(%rsp)
movsd  0x8(%rsp),%xmm0
call   1040 <xisminf@plt>
test   %rax,%rax
je     1190 <xexp2+0x50>
xorps  %xmm0,%xmm0
add    $0x28,%rsp
ret
movsd  0xe78(%rip),%xmm1
cmpltsd 0x8(%rsp),%xmm1
movsd  0xe71(%rip),%xmm0
andpd  %xmm1,%xmm0
andnpd 0x10(%rsp),%xmm1
orpd   %xmm1,%xmm0
add    $0x28,%rsp
ret

LLVM IR (-O0):
define double @xexp2(double %0) {
%2 = alloca double
%3 = alloca double
store double %0, double* %2
%4 = call i32 @dd(double 0x3FE62E42FEFA39EF, double 0x3C7ABC9E3B39803F)
%5 = load double, double* %2
%6 = call i32 @ddmul_d2_d2_d(i32 %4, double %5)
%7 = call double @expk(i32 %6)
store double %7, double* %3
%8 = load double, double* %2
%9 = fcmp ogt double %8, 1.023000e+03
br i1 %9, label %10, label %11
10: ; preds = %1
store double 0x7FF0000000000000, double* %3
br label %11
11: ; preds = %10, %1
%12 = load double, double* %2
%13 = call i64 @xisminf(double %12)
%14 = icmp ne i64 %13, 0
br i1 %14, label %15, label %16
15: ; preds = %11
store double 0.000000e+00, double* %3
br label %16
16: ; preds = %15, %11
%17 = load double, double* %3
ret double %17
}

LLVM IR (-O2):
define double @xexp2(double %0) {
%2 = tail call i32 @dd(double 0x3FE62E42FEFA39EF, double 0x3C7ABC9E3B39803F)
%3 = tail call i32 @ddmul_d2_d2_d(i32 %2, double %0)
%4 = tail call double @expk(i32 %3)
%5 = fcmp ogt double %0, 1.023000e+03
%6 = select i1 %5, double 0x7FF0000000000000, double %4
%7 = tail call i64 @xisminf(double %0)
%8 = icmp eq i64 %7, 0
%9 = select i1 %8, double %6, double 0.000000e+00
ret double %9
}