#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 */
typedef int /*<<< orphan*/ uint8_t;

/* Variables and functions */
float ct_fast_cos_impl(float);
float fmodf(float, float);
float ct_fast_cos(float x) {
  x = fmodf(x, (2.0f * 3.1415926535897932384626433832795029f));
  if (x < 0) {
    x = -x;
  }
  switch (
      (uint8_t)(x * (1.0f / (0.5f * 3.1415926535897932384626433832795029f)))) {
  case 0:
    return ct_fast_cos_impl(x);
  case 1:
    return -ct_fast_cos_impl(3.1415926535897932384626433832795029f - x);
  case 2:
    return -ct_fast_cos_impl(x - 3.1415926535897932384626433832795029f);
  default:
    return ct_fast_cos_impl((2.0f * 3.1415926535897932384626433832795029f) - x);
  }
}


x86 assembly (clang, -O0):
<ct_fast_cos>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
movss  0xec6(%rip),%xmm1
call   1040 <fmodf@plt>
movss  %xmm0,-0x8(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0x8(%rbp),%xmm0
jbe    1168 <ct_fast_cos+0x48>
movss  -0x8(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
movss  0xe8f(%rip),%xmm1
mulss  %xmm1,%xmm0
cvttss2si %xmm0,%eax
mov    %eax,-0xc(%rbp)
test   %eax,%eax
je     11af <ct_fast_cos+0x8f>
jmp    118d <ct_fast_cos+0x6d>
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
je     11c3 <ct_fast_cos+0xa3>
jmp    119e <ct_fast_cos+0x7e>
mov    -0xc(%rbp),%eax
sub    $0x2,%eax
je     11ec <ct_fast_cos+0xcc>
jmp    1219 <ct_fast_cos+0xf9>
movss  -0x8(%rbp),%xmm0
call   1030 <ct_fast_cos_impl@plt>
movss  %xmm0,-0x4(%rbp)
jmp    1230 <ct_fast_cos+0x110>
movss  0xe3d(%rip),%xmm0
subss  -0x8(%rbp),%xmm0
call   1030 <ct_fast_cos_impl@plt>
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1230 <ct_fast_cos+0x110>
movss  -0x8(%rbp),%xmm0
movss  0xe0f(%rip),%xmm1
subss  %xmm1,%xmm0
call   1030 <ct_fast_cos_impl@plt>
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1230 <ct_fast_cos+0x110>
movss  0xddf(%rip),%xmm0
subss  -0x8(%rbp),%xmm0
call   1030 <ct_fast_cos_impl@plt>
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ct_fast_cos>:
push   %rax
movss  0xed7(%rip),%xmm1
call   1040 <fmodf@plt>
movaps %xmm0,%xmm1
movaps 0xed8(%rip),%xmm2
xorps  %xmm0,%xmm2
xorps  %xmm3,%xmm3
cmpltss %xmm3,%xmm0
andps  %xmm0,%xmm2
andnps %xmm1,%xmm0
orps   %xmm2,%xmm0
movaps %xmm0,%xmm1
mulss  0xead(%rip),%xmm1
cvttss2si %xmm1,%eax
cmp    $0x2,%eax
je     116f <ct_fast_cos+0x4f>
cmp    $0x1,%eax
je     117d <ct_fast_cos+0x5d>
test   %eax,%eax
jne    119a <ct_fast_cos+0x7a>
pop    %rax
jmp    1030 <ct_fast_cos_impl@plt>
movss  0xe91(%rip),%xmm1
addss  %xmm0,%xmm1
jmp    1189 <ct_fast_cos+0x69>
movss  0xe87(%rip),%xmm1
subss  %xmm0,%xmm1
movaps %xmm1,%xmm0
call   1030 <ct_fast_cos_impl@plt>
xorps  0xe78(%rip),%xmm0
pop    %rax
ret
movss  0xe5e(%rip),%xmm1
subss  %xmm0,%xmm1
movaps %xmm1,%xmm0
pop    %rax
jmp    1030 <ct_fast_cos_impl@plt>

LLVM IR (-O0):
define float @ct_fast_cos(float %0) {
%2 = alloca float
%3 = alloca float
store float %0, float* %3
%4 = load float, float* %3
%5 = call float @fmodf(float %4, float 0x401921FB60000000)
store float %5, float* %3
%6 = load float, float* %3
%7 = fcmp olt float %6, 0.000000e+00
br i1 %7, label %8, label %11
8: ; preds = %1
%9 = load float, float* %3
%10 = fneg float %9
store float %10, float* %3
br label %11
11: ; preds = %8, %1
%12 = load float, float* %3
%13 = fmul float %12, 0x3FE45F3060000000
%14 = fptosi float %13 to i32
switch i32 %14, label %28 [
i32 0, label %15
i32 1, label %18
i32 2, label %23
]
15: ; preds = %11
%16 = load float, float* %3
%17 = call float @ct_fast_cos_impl(float %16)
store float %17, float* %2
br label %32
18: ; preds = %11
%19 = load float, float* %3
%20 = fsub float 0x400921FB60000000, %19
%21 = call float @ct_fast_cos_impl(float %20)
%22 = fneg float %21
store float %22, float* %2
br label %32
23: ; preds = %11
%24 = load float, float* %3
%25 = fsub float %24, 0x400921FB60000000
%26 = call float @ct_fast_cos_impl(float %25)
%27 = fneg float %26
store float %27, float* %2
br label %32
28: ; preds = %11
%29 = load float, float* %3
%30 = fsub float 0x401921FB60000000, %29
%31 = call float @ct_fast_cos_impl(float %30)
store float %31, float* %2
br label %32
32: ; preds = %28, %23, %18, %15
%33 = load float, float* %2
ret float %33
}

LLVM IR (-O2):
define float @ct_fast_cos(float %0) {
%2 = tail call float @fmodf(float %0, float 0x401921FB60000000)
%3 = fcmp olt float %2, 0.000000e+00
%4 = fneg float %2
%5 = select i1 %3, float %4, float %2
%6 = fmul float %5, 0x3FE45F3060000000
%7 = fptosi float %6 to i32
switch i32 %7, label %18 [
i32 0, label %8
i32 1, label %10
i32 2, label %14
]
8: ; preds = %1
%9 = tail call float @ct_fast_cos_impl(float %5)
br label %21
10: ; preds = %1
%11 = fsub float 0x400921FB60000000, %5
%12 = tail call float @ct_fast_cos_impl(float %11)
%13 = fneg float %12
br label %21
14: ; preds = %1
%15 = fadd float %5, 0xC00921FB60000000
%16 = tail call float @ct_fast_cos_impl(float %15)
%17 = fneg float %16
br label %21
18: ; preds = %1
%19 = fsub float 0x401921FB60000000, %5
%20 = tail call float @ct_fast_cos_impl(float %19)
br label %21
21: ; preds = %18, %14, %10, %8
%22 = phi float [ %20, %18 ], [ %17, %14 ], [ %13, %10 ], [ %9, %8 ]
ret float %22
}