#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 fabs(double);
double nan(char *);
double atan2_oct(double y, double x) {
  double ay = fabs(y);
  double ax = fabs(x);
  double out;
  if (ax == 0)
    return (y > 0     ? 3.141592653589793238462643383279502 / 2
            : (y < 0) ? -3.141592653589793238462643383279502 / 2
                      : nan("1"));
  out = 0.25 * 3.141592653589793238462643383279502 *
        ((ax >= ay) ? (ay / ax) : (2 - ax / ay));
  if (x > 0) {
    if (y < 0)
      out *= -1;
  } else {
    if (y >= 0) {
      out = 3.141592653589793238462643383279502 - out;
    } else {
      out -= 3.141592653589793238462643383279502;
    }
  }
  return out;
}


x86 assembly (clang, -O0):
<atan2_oct>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
movaps 0xed2(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
movaps 0xebd(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11d2 <atan2_oct+0xc2>
jp     11d2 <atan2_oct+0xc2>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1188 <atan2_oct+0x78>
movsd  0xeba(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
jmp    11c3 <atan2_oct+0xb3>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    11a8 <atan2_oct+0x98>
movsd  0xe92(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    11b9 <atan2_oct+0xa9>
lea    0xe91(%rip),%rdi
call   1030 <nan@plt>
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12ac <atan2_oct+0x19c>
movsd  -0x28(%rbp),%xmm0
ucomisd -0x20(%rbp),%xmm0
jb     11f6 <atan2_oct+0xe6>
movsd  -0x20(%rbp),%xmm0
divsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
jmp    1211 <atan2_oct+0x101>
movsd  -0x28(%rbp),%xmm1
divsd  -0x20(%rbp),%xmm1
movsd  0xe08(%rip),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm1
movsd  0xdfa(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    125e <atan2_oct+0x14e>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1259 <atan2_oct+0x149>
movsd  0xdd9(%rip),%xmm0
mulsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    12a2 <atan2_oct+0x192>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     1287 <atan2_oct+0x177>
movsd  0xda8(%rip),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    129d <atan2_oct+0x18d>
movsd  -0x30(%rbp),%xmm0
movsd  0xd8c(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    12a2 <atan2_oct+0x192>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<atan2_oct>:
movapd %xmm0,%xmm2
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jne    112f <atan2_oct+0x1f>
jp     112f <atan2_oct+0x1f>
ucomisd %xmm0,%xmm2
jbe    115b <atan2_oct+0x4b>
movsd  0xf12(%rip),%xmm0
ret
movapd 0xec9(%rip),%xmm3
movapd %xmm2,%xmm0
andpd  %xmm3,%xmm0
andpd  %xmm1,%xmm3
ucomisd %xmm0,%xmm3
jae    116e <atan2_oct+0x5e>
divsd  %xmm0,%xmm3
movsd  0xecb(%rip),%xmm0
subsd  %xmm3,%xmm0
jmp    1172 <atan2_oct+0x62>
xorpd  %xmm0,%xmm0
ucomisd %xmm2,%xmm0
jbe    11a2 <atan2_oct+0x92>
movsd  0xedb(%rip),%xmm0
ret
divsd  %xmm3,%xmm0
mulsd  0xeae(%rip),%xmm0
xorpd  %xmm3,%xmm3
ucomisd %xmm3,%xmm1
jbe    1193 <atan2_oct+0x83>
ucomisd %xmm2,%xmm3
jbe    11a1 <atan2_oct+0x91>
xorpd  0xe7e(%rip),%xmm0
ret
ucomisd %xmm3,%xmm2
jae    11ae <atan2_oct+0x9e>
addsd  0xe97(%rip),%xmm0
ret
lea    0xea7(%rip),%rdi
jmp    1030 <nan@plt>
movsd  0xe7a(%rip),%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
@.str = [2 x i8] c"1\00"
define double @atan2_oct(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
store double %0, double* %4
store double %1, double* %5
%9 = load double, double* %4
%10 = call double @llvm.fabs.f64(double %9)
store double %10, double* %6
%11 = load double, double* %5
%12 = call double @llvm.fabs.f64(double %11)
store double %12, double* %7
%13 = load double, double* %7
%14 = fcmp oeq double %13, 0.000000e+00
br i1 %14, label %15, label %29
15: ; preds = %2
%16 = load double, double* %4
%17 = fcmp ogt double %16, 0.000000e+00
br i1 %17, label %18, label %19
18: ; preds = %15
br label %27
19: ; preds = %15
%20 = load double, double* %4
%21 = fcmp olt double %20, 0.000000e+00
br i1 %21, label %22, label %23
22: ; preds = %19
br label %25
23: ; preds = %19
%24 = call double @nan(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
br label %25
25: ; preds = %23, %22
%26 = phi double [ 0xBFF921FB54442D18, %22 ], [ %24, %23 ]
br label %27
27: ; preds = %25, %18
%28 = phi double [ 0x3FF921FB54442D18, %18 ], [ %26, %25 ]
store double %28, double* %3
br label %66
29: ; preds = %2
%30 = load double, double* %7
%31 = load double, double* %6
%32 = fcmp oge double %30, %31
br i1 %32, label %33, label %37
33: ; preds = %29
%34 = load double, double* %6
%35 = load double, double* %7
%36 = fdiv double %34, %35
br label %42
37: ; preds = %29
%38 = load double, double* %7
%39 = load double, double* %6
%40 = fdiv double %38, %39
%41 = fsub double 2.000000e+00, %40
br label %42
42: ; preds = %37, %33
%43 = phi double [ %36, %33 ], [ %41, %37 ]
%44 = fmul double 0x3FE921FB54442D18, %43
store double %44, double* %8
%45 = load double, double* %5
%46 = fcmp ogt double %45, 0.000000e+00
br i1 %46, label %47, label %54
47: ; preds = %42
%48 = load double, double* %4
%49 = fcmp olt double %48, 0.000000e+00
br i1 %49, label %50, label %53
50: ; preds = %47
%51 = load double, double* %8
%52 = fmul double %51, -1.000000e+00
store double %52, double* %8
br label %53
53: ; preds = %50, %47
br label %64
54: ; preds = %42
%55 = load double, double* %4
%56 = fcmp oge double %55, 0.000000e+00
br i1 %56, label %57, label %60
57: ; preds = %54
%58 = load double, double* %8
%59 = fsub double 0x400921FB54442D18, %58
store double %59, double* %8
br label %63
60: ; preds = %54
%61 = load double, double* %8
%62 = fsub double %61, 0x400921FB54442D18
store double %62, double* %8
br label %63
63: ; preds = %60, %57
br label %64
64: ; preds = %63, %53
%65 = load double, double* %8
store double %65, double* %3
br label %66
66: ; preds = %64, %27
%67 = load double, double* %3
ret double %67
}

LLVM IR (-O2):
@.str = [2 x i8] c"1\00"
define double @atan2_oct(double %0, double %1) {
%3 = tail call double @llvm.fabs.f64(double %0)
%4 = tail call double @llvm.fabs.f64(double %1)
%5 = fcmp oeq double %1, 0.000000e+00
br i1 %5, label %6, label %12
6: ; preds = %2
%7 = fcmp ogt double %0, 0.000000e+00
br i1 %7, label %33, label %8
8: ; preds = %6
%9 = fcmp olt double %0, 0.000000e+00
br i1 %9, label %33, label %10
10: ; preds = %8
%11 = tail call double @nan(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
br label %33
12: ; preds = %2
%13 = fcmp ult double %4, %3
br i1 %13, label %16, label %14
14: ; preds = %12
%15 = fdiv double %3, %4
br label %19
16: ; preds = %12
%17 = fdiv double %4, %3
%18 = fsub double 2.000000e+00, %17
br label %19
19: ; preds = %16, %14
%20 = phi double [ %15, %14 ], [ %18, %16 ]
%21 = fmul double %20, 0x3FE921FB54442D18
%22 = fcmp ogt double %1, 0.000000e+00
br i1 %22, label %23, label %27
23: ; preds = %19
%24 = fcmp olt double %0, 0.000000e+00
br i1 %24, label %25, label %33
25: ; preds = %23
%26 = fneg double %21
br label %33
27: ; preds = %19
%28 = fcmp ult double %0, 0.000000e+00
br i1 %28, label %31, label %29
29: ; preds = %27
%30 = fsub double 0x400921FB54442D18, %21
br label %33
31: ; preds = %27
%32 = fadd double %21, 0xC00921FB54442D18
br label %33
33: ; preds = %25, %23, %31, %29, %6, %8, %10
%34 = phi double [ 0x3FF921FB54442D18, %6 ], [ %11, %10 ], [ 0xBFF921FB54442D18, %8 ], [ %26, %25 ], [ %21, %23 ], [ %30, %29 ], [ %32, %31 ]
ret double %34
}