#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 exp(double);
double transition_tan(double n) {
  if (n < -45.0)
    return -1.0;
  else if (n > 45.0)
    return 1.0;
  return (double)(exp(n) - exp(-n)) / (exp(n) + exp(-n));
}


x86 assembly (clang, -O0):
<transition_tan>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  0xedb(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1142 <transition_tan+0x32>
movsd  0xee0(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11fb <transition_tan+0xeb>
movsd  -0x10(%rbp),%xmm0
movsd  0xeb9(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    116b <transition_tan+0x5b>
movsd  0xeaf(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11fb <transition_tan+0xeb>
jmp    1170 <transition_tan+0x60>
movsd  -0x10(%rbp),%xmm0
call   1030 <exp@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1030 <exp@plt>
movaps %xmm0,%xmm1
movsd  -0x28(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1030 <exp@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1030 <exp@plt>
movsd  -0x20(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x18(%rbp),%xmm0
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<transition_tan>:
sub    $0x38,%rsp
movsd  0xeec(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    112f <transition_tan+0x1f>
movsd  0xed6(%rip),%xmm0
add    $0x38,%rsp
ret
ucomisd 0xee1(%rip),%xmm0
jbe    1146 <transition_tan+0x36>
movsd  0xecf(%rip),%xmm0
add    $0x38,%rsp
ret
movapd %xmm0,0x10(%rsp)
call   1030 <exp@plt>
movsd  %xmm0,0x8(%rsp)
movapd 0xec1(%rip),%xmm0
xorpd  0x10(%rsp),%xmm0
movapd %xmm0,0x20(%rsp)
call   1030 <exp@plt>
movsd  0x8(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
movaps 0x10(%rsp),%xmm0
call   1030 <exp@plt>
movsd  %xmm0,0x10(%rsp)
movapd 0x20(%rsp),%xmm0
call   1030 <exp@plt>
addsd  0x10(%rsp),%xmm0
movsd  0x8(%rsp),%xmm1
divsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
add    $0x38,%rsp
ret

LLVM IR (-O0):
define double @transition_tan(double %0) {
%2 = alloca double
%3 = alloca double
store double %0, double* %3
%4 = load double, double* %3
%5 = fcmp olt double %4, -4.500000e+01
br i1 %5, label %6, label %7
6: ; preds = %1
store double -1.000000e+00, double* %2
br label %26
7: ; preds = %1
%8 = load double, double* %3
%9 = fcmp ogt double %8, 4.500000e+01
br i1 %9, label %10, label %11
10: ; preds = %7
store double 1.000000e+00, double* %2
br label %26
11: ; preds = %7
br label %12
12: ; preds = %11
%13 = load double, double* %3
%14 = call double @exp(double %13)
%15 = load double, double* %3
%16 = fneg double %15
%17 = call double @exp(double %16)
%18 = fsub double %14, %17
%19 = load double, double* %3
%20 = call double @exp(double %19)
%21 = load double, double* %3
%22 = fneg double %21
%23 = call double @exp(double %22)
%24 = fadd double %20, %23
%25 = fdiv double %18, %24
store double %25, double* %2
br label %26
26: ; preds = %12, %10, %6
%27 = load double, double* %2
ret double %27
}

LLVM IR (-O2):
define double @transition_tan(double %0) {
%2 = fcmp olt double %0, -4.500000e+01
br i1 %2, label %14, label %3
3: ; preds = %1
%4 = fcmp ogt double %0, 4.500000e+01
br i1 %4, label %14, label %5
5: ; preds = %3
%6 = tail call double @exp(double %0)
%7 = fneg double %0
%8 = tail call double @exp(double %7)
%9 = fsub double %6, %8
%10 = tail call double @exp(double %0)
%11 = tail call double @exp(double %7)
%12 = fadd double %10, %11
%13 = fdiv double %9, %12
br label %14
14: ; preds = %3, %1, %5
%15 = phi double [ %13, %5 ], [ -1.000000e+00, %1 ], [ 1.000000e+00, %3 ]
ret double %15
}