#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 */
scalar_t__ M_PI;
float fabsf(float);
float kernel_cos(float, int);
float kernel_sin(float, int);
float reduction_2pi(float);
float mysin(float a) {
  int flag = (a < 0.0) ? 1 : 0;
  a = fabsf(a);
  a = reduction_2pi(a);
  if (a >= (float)M_PI) {
    a -= (float)M_PI;
    flag ^= 1;
  }
  if (a >= (float)M_PI / 2.0f)
    a = (float)M_PI - a;
  if (a <= (float)M_PI / 4.0f) {
    return kernel_sin(a, flag);
  } else {
    a = (float)M_PI / 2.0f - a;
    return kernel_cos(a, flag);
  }
}


x86 assembly (clang, -O0):
<mysin>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
xorps  %xmm0,%xmm0
xor    %eax,%eax
mov    $0x1,%ecx
ucomisd %xmm1,%xmm0
cmova  %ecx,%eax
mov    %eax,-0xc(%rbp)
movss  -0x8(%rbp),%xmm0
movaps 0xe9a(%rip),%xmm1
pand   %xmm1,%xmm0
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
call   1050 <reduction_2pi@plt>
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
mov    0x2e5e(%rip),%rax
cvtsi2ssq (%rax),%xmm1
ucomiss %xmm1,%xmm0
jb     11bb <mysin+0x8b>
mov    0x2e49(%rip),%rax
cvtsi2ssq (%rax),%xmm1
movss  -0x8(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,-0x8(%rbp)
mov    -0xc(%rbp),%eax
xor    $0x1,%eax
mov    %eax,-0xc(%rbp)
movss  -0x8(%rbp),%xmm0
mov    0x2e21(%rip),%rax
cvtsi2ssq (%rax),%xmm1
movss  0xe3c(%rip),%xmm2
divss  %xmm2,%xmm1
ucomiss %xmm1,%xmm0
jb     11f7 <mysin+0xc7>
mov    0x2e00(%rip),%rax
cvtsi2ssq (%rax),%xmm0
subss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm1
mov    0x2de5(%rip),%rax
cvtsi2ssq (%rax),%xmm0
movss  0xe04(%rip),%xmm2
divss  %xmm2,%xmm0
ucomiss %xmm1,%xmm0
jb     1234 <mysin+0x104>
movss  -0x8(%rbp),%xmm0
mov    -0xc(%rbp),%edi
call   1030 <kernel_sin@plt>
movss  %xmm0,-0x4(%rbp)
jmp    1268 <mysin+0x138>
mov    0x2dad(%rip),%rax
cvtsi2ssq (%rax),%xmm0
movss  0xdc8(%rip),%xmm1
divss  %xmm1,%xmm0
subss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
mov    -0xc(%rbp),%edi
call   1040 <kernel_cos@plt>
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mysin>:
push   %rbx
xorps  %xmm1,%xmm1
ucomiss %xmm0,%xmm1
setbe  %bl
andps  0xebf(%rip),%xmm0
call   1050 <reduction_2pi@plt>
xorps  %xmm1,%xmm1
mov    0x2e98(%rip),%rax
cvtsi2ssq (%rax),%xmm3
ucomiss %xmm3,%xmm0
setb   %al
jb     1160 <mysin+0x30>
movaps %xmm3,%xmm1
subss  %xmm1,%xmm0
xor    %al,%bl
movzbl %bl,%edi
movss  0xe9f(%rip),%xmm1
mulss  %xmm3,%xmm1
movaps %xmm3,%xmm4
subss  %xmm0,%xmm4
movaps %xmm1,%xmm2
cmpnless %xmm0,%xmm2
andps  %xmm2,%xmm0
andnps %xmm4,%xmm2
orps   %xmm0,%xmm2
mulss  0xe7f(%rip),%xmm3
ucomiss %xmm2,%xmm3
jae    11a7 <mysin+0x77>
subss  %xmm2,%xmm1
movaps %xmm1,%xmm0
pop    %rbx
jmp    1040 <kernel_cos@plt>
movaps %xmm2,%xmm0
pop    %rbx
jmp    1030 <kernel_sin@plt>

LLVM IR (-O0):
@M_PI = global i64 0
define float @mysin(float %0) {
%2 = alloca float
%3 = alloca float
%4 = alloca i32
store float %0, float* %3
%5 = load float, float* %3
%6 = fpext float %5 to double
%7 = fcmp olt double %6, 0.000000e+00
%8 = zext i1 %7 to i64
%9 = select i1 %7, i32 1, i32 0
store i32 %9, i32* %4
%10 = load float, float* %3
%11 = call float @llvm.fabs.f32(float %10)
store float %11, float* %3
%12 = load float, float* %3
%13 = call float @reduction_2pi(float %12)
store float %13, float* %3
%14 = load float, float* %3
%15 = load i64, i64* @M_PI
%16 = sitofp i64 %15 to float
%17 = fcmp oge float %14, %16
br i1 %17, label %18, label %25
18: ; preds = %1
%19 = load i64, i64* @M_PI
%20 = sitofp i64 %19 to float
%21 = load float, float* %3
%22 = fsub float %21, %20
store float %22, float* %3
%23 = load i32, i32* %4
%24 = xor i32 %23, 1
store i32 %24, i32* %4
br label %25
25: ; preds = %18, %1
%26 = load float, float* %3
%27 = load i64, i64* @M_PI
%28 = sitofp i64 %27 to float
%29 = fdiv float %28, 2.000000e+00
%30 = fcmp oge float %26, %29
br i1 %30, label %31, label %36
31: ; preds = %25
%32 = load i64, i64* @M_PI
%33 = sitofp i64 %32 to float
%34 = load float, float* %3
%35 = fsub float %33, %34
store float %35, float* %3
br label %36
36: ; preds = %31, %25
%37 = load float, float* %3
%38 = load i64, i64* @M_PI
%39 = sitofp i64 %38 to float
%40 = fdiv float %39, 4.000000e+00
%41 = fcmp ole float %37, %40
br i1 %41, label %42, label %46
42: ; preds = %36
%43 = load float, float* %3
%44 = load i32, i32* %4
%45 = call float @kernel_sin(float %43, i32 %44)
store float %45, float* %2
br label %55
46: ; preds = %36
%47 = load i64, i64* @M_PI
%48 = sitofp i64 %47 to float
%49 = fdiv float %48, 2.000000e+00
%50 = load float, float* %3
%51 = fsub float %49, %50
store float %51, float* %3
%52 = load float, float* %3
%53 = load i32, i32* %4
%54 = call float @kernel_cos(float %52, i32 %53)
store float %54, float* %2
br label %55
55: ; preds = %46, %42
%56 = load float, float* %2
ret float %56
}

LLVM IR (-O2):
@M_PI = global i64 0
define float @mysin(float %0) {
%2 = fcmp uge float %0, 0.000000e+00
%3 = tail call float @llvm.fabs.f32(float %0)
%4 = tail call float @reduction_2pi(float %3)
%5 = load i64, i64* @M_PI
%6 = sitofp i64 %5 to float
%7 = fcmp ult float %4, %6
%8 = select i1 %7, float 0.000000e+00, float %6
%9 = fsub float %4, %8
%10 = xor i1 %2, %7
%11 = zext i1 %10 to i32
%12 = fmul float %6, 5.000000e-01
%13 = fcmp ult float %9, %12
%14 = fsub float %6, %9
%15 = select i1 %13, float %9, float %14
%16 = fmul float %6, 2.500000e-01
%17 = fcmp ugt float %15, %16
br i1 %17, label %20, label %18
18: ; preds = %1
%19 = tail call float @kernel_sin(float %15, i32 %11)
br label %23
20: ; preds = %1
%21 = fsub float %12, %15
%22 = tail call float @kernel_cos(float %21, i32 %11)
br label %23
23: ; preds = %20, %18
%24 = phi float [ %19, %18 ], [ %22, %20 ]
ret float %24
}