#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 */
int M_PI;
double const M_PI_2;
double acos(int);
double calcAngularDist(double const, double const, double const, double const);
int cos(double const);
double const fabs(double const);
int sin(double const);
double calcGreatCircleRoute(const double lat1, const double lon1,
                            const double lat2, const double lon2, double *d) {
  *d = calcAngularDist(lat1, lon1, lat2, lon2);
  if (lat1 + lat2 == 0 && fabs(lon1 - lon2) == M_PI && fabs(lat1) != M_PI_2)
    return 0;
  if (d == 0 || lat1 == -M_PI_2)
    return (2 * M_PI);
  if (lat1 == M_PI_2)
    return M_PI;
  if (lon1 == lon2) {
    if (lat1 > lat2)
      return M_PI;
    else
      return (2 * M_PI);
  }
  double tc = acos((sin(lat2) - sin(lat1) * cos(*d)) / (sin(*d) * cos(lat1)));
  if (sin(lon2 - lon1) > 0)
    tc = (2 * M_PI) - tc;
  return tc;
}


x86 assembly (clang, -O0):
<calcGreatCircleRoute>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
mov    %rdi,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm3
call   1060 <calcAngularDist@plt>
mov    -0x30(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x10(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    120b <calcGreatCircleRoute+0xbb>
jp     120b <calcGreatCircleRoute+0xbb>
movsd  -0x18(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
call   1040 <fabs@plt>
mov    0x2e24(%rip),%rax
cvtsi2sdl (%rax),%xmm1
ucomisd %xmm1,%xmm0
jne    120b <calcGreatCircleRoute+0xbb>
jp     120b <calcGreatCircleRoute+0xbb>
movsd  -0x10(%rbp),%xmm0
call   1040 <fabs@plt>
mov    0x2df7(%rip),%rax
ucomisd (%rax),%xmm0
jne    11fe <calcGreatCircleRoute+0xae>
jp     11fe <calcGreatCircleRoute+0xae>
jmp    120b <calcGreatCircleRoute+0xbb>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1394 <calcGreatCircleRoute+0x244>
cmpq   $0x0,-0x30(%rbp)
je     124d <calcGreatCircleRoute+0xfd>
movsd  -0x10(%rbp),%xmm0
mov    0x2dbe(%rip),%rax
movsd  (%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
ucomisd %xmm1,%xmm0
jne    1267 <calcGreatCircleRoute+0x117>
jp     1267 <calcGreatCircleRoute+0x117>
mov    0x2d94(%rip),%rax
mov    (%rax),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1394 <calcGreatCircleRoute+0x244>
movsd  -0x10(%rbp),%xmm0
mov    0x2d6d(%rip),%rax
ucomisd (%rax),%xmm0
jne    1298 <calcGreatCircleRoute+0x148>
jp     1298 <calcGreatCircleRoute+0x148>
mov    0x2d5e(%rip),%rax
cvtsi2sdl (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1394 <calcGreatCircleRoute+0x244>
movsd  -0x18(%rbp),%xmm0
ucomisd -0x28(%rbp),%xmm0
jne    12ed <calcGreatCircleRoute+0x19d>
jp     12ed <calcGreatCircleRoute+0x19d>
movsd  -0x10(%rbp),%xmm0
ucomisd -0x20(%rbp),%xmm0
jbe    12d3 <calcGreatCircleRoute+0x183>
mov    0x2d23(%rip),%rax
cvtsi2sdl (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1394 <calcGreatCircleRoute+0x244>
mov    0x2d0e(%rip),%rax
mov    (%rax),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1394 <calcGreatCircleRoute+0x244>
movsd  -0x20(%rbp),%xmm0
call   1050 <sin@plt>
mov    %eax,-0x44(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1050 <sin@plt>
mov    %eax,-0x48(%rbp)
mov    -0x30(%rbp),%rax
movsd  (%rax),%xmm0
call   1070 <cos@plt>
mov    -0x48(%rbp),%ecx
mov    %eax,%edx
mov    -0x44(%rbp),%eax
imul   %edx,%ecx
sub    %ecx,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x30(%rbp),%rax
movsd  (%rax),%xmm0
call   1050 <sin@plt>
mov    %eax,-0x40(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1070 <cos@plt>
mov    -0x40(%rbp),%ecx
mov    %eax,%edx
mov    -0x3c(%rbp),%eax
imul   %edx,%ecx
cltd
idiv   %ecx
mov    %eax,%edi
call   1030 <acos@plt>
movsd  %xmm0,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
call   1050 <sin@plt>
cmp    $0x0,%eax
jle    138a <calcGreatCircleRoute+0x23a>
mov    0x2c71(%rip),%rax
mov    (%rax),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm0
subsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<calcGreatCircleRoute>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
mov    %rdi,%rbx
movsd  %xmm2,0x18(%rsp)
movsd  %xmm0,(%rsp)
movsd  %xmm1,0x8(%rsp)
movsd  %xmm3,0x10(%rsp)
call   1050 <calcAngularDist@plt>
movsd  0x18(%rsp),%xmm4
movsd  (%rsp),%xmm2
movsd  %xmm0,(%rbx)
movapd %xmm2,%xmm1
addsd  %xmm4,%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jne    11bc <calcGreatCircleRoute+0x7c>
jp     11bc <calcGreatCircleRoute+0x7c>
ucomisd %xmm0,%xmm2
jne    1192 <calcGreatCircleRoute+0x52>
jnp    11bc <calcGreatCircleRoute+0x7c>
movsd  0x8(%rsp),%xmm3
subsd  0x10(%rsp),%xmm3
andpd  0xe5a(%rip),%xmm3
mov    0x2e3b(%rip),%rax
xorps  %xmm1,%xmm1
cvtsi2sdl (%rax),%xmm1
ucomisd %xmm1,%xmm3
jne    11bc <calcGreatCircleRoute+0x7c>
jnp    11d6 <calcGreatCircleRoute+0x96>
ucomisd %xmm0,%xmm2
jne    11df <calcGreatCircleRoute+0x9f>
jp     11df <calcGreatCircleRoute+0x9f>
mov    0x2e1d(%rip),%rax
mov    (%rax),%eax
add    %eax,%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm0
ucomisd %xmm1,%xmm0
jne    1204 <calcGreatCircleRoute+0xc4>
jp     1204 <calcGreatCircleRoute+0xc4>
ucomisd %xmm4,%xmm2
mov    0x2dea(%rip),%rax
mov    (%rax),%eax
jbe    11cd <calcGreatCircleRoute+0x8d>
jmp    11cf <calcGreatCircleRoute+0x8f>
movapd %xmm4,%xmm0
call   1040 <sin@plt>
mov    %eax,%ebp
movsd  (%rsp),%xmm0
call   1040 <sin@plt>
mov    %eax,%r14d
movsd  (%rbx),%xmm0
call   1060 <cos@plt>
imul   %r14d,%eax
sub    %eax,%ebp
movsd  (%rbx),%xmm0
call   1040 <sin@plt>
mov    %eax,%ebx
movsd  (%rsp),%xmm0
call   1060 <cos@plt>
mov    %eax,%ecx
imul   %ebx,%ecx
mov    %ebp,%eax
cltd
idiv   %ecx
mov    %eax,%edi
call   1030 <acos@plt>
movsd  %xmm0,(%rsp)
movsd  0x10(%rsp),%xmm0
subsd  0x8(%rsp),%xmm0
call   1040 <sin@plt>
test   %eax,%eax
jg     1275 <calcGreatCircleRoute+0x135>
movsd  (%rsp),%xmm0
jmp    11d6 <calcGreatCircleRoute+0x96>
mov    0x2d6c(%rip),%rax
mov    (%rax),%eax
add    %eax,%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
subsd  (%rsp),%xmm0
jmp    11d6 <calcGreatCircleRoute+0x96>

LLVM IR (-O0):
@M_PI = global i32 0
@M_PI_2 = constant double 0.000000e+00
define double @calcGreatCircleRoute(double %0, double %1, double %2, double %3, double* %4) {
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double*
%12 = alloca double
store double %0, double* %7
store double %1, double* %8
store double %2, double* %9
store double %3, double* %10
store double* %4, double** %11
%13 = load double, double* %7
%14 = load double, double* %8
%15 = load double, double* %9
%16 = load double, double* %10
%17 = call double @calcAngularDist(double %13, double %14, double %15, double %16)
%18 = load double*, double** %11
store double %17, double* %18
%19 = load double, double* %7
%20 = load double, double* %9
%21 = fadd double %19, %20
%22 = fcmp oeq double %21, 0.000000e+00
br i1 %22, label %23, label %37
23: ; preds = %5
%24 = load double, double* %8
%25 = load double, double* %10
%26 = fsub double %24, %25
%27 = call double @fabs(double %26)
%28 = load i32, i32* @M_PI
%29 = sitofp i32 %28 to double
%30 = fcmp oeq double %27, %29
br i1 %30, label %31, label %37
31: ; preds = %23
%32 = load double, double* %7
%33 = call double @fabs(double %32)
%34 = load double, double* @M_PI_2
%35 = fcmp une double %33, %34
br i1 %35, label %36, label %37
36: ; preds = %31
store double 0.000000e+00, double* %6
br label %102
37: ; preds = %31, %23, %5
%38 = load double*, double** %11
%39 = icmp eq double* %38, null
br i1 %39, label %45, label %40
40: ; preds = %37
%41 = load double, double* %7
%42 = load double, double* @M_PI_2
%43 = fneg double %42
%44 = fcmp oeq double %41, %43
br i1 %44, label %45, label %49
45: ; preds = %40, %37
%46 = load i32, i32* @M_PI
%47 = mul nsw i32 2, %46
%48 = sitofp i32 %47 to double
store double %48, double* %6
br label %102
49: ; preds = %40
%50 = load double, double* %7
%51 = load double, double* @M_PI_2
%52 = fcmp oeq double %50, %51
br i1 %52, label %53, label %56
53: ; preds = %49
%54 = load i32, i32* @M_PI
%55 = sitofp i32 %54 to double
store double %55, double* %6
br label %102
56: ; preds = %49
%57 = load double, double* %8
%58 = load double, double* %10
%59 = fcmp oeq double %57, %58
br i1 %59, label %60, label %71
60: ; preds = %56
%61 = load double, double* %7
%62 = load double, double* %9
%63 = fcmp ogt double %61, %62
br i1 %63, label %64, label %67
64: ; preds = %60
%65 = load i32, i32* @M_PI
%66 = sitofp i32 %65 to double
store double %66, double* %6
br label %102
67: ; preds = %60
%68 = load i32, i32* @M_PI
%69 = mul nsw i32 2, %68
%70 = sitofp i32 %69 to double
store double %70, double* %6
br label %102
71: ; preds = %56
%72 = load double, double* %9
%73 = call i32 @sin(double %72)
%74 = load double, double* %7
%75 = call i32 @sin(double %74)
%76 = load double*, double** %11
%77 = load double, double* %76
%78 = call i32 @cos(double %77)
%79 = mul nsw i32 %75, %78
%80 = sub nsw i32 %73, %79
%81 = load double*, double** %11
%82 = load double, double* %81
%83 = call i32 @sin(double %82)
%84 = load double, double* %7
%85 = call i32 @cos(double %84)
%86 = mul nsw i32 %83, %85
%87 = sdiv i32 %80, %86
%88 = call double @acos(i32 %87)
store double %88, double* %12
%89 = load double, double* %10
%90 = load double, double* %8
%91 = fsub double %89, %90
%92 = call i32 @sin(double %91)
%93 = icmp sgt i32 %92, 0
br i1 %93, label %94, label %100
94: ; preds = %71
%95 = load i32, i32* @M_PI
%96 = mul nsw i32 2, %95
%97 = sitofp i32 %96 to double
%98 = load double, double* %12
%99 = fsub double %97, %98
store double %99, double* %12
br label %100
100: ; preds = %94, %71
%101 = load double, double* %12
store double %101, double* %6
br label %102
102: ; preds = %100, %67, %64, %53, %45, %36
%103 = load double, double* %6
ret double %103
}

LLVM IR (-O2):
@M_PI = global i32 0
@M_PI_2 = constant double 0.000000e+00
define double @calcGreatCircleRoute(double %0, double %1, double %2, double %3, double* nocapture %4) {
%6 = tail call double @calcAngularDist(double %0, double %1, double %2, double %3)
store double %6, double* %4
%7 = fadd double %0, %2
%8 = fcmp oeq double %7, 0.000000e+00
br i1 %8, label %9, label %17
9: ; preds = %5
%10 = fsub double %1, %3
%11 = tail call double @llvm.fabs.f64(double %10)
%12 = load i32, i32* @M_PI
%13 = sitofp i32 %12 to double
%14 = fcmp oeq double %11, %13
%15 = fcmp une double %0, 0.000000e+00
%16 = and i1 %15, %14
br i1 %16, label %54, label %17
17: ; preds = %5, %9
%18 = fcmp oeq double %0, 0.000000e+00
br i1 %18, label %19, label %23
19: ; preds = %17
%20 = load i32, i32* @M_PI
%21 = shl nsw i32 %20, 1
%22 = sitofp i32 %21 to double
br label %54
23: ; preds = %17
%24 = fcmp oeq double %1, %3
br i1 %24, label %25, label %33
25: ; preds = %23
%26 = fcmp ogt double %0, %2
%27 = load i32, i32* @M_PI
br i1 %26, label %28, label %30
28: ; preds = %25
%29 = sitofp i32 %27 to double
br label %54
30: ; preds = %25
%31 = shl nsw i32 %27, 1
%32 = sitofp i32 %31 to double
br label %54
33: ; preds = %23
%34 = tail call i32 @sin(double %2)
%35 = tail call i32 @sin(double %0)
%36 = load double, double* %4
%37 = tail call i32 @cos(double %36)
%38 = mul nsw i32 %37, %35
%39 = sub nsw i32 %34, %38
%40 = load double, double* %4
%41 = tail call i32 @sin(double %40)
%42 = tail call i32 @cos(double %0)
%43 = mul nsw i32 %42, %41
%44 = sdiv i32 %39, %43
%45 = tail call double @acos(i32 %44)
%46 = fsub double %3, %1
%47 = tail call i32 @sin(double %46)
%48 = icmp sgt i32 %47, 0
%49 = load i32, i32* @M_PI
%50 = shl nsw i32 %49, 1
%51 = sitofp i32 %50 to double
%52 = fsub double %51, %45
%53 = select i1 %48, double %52, double %45
br label %54
54: ; preds = %9, %33, %30, %28, %19
%55 = phi double [ %22, %19 ], [ %29, %28 ], [ %32, %30 ], [ %53, %33 ], [ 0.000000e+00, %9 ]
ret double %55
}