#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 */
typedef int uint64_t;

/* Variables and functions */
int FP_INFINITE;
int FP_NAN;
int FP_NORMAL;
int FP_SUBNORMAL;
int FP_ZERO;
int __fpclassify(double x) {
  union {
    double f;
    uint64_t i;
  } u = {x};
  int e = u.i >> 52 & 0x7ff;
  if (!e)
    return u.i << 1 ? FP_SUBNORMAL : FP_ZERO;
  if (e == 0x7ff)
    return u.i << 12 ? FP_NAN : FP_INFINITE;
  return FP_NORMAL;
}


x86 assembly (clang, -O0):
<__fpclassify>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    $0x34,%ecx
sar    %cl,%eax
and    $0x7ff,%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jne    1166 <__fpclassify+0x66>
mov    -0x18(%rbp),%eax
shl    $0x1,%eax
cmp    $0x0,%eax
je     114f <__fpclassify+0x4f>
mov    0x2e7b(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x20(%rbp)
jmp    115b <__fpclassify+0x5b>
mov    0x2e7a(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    11b6 <__fpclassify+0xb6>
cmpl   $0x7ff,-0x1c(%rbp)
jne    11aa <__fpclassify+0xaa>
mov    -0x18(%rbp),%eax
shl    $0xc,%eax
cmp    $0x0,%eax
je     1193 <__fpclassify+0x93>
mov    0x2e57(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x24(%rbp)
jmp    119f <__fpclassify+0x9f>
mov    0x2e3e(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    11b6 <__fpclassify+0xb6>
mov    0x2e3f(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<__fpclassify>:
movq   %xmm0,%rax
test   $0x7fffffff,%eax
jne    1116 <__fpclassify+0x16>
mov    0x2ed5(%rip),%rax
mov    (%rax),%eax
ret
mov    0x2ebb(%rip),%rax
mov    (%rax),%eax
ret

LLVM IR (-O0):
%union.anon = type { double }
@FP_SUBNORMAL = global i32 0
@FP_ZERO = global i32 0
@FP_NAN = global i32 0
@FP_INFINITE = global i32 0
@FP_NORMAL = global i32 0
define i32 @__fpclassify(double %0) {
%2 = alloca i32
%3 = alloca double
%4 = alloca %union.anon
%5 = alloca i32
store double %0, double* %3
%6 = bitcast %union.anon* %4 to double*
%7 = load double, double* %3
store double %7, double* %6
%8 = bitcast %union.anon* %4 to i32*
%9 = load i32, i32* %8
%10 = ashr i32 %9, 52
%11 = and i32 %10, 2047
store i32 %11, i32* %5
%12 = load i32, i32* %5
%13 = icmp ne i32 %12, 0
br i1 %13, label %25, label %14
14: ; preds = %1
%15 = bitcast %union.anon* %4 to i32*
%16 = load i32, i32* %15
%17 = shl i32 %16, 1
%18 = icmp ne i32 %17, 0
br i1 %18, label %19, label %21
19: ; preds = %14
%20 = load i32, i32* @FP_SUBNORMAL
br label %23
21: ; preds = %14
%22 = load i32, i32* @FP_ZERO
br label %23
23: ; preds = %21, %19
%24 = phi i32 [ %20, %19 ], [ %22, %21 ]
store i32 %24, i32* %2
br label %41
25: ; preds = %1
%26 = load i32, i32* %5
%27 = icmp eq i32 %26, 2047
br i1 %27, label %28, label %39
28: ; preds = %25
%29 = bitcast %union.anon* %4 to i32*
%30 = load i32, i32* %29
%31 = shl i32 %30, 12
%32 = icmp ne i32 %31, 0
br i1 %32, label %33, label %35
33: ; preds = %28
%34 = load i32, i32* @FP_NAN
br label %37
35: ; preds = %28
%36 = load i32, i32* @FP_INFINITE
br label %37
37: ; preds = %35, %33
%38 = phi i32 [ %34, %33 ], [ %36, %35 ]
store i32 %38, i32* %2
br label %41
39: ; preds = %25
%40 = load i32, i32* @FP_NORMAL
store i32 %40, i32* %2
br label %41
41: ; preds = %39, %37, %23
%42 = load i32, i32* %2
ret i32 %42
}

LLVM IR (-O2):
@FP_SUBNORMAL = global i32 0
@FP_ZERO = global i32 0
@FP_NAN = global i32 0
@FP_INFINITE = global i32 0
@FP_NORMAL = global i32 0
define i32 @__fpclassify(double %0) {
%2 = bitcast double %0 to i64
%3 = and i64 %2, 2147483647
%4 = icmp eq i64 %3, 0
%5 = load i32, i32* @FP_ZERO
%6 = load i32, i32* @FP_SUBNORMAL
%7 = select i1 %4, i32 %5, i32 %6
ret i32 %7
}