#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 atan(double);
double atan2(double y, double x) {
  if (y == 0.0) {
    if (x >= 0.0) {
      return 0.0;
    } else {
      return 3.14159265358979323846;
    }
  } else if (y > 0.0) {
    if (x == 0.0) {
      return 1.57079632679489661923;
    } else if (x > 0.0) {
      return atan(y / x);
    } else {
      return 3.14159265358979323846 - atan(y / x);
    }
  } else {
    if (x == 0.0) {
      return 3.14159265358979323846 + 1.57079632679489661923;
    } else if (x > 0.0) {
      return 2 * 3.14159265358979323846 - atan(y / x);
    } else {
      return 3.14159265358979323846 + atan(y / x);
    }
  }
}


x86 assembly (clang, -O0):
<atan2>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    116b <atan2+0x5b>
jp     116b <atan2+0x5b>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     1159 <atan2+0x49>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <atan2+0x171>
movsd  0xe9f(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <atan2+0x171>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    11fa <atan2+0xea>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11a7 <atan2+0x97>
jp     11a7 <atan2+0x97>
movsd  0xe7b(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <atan2+0x171>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    11d2 <atan2+0xc2>
movsd  -0x10(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <atan@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <atan2+0x171>
movsd  -0x10(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <atan@plt>
movaps %xmm0,%xmm1
movsd  0xe14(%rip),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <atan2+0x171>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1224 <atan2+0x114>
jp     1224 <atan2+0x114>
movsd  0xdf6(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <atan2+0x171>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    125e <atan2+0x14e>
movsd  -0x10(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <atan@plt>
movaps %xmm0,%xmm1
movsd  0xdb8(%rip),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <atan2+0x171>
movsd  -0x10(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <atan@plt>
movaps %xmm0,%xmm1
movsd  0xd88(%rip),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<atan2>:
push   %rax
xorpd  %xmm2,%xmm2
ucomisd %xmm2,%xmm0
jne    1130 <atan2+0x20>
jp     1130 <atan2+0x20>
cmpnlesd %xmm1,%xmm2
movsd  0xede(%rip),%xmm0
andpd  %xmm2,%xmm0
pop    %rax
ret
xorpd  %xmm2,%xmm2
jbe    1148 <atan2+0x38>
ucomisd %xmm2,%xmm1
jne    115a <atan2+0x4a>
jp     115a <atan2+0x4a>
movsd  0xed2(%rip),%xmm0
pop    %rax
ret
ucomisd %xmm2,%xmm1
jne    1185 <atan2+0x75>
jp     1185 <atan2+0x75>
movsd  0xea8(%rip),%xmm0
pop    %rax
ret
divsd  %xmm1,%xmm0
movsd  %xmm1,(%rsp)
call   1030 <atan@plt>
movsd  (%rsp),%xmm1
ucomisd 0xeab(%rip),%xmm1
ja     11c0 <atan2+0xb0>
movsd  0xe89(%rip),%xmm1
subsd  %xmm0,%xmm1
jmp    11bc <atan2+0xac>
divsd  %xmm1,%xmm0
movsd  %xmm1,(%rsp)
call   1030 <atan@plt>
movapd %xmm0,%xmm1
movsd  (%rsp),%xmm0
ucomisd 0xe7c(%rip),%xmm0
jbe    11b4 <atan2+0xa4>
movsd  0xe62(%rip),%xmm0
subsd  %xmm1,%xmm0
pop    %rax
ret
addsd  0xe4c(%rip),%xmm1
movapd %xmm1,%xmm0
pop    %rax
ret

LLVM IR (-O0):
define double @atan2(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
store double %0, double* %4
store double %1, double* %5
%6 = load double, double* %4
%7 = fcmp oeq double %6, 0.000000e+00
br i1 %7, label %8, label %13
8: ; preds = %2
%9 = load double, double* %5
%10 = fcmp oge double %9, 0.000000e+00
br i1 %10, label %11, label %12
11: ; preds = %8
store double 0.000000e+00, double* %3
br label %53
12: ; preds = %8
store double 0x400921FB54442D18, double* %3
br label %53
13: ; preds = %2
%14 = load double, double* %4
%15 = fcmp ogt double %14, 0.000000e+00
br i1 %15, label %16, label %34
16: ; preds = %13
%17 = load double, double* %5
%18 = fcmp oeq double %17, 0.000000e+00
br i1 %18, label %19, label %20
19: ; preds = %16
store double 0x3FF921FB54442D18, double* %3
br label %53
20: ; preds = %16
%21 = load double, double* %5
%22 = fcmp ogt double %21, 0.000000e+00
br i1 %22, label %23, label %28
23: ; preds = %20
%24 = load double, double* %4
%25 = load double, double* %5
%26 = fdiv double %24, %25
%27 = call double @atan(double %26)
store double %27, double* %3
br label %53
28: ; preds = %20
%29 = load double, double* %4
%30 = load double, double* %5
%31 = fdiv double %29, %30
%32 = call double @atan(double %31)
%33 = fsub double 0x400921FB54442D18, %32
store double %33, double* %3
br label %53
34: ; preds = %13
%35 = load double, double* %5
%36 = fcmp oeq double %35, 0.000000e+00
br i1 %36, label %37, label %38
37: ; preds = %34
store double 0x4012D97C7F3321D2, double* %3
br label %53
38: ; preds = %34
%39 = load double, double* %5
%40 = fcmp ogt double %39, 0.000000e+00
br i1 %40, label %41, label %47
41: ; preds = %38
%42 = load double, double* %4
%43 = load double, double* %5
%44 = fdiv double %42, %43
%45 = call double @atan(double %44)
%46 = fsub double 0x401921FB54442D18, %45
store double %46, double* %3
br label %53
47: ; preds = %38
%48 = load double, double* %4
%49 = load double, double* %5
%50 = fdiv double %48, %49
%51 = call double @atan(double %50)
%52 = fadd double 0x400921FB54442D18, %51
store double %52, double* %3
br label %53
53: ; preds = %47, %41, %37, %28, %23, %19, %12, %11
%54 = load double, double* %3
ret double %54
}

LLVM IR (-O2):
define double @atan2(double %0, double %1) {
%3 = fcmp oeq double %0, 0.000000e+00
br i1 %3, label %4, label %7
4: ; preds = %2
%5 = fcmp ult double %1, 0.000000e+00
%6 = select i1 %5, double 0x400921FB54442D18, double 0.000000e+00
br label %26
7: ; preds = %2
%8 = fcmp ogt double %0, 0.000000e+00
%9 = fcmp oeq double %1, 0.000000e+00
br i1 %8, label %10, label %17
10: ; preds = %7
br i1 %9, label %26, label %11
11: ; preds = %10
%12 = fcmp ogt double %1, 0.000000e+00
%13 = fdiv double %0, %1
%14 = tail call double @atan(double %13)
br i1 %12, label %26, label %15
15: ; preds = %11
%16 = fsub double 0x400921FB54442D18, %14
br label %26
17: ; preds = %7
br i1 %9, label %26, label %18
18: ; preds = %17
%19 = fcmp ogt double %1, 0.000000e+00
%20 = fdiv double %0, %1
%21 = tail call double @atan(double %20)
br i1 %19, label %22, label %24
22: ; preds = %18
%23 = fsub double 0x401921FB54442D18, %21
br label %26
24: ; preds = %18
%25 = fadd double %21, 0x400921FB54442D18
br label %26
26: ; preds = %11, %17, %10, %4, %24, %22, %15
%27 = phi double [ %16, %15 ], [ %23, %22 ], [ %25, %24 ], [ %6, %4 ], [ 0x3FF921FB54442D18, %10 ], [ 0x4012D97C7F3321D2, %17 ], [ %14, %11 ]
ret double %27
}