#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 fast_atan(float);
float fa_fast_atan2(float y, float x) {
  float sita;
  float abs_y, abs_x;
  abs_y = ((y) > 0 ? (y) : (-(y)));
  abs_x = ((x) > 0 ? (x) : (-(x)));
  if (abs_y >= abs_x) {
    if (y > 0)
      sita = 1.57079632679489661923 - fast_atan(x / y);
    else
      sita = 1.57079632679489661923 - fast_atan(x / y) - 3.14159265358979323846;
  } else {
    if (x > 0)
      sita = fast_atan(y / x);
    else
      sita = fast_atan(y / x) - 3.14159265358979323846;
  }
  return sita;
}


x86 assembly (clang, -O0):
<fa_fast_atan2>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movss  %xmm0,-0x4(%rbp)
movss  %xmm1,-0x8(%rbp)
movss  -0x4(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jbe    1142 <fa_fast_atan2+0x32>
movss  -0x4(%rbp),%xmm0
movss  %xmm0,-0x18(%rbp)
jmp    1159 <fa_fast_atan2+0x49>
movss  -0x4(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x18(%rbp)
movss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x10(%rbp)
movss  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jbe    1183 <fa_fast_atan2+0x73>
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x1c(%rbp)
jmp    119a <fa_fast_atan2+0x8a>
movss  -0x8(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x14(%rbp)
movss  -0x10(%rbp),%xmm0
ucomiss -0x14(%rbp),%xmm0
jb     1228 <fa_fast_atan2+0x118>
movss  -0x4(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jbe    11f0 <fa_fast_atan2+0xe0>
movss  -0x8(%rbp),%xmm0
divss  -0x4(%rbp),%xmm0
call   1030 <fast_atan@plt>
movaps %xmm0,%xmm1
movsd  0xe2a(%rip),%xmm0
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0xc(%rbp)
jmp    1223 <fa_fast_atan2+0x113>
movss  -0x8(%rbp),%xmm0
divss  -0x4(%rbp),%xmm0
call   1030 <fast_atan@plt>
movaps %xmm0,%xmm1
movsd  0xdfe(%rip),%xmm0
subsd  %xmm1,%xmm0
movsd  0xdea(%rip),%xmm1
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0xc(%rbp)
jmp    127f <fa_fast_atan2+0x16f>
movss  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jbe    1256 <fa_fast_atan2+0x146>
movss  -0x4(%rbp),%xmm0
divss  -0x8(%rbp),%xmm0
call   1030 <fast_atan@plt>
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0xc(%rbp)
jmp    127a <fa_fast_atan2+0x16a>
movss  -0x4(%rbp),%xmm0
divss  -0x8(%rbp),%xmm0
call   1030 <fast_atan@plt>
movsd  0xd93(%rip),%xmm1
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0xc(%rbp)
jmp    127f <fa_fast_atan2+0x16f>
movss  -0xc(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fa_fast_atan2>:
sub    $0x18,%rsp
movaps %xmm0,%xmm5
movaps 0xee2(%rip),%xmm0
movaps %xmm5,%xmm4
xorps  %xmm0,%xmm4
xorps  %xmm2,%xmm2
cmpltss %xmm5,%xmm2
movaps %xmm2,%xmm3
andnps %xmm4,%xmm3
andps  %xmm5,%xmm2
orps   %xmm3,%xmm2
xorps  %xmm1,%xmm0
xorps  %xmm4,%xmm4
cmpltss %xmm1,%xmm4
movaps %xmm4,%xmm3
andnps %xmm0,%xmm3
andps  %xmm1,%xmm4
orps   %xmm3,%xmm4
ucomiss %xmm4,%xmm2
jae    1182 <fa_fast_atan2+0x72>
divss  %xmm1,%xmm5
movaps %xmm5,%xmm0
movaps %xmm1,(%rsp)
call   1030 <fast_atan@plt>
movaps (%rsp),%xmm1
ucomiss 0xeb1(%rip),%xmm1
ja     1179 <fa_fast_atan2+0x69>
addsd  0xe9f(%rip),%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x18,%rsp
ret
divss  %xmm5,%xmm1
movaps %xmm1,%xmm0
movaps %xmm5,(%rsp)
call   1030 <fast_atan@plt>
movaps %xmm0,%xmm1
movaps (%rsp),%xmm0
ucomiss 0xe80(%rip),%xmm0
movsd  0xe68(%rip),%xmm0
subsd  %xmm1,%xmm0
jbe    1171 <fa_fast_atan2+0x61>
jmp    1179 <fa_fast_atan2+0x69>

LLVM IR (-O0):
define float @fa_fast_atan2(float %0, float %1) {
%3 = alloca float
%4 = alloca float
%5 = alloca float
%6 = alloca float
%7 = alloca float
store float %0, float* %3
store float %1, float* %4
%8 = load float, float* %3
%9 = fcmp ogt float %8, 0.000000e+00
br i1 %9, label %10, label %12
10: ; preds = %2
%11 = load float, float* %3
br label %15
12: ; preds = %2
%13 = load float, float* %3
%14 = fneg float %13
br label %15
15: ; preds = %12, %10
%16 = phi float [ %11, %10 ], [ %14, %12 ]
store float %16, float* %6
%17 = load float, float* %4
%18 = fcmp ogt float %17, 0.000000e+00
br i1 %18, label %19, label %21
19: ; preds = %15
%20 = load float, float* %4
br label %24
21: ; preds = %15
%22 = load float, float* %4
%23 = fneg float %22
br label %24
24: ; preds = %21, %19
%25 = phi float [ %20, %19 ], [ %23, %21 ]
store float %25, float* %7
%26 = load float, float* %6
%27 = load float, float* %7
%28 = fcmp oge float %26, %27
br i1 %28, label %29, label %48
29: ; preds = %24
%30 = load float, float* %3
%31 = fcmp ogt float %30, 0.000000e+00
br i1 %31, label %32, label %39
32: ; preds = %29
%33 = load float, float* %4
%34 = load float, float* %3
%35 = fdiv float %33, %34
%36 = call double @fast_atan(float %35)
%37 = fsub double 0x3FF921FB54442D18, %36
%38 = fptrunc double %37 to float
store float %38, float* %5
br label %47
39: ; preds = %29
%40 = load float, float* %4
%41 = load float, float* %3
%42 = fdiv float %40, %41
%43 = call double @fast_atan(float %42)
%44 = fsub double 0x3FF921FB54442D18, %43
%45 = fsub double %44, 0x400921FB54442D18
%46 = fptrunc double %45 to float
store float %46, float* %5
br label %47
47: ; preds = %39, %32
br label %65
48: ; preds = %24
%49 = load float, float* %4
%50 = fcmp ogt float %49, 0.000000e+00
br i1 %50, label %51, label %57
51: ; preds = %48
%52 = load float, float* %3
%53 = load float, float* %4
%54 = fdiv float %52, %53
%55 = call double @fast_atan(float %54)
%56 = fptrunc double %55 to float
store float %56, float* %5
br label %64
57: ; preds = %48
%58 = load float, float* %3
%59 = load float, float* %4
%60 = fdiv float %58, %59
%61 = call double @fast_atan(float %60)
%62 = fsub double %61, 0x400921FB54442D18
%63 = fptrunc double %62 to float
store float %63, float* %5
br label %64
64: ; preds = %57, %51
br label %65
65: ; preds = %64, %47
%66 = load float, float* %5
ret float %66
}

LLVM IR (-O2):
define float @fa_fast_atan2(float %0, float %1) {
%3 = fcmp ogt float %0, 0.000000e+00
%4 = fneg float %0
%5 = select i1 %3, float %0, float %4
%6 = fcmp ogt float %1, 0.000000e+00
%7 = fneg float %1
%8 = select i1 %6, float %1, float %7
%9 = fcmp ult float %5, %8
br i1 %9, label %16, label %10
10: ; preds = %2
%11 = fdiv float %1, %0
%12 = tail call double @fast_atan(float %11)
%13 = fsub double 0x3FF921FB54442D18, %12
br i1 %3, label %21, label %14
14: ; preds = %10
%15 = fadd double %13, 0xC00921FB54442D18
br label %21
16: ; preds = %2
%17 = fdiv float %0, %1
%18 = tail call double @fast_atan(float %17)
br i1 %6, label %21, label %19
19: ; preds = %16
%20 = fadd double %18, 0xC00921FB54442D18
br label %21
21: ; preds = %16, %10, %19, %14
%22 = phi double [ %15, %14 ], [ %20, %19 ], [ %13, %10 ], [ %18, %16 ]
%23 = fptrunc double %22 to float
ret float %23
}