#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 */
float FastExp2(float);
float FastTanh(float x) {
  if (x >= 9.011f) {
    return 1.0f;
  }
  if (x <= -9.011f) {
    return -1.0f;
  }
  const float exp_2x = FastExp2((float)(2.0 / 0.69314718055994531) * x);
  return (exp_2x - 1.0f) / (exp_2x + 1.0f);
}


x86 assembly (clang, -O0):
<FastTanh>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
movss  0xed6(%rip),%xmm1
ucomiss %xmm1,%xmm0
jb     1145 <FastTanh+0x35>
movss  0xecd(%rip),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    11a7 <FastTanh+0x97>
movss  0xeb7(%rip),%xmm0
ucomiss -0x8(%rbp),%xmm0
jb     1169 <FastTanh+0x59>
movss  0xeb1(%rip),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    11a7 <FastTanh+0x97>
movss  0xe9b(%rip),%xmm0
mulss  -0x8(%rbp),%xmm0
call   1030 <FastExp2@plt>
movss  %xmm0,-0xc(%rbp)
movss  -0xc(%rbp),%xmm0
movss  0xe7b(%rip),%xmm1
subss  %xmm1,%xmm0
movss  0xe6f(%rip),%xmm1
addss  -0xc(%rbp),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<FastTanh>:
push   %rax
ucomiss 0xeec(%rip),%xmm0
jae    1151 <FastTanh+0x41>
movss  0xeea(%rip),%xmm1
ucomiss %xmm0,%xmm1
jae    115b <FastTanh+0x4b>
mulss  0xee1(%rip),%xmm0
call   1030 <FastExp2@plt>
movaps %xmm0,%xmm1
movss  0xec9(%rip),%xmm0
addss  %xmm1,%xmm0
addss  0xeb5(%rip),%xmm1
divss  %xmm1,%xmm0
pop    %rax
ret
movss  0xea7(%rip),%xmm0
pop    %rax
ret
movss  0xea5(%rip),%xmm0
pop    %rax
ret

LLVM IR (-O0):
define float @FastTanh(float %0) {
%2 = alloca float
%3 = alloca float
%4 = alloca float
store float %0, float* %3
%5 = load float, float* %3
%6 = fcmp oge float %5, 0x402205A1C0000000
br i1 %6, label %7, label %8
7: ; preds = %1
store float 1.000000e+00, float* %2
br label %21
8: ; preds = %1
%9 = load float, float* %3
%10 = fcmp ole float %9, 0xC02205A1C0000000
br i1 %10, label %11, label %12
11: ; preds = %8
store float -1.000000e+00, float* %2
br label %21
12: ; preds = %8
%13 = load float, float* %3
%14 = fmul float 0x4007154760000000, %13
%15 = call float @FastExp2(float %14)
store float %15, float* %4
%16 = load float, float* %4
%17 = fsub float %16, 1.000000e+00
%18 = load float, float* %4
%19 = fadd float %18, 1.000000e+00
%20 = fdiv float %17, %19
store float %20, float* %2
br label %21
21: ; preds = %12, %11, %7
%22 = load float, float* %2
ret float %22
}

LLVM IR (-O2):
define float @FastTanh(float %0) {
%2 = fcmp ult float %0, 0x402205A1C0000000
br i1 %2, label %3, label %11
3: ; preds = %1
%4 = fcmp ugt float %0, 0xC02205A1C0000000
br i1 %4, label %5, label %11
5: ; preds = %3
%6 = fmul float %0, 0x4007154760000000
%7 = tail call float @FastExp2(float %6)
%8 = fadd float %7, -1.000000e+00
%9 = fadd float %7, 1.000000e+00
%10 = fdiv float %8, %9
br label %11
11: ; preds = %3, %1, %5
%12 = phi float [ %10, %5 ], [ 1.000000e+00, %1 ], [ -1.000000e+00, %3 ]
ret float %12
}