#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 log(double);
scalar_t__ sqrt(double);
double acosh(double x) {
  if (x < 1)
    x = -1;
  else if (x == 1)
    return 0;
  else if (x > (1.0 * (1 << 53 / 2)))
    x += x;
  else
    x += sqrt((x + 1) * (x - 1));
  return log(x);
}


x86 assembly (clang, -O0):
<acosh>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  0xecb(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1152 <acosh+0x32>
movsd  0xec8(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    11e7 <acosh+0xc7>
movsd  -0x10(%rbp),%xmm0
movsd  0xea1(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    117c <acosh+0x5c>
jp     117c <acosh+0x5c>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11f6 <acosh+0xd6>
movsd  -0x10(%rbp),%xmm0
movsd  0xe7f(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11a7 <acosh+0x87>
movsd  -0x10(%rbp),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    11dd <acosh+0xbd>
movsd  0xe51(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
movsd  0xe3f(%rip),%xmm2
subsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
call   1040 <sqrt@plt>
cvtsi2sd %rax,%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    11e2 <acosh+0xc2>
jmp    11e7 <acosh+0xc7>
movsd  -0x10(%rbp),%xmm0
call   1030 <log@plt>
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<acosh>:
push   %rax
movapd %xmm0,%xmm2
movsd  0xedb(%rip),%xmm0
ucomisd %xmm2,%xmm0
jbe    1145 <acosh+0x25>
movsd  0xec5(%rip),%xmm2
movapd %xmm2,%xmm0
pop    %rax
jmp    1030 <log@plt>
ucomisd 0xebb(%rip),%xmm2
jne    1157 <acosh+0x37>
jp     1157 <acosh+0x37>
xorpd  %xmm0,%xmm0
pop    %rax
ret
ucomisd 0xeb1(%rip),%xmm2
jbe    1167 <acosh+0x47>
addsd  %xmm2,%xmm2
jmp    113b <acosh+0x1b>
movsd  0xe99(%rip),%xmm1
addsd  %xmm2,%xmm1
movsd  0xe85(%rip),%xmm0
addsd  %xmm2,%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm2,(%rsp)
call   1040 <sqrt@plt>
movsd  (%rsp),%xmm2
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  %xmm0,%xmm2
jmp    113b <acosh+0x1b>

LLVM IR (-O0):
define double @acosh(double %0) {
%2 = alloca double
%3 = alloca double
store double %0, double* %3
%4 = load double, double* %3
%5 = fcmp olt double %4, 1.000000e+00
br i1 %5, label %6, label %7
6: ; preds = %1
store double -1.000000e+00, double* %3
br label %30
7: ; preds = %1
%8 = load double, double* %3
%9 = fcmp oeq double %8, 1.000000e+00
br i1 %9, label %10, label %11
10: ; preds = %7
store double 0.000000e+00, double* %2
br label %33
11: ; preds = %7
%12 = load double, double* %3
%13 = fcmp ogt double %12, 0x4190000000000000
br i1 %13, label %14, label %18
14: ; preds = %11
%15 = load double, double* %3
%16 = load double, double* %3
%17 = fadd double %16, %15
store double %17, double* %3
br label %28
18: ; preds = %11
%19 = load double, double* %3
%20 = fadd double %19, 1.000000e+00
%21 = load double, double* %3
%22 = fsub double %21, 1.000000e+00
%23 = fmul double %20, %22
%24 = call i64 @sqrt(double %23)
%25 = sitofp i64 %24 to double
%26 = load double, double* %3
%27 = fadd double %26, %25
store double %27, double* %3
br label %28
28: ; preds = %18, %14
br label %29
29: ; preds = %28
br label %30
30: ; preds = %29, %6
%31 = load double, double* %3
%32 = call double @log(double %31)
store double %32, double* %2
br label %33
33: ; preds = %30, %10
%34 = load double, double* %2
ret double %34
}

LLVM IR (-O2):
define double @acosh(double %0) {
%2 = fcmp olt double %0, 1.000000e+00
br i1 %2, label %16, label %3
3: ; preds = %1
%4 = fcmp oeq double %0, 1.000000e+00
br i1 %4, label %19, label %5
5: ; preds = %3
%6 = fcmp ogt double %0, 0x4190000000000000
br i1 %6, label %7, label %9
7: ; preds = %5
%8 = fadd double %0, %0
br label %16
9: ; preds = %5
%10 = fadd double %0, 1.000000e+00
%11 = fadd double %0, -1.000000e+00
%12 = fmul double %10, %11
%13 = tail call i64 @sqrt(double %12)
%14 = sitofp i64 %13 to double
%15 = fadd double %14, %0
br label %16
16: ; preds = %1, %9, %7
%17 = phi double [ %8, %7 ], [ %15, %9 ], [ -1.000000e+00, %1 ]
%18 = tail call double @log(double %17)
br label %19
19: ; preds = %3, %16
%20 = phi double [ %18, %16 ], [ 0.000000e+00, %3 ]
ret double %20
}