#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 egSinZH(float);
int fmodf(float, double);
float egSin(float a) {
  short even = (short)(a * 0.63661977236758134307553505349006) % 2,
        negate = (short)(a * 0.31830988618379067153776752674503) % 2;
  a = (even == 0) ? fmodf(a, 3.14159265358979323846 * 0.5)
                  : 1 - fmodf(a, 3.14159265358979323846 * 0.5);
  return (negate) ? egSinZH(a) * -1 : egSinZH(a);
}


x86 assembly (clang, -O0):
<egSin>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xec2(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
cwtl
mov    %eax,%edx
shr    $0x1f,%edx
mov    %eax,%ecx
add    %edx,%ecx
and    $0xfffe,%ecx
sub    %ecx,%eax
mov    %ax,-0x6(%rbp)
movss  -0x4(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe9b(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
cwtl
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %dx,%ax
mov    %ax,-0x8(%rbp)
movswl -0x6(%rbp),%eax
cmp    $0x0,%eax
jne    11ac <egSin+0x8c>
movss  -0x4(%rbp),%xmm0
movsd  0xe71(%rip),%xmm1
call   1030 <fmodf@plt>
mov    %eax,-0xc(%rbp)
jmp    11ca <egSin+0xaa>
movss  -0x4(%rbp),%xmm0
movsd  0xe57(%rip),%xmm1
call   1030 <fmodf@plt>
mov    %eax,%ecx
mov    $0x1,%eax
sub    %ecx,%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x4(%rbp)
movswl -0x8(%rbp),%eax
cmp    $0x0,%eax
je     1203 <egSin+0xe3>
movss  -0x4(%rbp),%xmm0
call   1040 <egSinZH@plt>
movss  0xe23(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x10(%rbp)
jmp    1212 <egSin+0xf2>
movss  -0x4(%rbp),%xmm0
call   1040 <egSinZH@plt>
movss  %xmm0,-0x10(%rbp)
movss  -0x10(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<egSin>:
push   %rbx
sub    $0x10,%rsp
cvtss2sd %xmm0,%xmm1
movlhps %xmm1,%xmm1
mulpd  0xecc(%rip),%xmm1
cvttpd2dq %xmm1,%xmm1
pshuflw $0xe8,%xmm1,%xmm1
movdqa %xmm1,(%rsp)
movq   0xee6(%rip),%xmm1
call   1030 <fmodf@plt>
mov    $0x1,%ecx
sub    %eax,%ecx
movdqa (%rsp),%xmm0
pand   0xead(%rip),%xmm0
pshuflw $0x60,%xmm0,%xmm0
pshufd $0x50,%xmm0,%xmm0
pxor   %xmm1,%xmm1
pcmpeqw %xmm0,%xmm1
movmskpd %xmm1,%ebx
test   $0x2,%bl
cmovne %eax,%ecx
xorps  %xmm0,%xmm0
cvtsi2ss %ecx,%xmm0
call   1040 <egSinZH@plt>
test   $0x1,%bl
jne    1197 <egSin+0x77>
xorps  0xe89(%rip),%xmm0
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define float @egSin(float %0) {
%2 = alloca float
%3 = alloca i16
%4 = alloca i16
store float %0, float* %2
%5 = load float, float* %2
%6 = fpext float %5 to double
%7 = fmul double %6, 0x3FE45F306DC9C883
%8 = fptosi double %7 to i16
%9 = sext i16 %8 to i32
%10 = srem i32 %9, 2
%11 = trunc i32 %10 to i16
store i16 %11, i16* %3
%12 = load float, float* %2
%13 = fpext float %12 to double
%14 = fmul double %13, 0x3FD45F306DC9C883
%15 = fptosi double %14 to i16
%16 = sext i16 %15 to i32
%17 = srem i32 %16, 2
%18 = trunc i32 %17 to i16
store i16 %18, i16* %4
%19 = load i16, i16* %3
%20 = sext i16 %19 to i32
%21 = icmp eq i32 %20, 0
br i1 %21, label %22, label %25
22: ; preds = %1
%23 = load float, float* %2
%24 = call i32 @fmodf(float %23, double 0x3FF921FB54442D18)
br label %29
25: ; preds = %1
%26 = load float, float* %2
%27 = call i32 @fmodf(float %26, double 0x3FF921FB54442D18)
%28 = sub nsw i32 1, %27
br label %29
29: ; preds = %25, %22
%30 = phi i32 [ %24, %22 ], [ %28, %25 ]
%31 = sitofp i32 %30 to float
store float %31, float* %2
%32 = load i16, i16* %4
%33 = sext i16 %32 to i32
%34 = icmp ne i32 %33, 0
br i1 %34, label %35, label %39
35: ; preds = %29
%36 = load float, float* %2
%37 = call float @egSinZH(float %36)
%38 = fmul float %37, -1.000000e+00
br label %42
39: ; preds = %29
%40 = load float, float* %2
%41 = call float @egSinZH(float %40)
br label %42
42: ; preds = %39, %35
%43 = phi float [ %38, %35 ], [ %41, %39 ]
ret float %43
}

LLVM IR (-O2):
define float @egSin(float %0) {
%2 = fpext float %0 to double
%3 = insertelement <2 x double> poison, double %2, i64 0
%4 = shufflevector <2 x double> %3, <2 x double> poison, <2 x i32> zeroinitializer
%5 = fmul <2 x double> %4, <double 0x3FD45F306DC9C883, double 0x3FE45F306DC9C883>
%6 = fptosi <2 x double> %5 to <2 x i16>
%7 = tail call i32 @fmodf(float %0, double 0x3FF921FB54442D18)
%8 = sub nsw i32 1, %7
%9 = and <2 x i16> %6, <i16 1, i16 1>
%10 = icmp eq <2 x i16> %9, zeroinitializer
%11 = extractelement <2 x i1> %10, i64 1
%12 = select i1 %11, i32 %7, i32 %8
%13 = sitofp i32 %12 to float
%14 = tail call float @egSinZH(float %13)
%15 = fneg float %14
%16 = extractelement <2 x i1> %10, i64 0
%17 = select i1 %16, float %14, float %15
ret float %17
}