#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 M_PI;
int cosh(double);
double cosine(double);
double fexp(double);
scalar_t__ floor(double);
double cosineh(double phase, double sharpness) {
  if (sharpness < (1e-10)) {
    return 0.5 + 0.5 * cosine(phase);
  } else if (sharpness < 0.99) {
    double a = sharpness / (1 - sharpness);
    return (cosh(a * cosine(0.5 * phase)) - 1) / (cosh(a) - 1);
  } else if (sharpness < 1) {
    phase -= floor(phase + 0.5);
    double a = -0.5 * M_PI * M_PI * sharpness / (1 - sharpness);
    return fexp(a * phase * phase);
  } else {
    return 0.0;
  }
}


x86 assembly (clang, -O0):
<cosineh>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  0xea6(%rip),%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    1189 <cosineh+0x49>
movsd  -0x10(%rbp),%xmm0
call   1030 <cosine@plt>
movsd  0xea9(%rip),%xmm1
mulsd  %xmm1,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12a4 <cosineh+0x164>
movsd  0xe77(%rip),%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    120d <cosineh+0xcd>
movsd  -0x18(%rbp),%xmm0
movsd  0xe67(%rip),%xmm1
subsd  -0x18(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0xe57(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
call   1030 <cosine@plt>
movaps %xmm0,%xmm1
movsd  -0x38(%rbp),%xmm0
mulsd  %xmm1,%xmm0
call   1040 <cosh@plt>
sub    $0x1,%eax
mov    %eax,-0x2c(%rbp)
movsd  -0x20(%rbp),%xmm0
call   1040 <cosh@plt>
mov    %eax,%ecx
mov    -0x2c(%rbp),%eax
sub    $0x1,%ecx
cltd
idiv   %ecx
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12a4 <cosineh+0x164>
movsd  0xdfb(%rip),%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    129c <cosineh+0x15c>
movsd  0xdf8(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
call   1060 <floor@plt>
cvtsi2sd %rax,%xmm1
movsd  -0x10(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xdcb(%rip),%xmm0
mov    0x2d94(%rip),%rax
mulsd  (%rax),%xmm0
mov    0x2d89(%rip),%rax
mulsd  (%rax),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  0xda0(%rip),%xmm1
subsd  -0x18(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
call   1050 <fexp@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    12a4 <cosineh+0x164>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<cosineh>:
push   %rbx
sub    $0x10,%rsp
movapd %xmm0,%xmm2
movsd  0xeaf(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    1175 <cosineh+0x35>
movapd %xmm2,%xmm0
call   1030 <cosine@plt>
movsd  0xeb0(%rip),%xmm1
mulsd  %xmm1,%xmm0
addsd  %xmm1,%xmm0
jmp    125e <cosineh+0x11e>
movsd  0xe8b(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    11d8 <cosineh+0x98>
movsd  0xe85(%rip),%xmm0
subsd  %xmm1,%xmm0
divsd  %xmm0,%xmm1
movsd  %xmm1,(%rsp)
mulsd  0xe78(%rip),%xmm2
movapd %xmm2,%xmm0
call   1030 <cosine@plt>
mulsd  (%rsp),%xmm0
call   1040 <cosh@plt>
mov    %eax,%ebx
add    $0xffffffff,%ebx
movsd  (%rsp),%xmm0
call   1040 <cosh@plt>
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ebx,%eax
cltd
idiv   %ecx
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
jmp    125e <cosineh+0x11e>
xorpd  %xmm0,%xmm0
movsd  0xe2c(%rip),%xmm3
ucomisd %xmm1,%xmm3
jbe    125e <cosineh+0x11e>
movsd  0xe26(%rip),%xmm0
addsd  %xmm2,%xmm0
movsd  %xmm1,(%rsp)
movsd  %xmm2,0x8(%rsp)
call   1060 <floor@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
movsd  0x8(%rsp),%xmm2
subsd  %xmm0,%xmm2
mov    0x2dc9(%rip),%rax
movsd  (%rax),%xmm1
movsd  0xdf5(%rip),%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
movsd  (%rsp),%xmm3
mulsd  %xmm3,%xmm0
movsd  0xdcc(%rip),%xmm1
subsd  %xmm3,%xmm1
divsd  %xmm1,%xmm0
mulsd  %xmm2,%xmm0
mulsd  %xmm2,%xmm0
add    $0x10,%rsp
pop    %rbx
jmp    1050 <fexp@plt>
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@M_PI = global double 0.000000e+00
define double @cosineh(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
store double %0, double* %4
store double %1, double* %5
%8 = load double, double* %5
%9 = fcmp olt double %8, 1.000000e-10
br i1 %9, label %10, label %14
10: ; preds = %2
%11 = load double, double* %4
%12 = call double @cosine(double %11)
%13 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %12, double 5.000000e-01)
store double %13, double* %3
br label %60
14: ; preds = %2
%15 = load double, double* %5
%16 = fcmp olt double %15, 0x3FEFAE147AE147AE
br i1 %16, label %17, label %34
17: ; preds = %14
%18 = load double, double* %5
%19 = load double, double* %5
%20 = fsub double 1.000000e+00, %19
%21 = fdiv double %18, %20
store double %21, double* %6
%22 = load double, double* %6
%23 = load double, double* %4
%24 = fmul double 5.000000e-01, %23
%25 = call double @cosine(double %24)
%26 = fmul double %22, %25
%27 = call i32 @cosh(double %26)
%28 = sub nsw i32 %27, 1
%29 = load double, double* %6
%30 = call i32 @cosh(double %29)
%31 = sub nsw i32 %30, 1
%32 = sdiv i32 %28, %31
%33 = sitofp i32 %32 to double
store double %33, double* %3
br label %60
34: ; preds = %14
%35 = load double, double* %5
%36 = fcmp olt double %35, 1.000000e+00
br i1 %36, label %37, label %59
37: ; preds = %34
%38 = load double, double* %4
%39 = fadd double %38, 5.000000e-01
%40 = call i64 @floor(double %39)
%41 = sitofp i64 %40 to double
%42 = load double, double* %4
%43 = fsub double %42, %41
store double %43, double* %4
%44 = load double, double* @M_PI
%45 = fmul double -5.000000e-01, %44
%46 = load double, double* @M_PI
%47 = fmul double %45, %46
%48 = load double, double* %5
%49 = fmul double %47, %48
%50 = load double, double* %5
%51 = fsub double 1.000000e+00, %50
%52 = fdiv double %49, %51
store double %52, double* %7
%53 = load double, double* %7
%54 = load double, double* %4
%55 = fmul double %53, %54
%56 = load double, double* %4
%57 = fmul double %55, %56
%58 = call double @fexp(double %57)
store double %58, double* %3
br label %60
59: ; preds = %34
store double 0.000000e+00, double* %3
br label %60
60: ; preds = %59, %37, %17, %10
%61 = load double, double* %3
ret double %61
}

LLVM IR (-O2):
@M_PI = global double 0.000000e+00
define double @cosineh(double %0, double %1) {
%3 = fcmp olt double %1, 1.000000e-10
br i1 %3, label %4, label %7
4: ; preds = %2
%5 = tail call double @cosine(double %0)
%6 = tail call double @llvm.fmuladd.f64(double %5, double 5.000000e-01, double 5.000000e-01)
br label %37
7: ; preds = %2
%8 = fcmp olt double %1, 0x3FEFAE147AE147AE
br i1 %8, label %9, label %21
9: ; preds = %7
%10 = fsub double 1.000000e+00, %1
%11 = fdiv double %1, %10
%12 = fmul double %0, 5.000000e-01
%13 = tail call double @cosine(double %12)
%14 = fmul double %11, %13
%15 = tail call i32 @cosh(double %14)
%16 = add nsw i32 %15, -1
%17 = tail call i32 @cosh(double %11)
%18 = add nsw i32 %17, -1
%19 = sdiv i32 %16, %18
%20 = sitofp i32 %19 to double
br label %37
21: ; preds = %7
%22 = fcmp olt double %1, 1.000000e+00
br i1 %22, label %23, label %37
23: ; preds = %21
%24 = fadd double %0, 5.000000e-01
%25 = tail call i64 @floor(double %24)
%26 = sitofp i64 %25 to double
%27 = fsub double %0, %26
%28 = load double, double* @M_PI
%29 = fmul double %28, -5.000000e-01
%30 = fmul double %28, %29
%31 = fmul double %30, %1
%32 = fsub double 1.000000e+00, %1
%33 = fdiv double %31, %32
%34 = fmul double %27, %33
%35 = fmul double %27, %34
%36 = tail call double @fexp(double %35)
br label %37
37: ; preds = %21, %23, %9, %4
%38 = phi double [ %6, %4 ], [ %20, %9 ], [ %36, %23 ], [ 0.000000e+00, %21 ]
ret double %38
}