#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 acos(int);
double asin(int);
int cos(double);
int sin(double);
double GCAzimuth(double lat1, double lon1, double lat2, double lon2) {
  double result = 0.0;
  double c, A;
  long ilat1 = (long)(0.50 + lat1 * 360000.0);
  long ilat2 = (long)(0.50 + lat2 * 360000.0);
  long ilon1 = (long)(0.50 + lon1 * 360000.0);
  long ilon2 = (long)(0.50 + lon2 * 360000.0);
  lat1 *= 0.01745329252;
  lon1 *= 0.01745329252;
  lat2 *= 0.01745329252;
  lon2 *= 0.01745329252;
  if ((ilat1 == ilat2) && (ilon1 == ilon2)) {
    return result;
  } else if (ilat1 == ilat2) {
    if (ilon1 > ilon2)
      result = 90.0;
    else
      result = 270.0;
  } else if (ilon1 == ilon2) {
    if (ilat1 > ilat2)
      result = 180.0;
  } else {
    c = acos(sin(lat2) * sin(lat1) +
             cos(lat2) * cos(lat1) * cos((lon2 - lon1)));
    A = asin(cos(lat2) * sin((lon2 - lon1)) / sin(c));
    result = (A * 57.2957795129);
    if ((ilat2 > ilat1) && (ilon2 > ilon1)) {
    } else if ((ilat2 < ilat1) && (ilon2 < ilon1)) {
      result = 180.0 - result;
    } else if ((ilat2 < ilat1) && (ilon2 > ilon1)) {
      result = 180.0 - result;
    } else if ((ilat2 > ilat1) && (ilon2 < ilon1)) {
      result += 360.0;
    }
  }
  return result;
}


x86 assembly (clang, -O0):
<GCAzimuth>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  0xe94(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe90(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x48(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe6e(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe6a(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x50(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xe48(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe44(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x58(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xe22(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe1e(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x60(%rbp)
movsd  0xdf9(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xde7(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xdd5(%rip),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xdc3(%rip),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x50(%rbp),%rax
jne    1272 <GCAzimuth+0x132>
mov    -0x58(%rbp),%rax
cmp    -0x60(%rbp),%rax
jne    1272 <GCAzimuth+0x132>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    147e <GCAzimuth+0x33e>
mov    -0x48(%rbp),%rax
cmp    -0x50(%rbp),%rax
jne    12b2 <GCAzimuth+0x172>
mov    -0x58(%rbp),%rax
cmp    -0x60(%rbp),%rax
jle    12a0 <GCAzimuth+0x160>
movsd  0xda2(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    12ad <GCAzimuth+0x16d>
movsd  0xd88(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    146f <GCAzimuth+0x32f>
mov    -0x58(%rbp),%rax
cmp    -0x60(%rbp),%rax
jne    12e0 <GCAzimuth+0x1a0>
mov    -0x48(%rbp),%rax
cmp    -0x50(%rbp),%rax
jle    12db <GCAzimuth+0x19b>
movsd  0xd52(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    146a <GCAzimuth+0x32a>
movsd  -0x20(%rbp),%xmm0
call   1040 <sin@plt>
mov    %eax,-0x78(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1040 <sin@plt>
mov    %eax,%ecx
mov    -0x78(%rbp),%eax
imul   %ecx,%eax
mov    %eax,-0x70(%rbp)
movsd  -0x20(%rbp),%xmm0
call   1060 <cos@plt>
mov    %eax,-0x74(%rbp)
movsd  -0x10(%rbp),%xmm0
call   1060 <cos@plt>
mov    %eax,%ecx
mov    -0x74(%rbp),%eax
imul   %ecx,%eax
mov    %eax,-0x6c(%rbp)
movsd  -0x28(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
call   1060 <cos@plt>
mov    -0x70(%rbp),%edi
mov    %eax,%ecx
mov    -0x6c(%rbp),%eax
imul   %ecx,%eax
add    %eax,%edi
call   1030 <acos@plt>
movsd  %xmm0,-0x38(%rbp)
movsd  -0x20(%rbp),%xmm0
call   1060 <cos@plt>
mov    %eax,-0x68(%rbp)
movsd  -0x28(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
call   1040 <sin@plt>
mov    %eax,%ecx
mov    -0x68(%rbp),%eax
imul   %ecx,%eax
mov    %eax,-0x64(%rbp)
movsd  -0x38(%rbp),%xmm0
call   1040 <sin@plt>
mov    %eax,%ecx
mov    -0x64(%rbp),%eax
cltd
idiv   %ecx
mov    %eax,%edi
call   1050 <asin@plt>
movsd  %xmm0,-0x40(%rbp)
movsd  0xc81(%rip),%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x50(%rbp),%rax
cmp    -0x48(%rbp),%rax
jle    13c2 <GCAzimuth+0x282>
mov    -0x60(%rbp),%rax
cmp    -0x58(%rbp),%rax
jle    13c2 <GCAzimuth+0x282>
jmp    1465 <GCAzimuth+0x325>
mov    -0x50(%rbp),%rax
cmp    -0x48(%rbp),%rax
jge    13f5 <GCAzimuth+0x2b5>
mov    -0x60(%rbp),%rax
cmp    -0x58(%rbp),%rax
jge    13f5 <GCAzimuth+0x2b5>
movsd  0xc42(%rip),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    1460 <GCAzimuth+0x320>
mov    -0x50(%rbp),%rax
cmp    -0x48(%rbp),%rax
jge    1428 <GCAzimuth+0x2e8>
mov    -0x60(%rbp),%rax
cmp    -0x58(%rbp),%rax
jle    1428 <GCAzimuth+0x2e8>
movsd  0xc0f(%rip),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    145b <GCAzimuth+0x31b>
mov    -0x50(%rbp),%rax
cmp    -0x48(%rbp),%rax
jle    1456 <GCAzimuth+0x316>
mov    -0x60(%rbp),%rax
cmp    -0x58(%rbp),%rax
jge    1456 <GCAzimuth+0x316>
movsd  0xbd4(%rip),%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    145b <GCAzimuth+0x31b>
jmp    1460 <GCAzimuth+0x320>
jmp    1465 <GCAzimuth+0x325>
jmp    146a <GCAzimuth+0x32a>
jmp    146f <GCAzimuth+0x32f>
jmp    1474 <GCAzimuth+0x334>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<GCAzimuth>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
movapd %xmm0,%xmm6
movsd  0xea6(%rip),%xmm0
movapd %xmm6,%xmm5
mulsd  %xmm0,%xmm5
movsd  0xe9e(%rip),%xmm4
addsd  %xmm4,%xmm5
cvttsd2si %xmm5,%r15
movapd %xmm2,%xmm5
mulsd  %xmm0,%xmm5
addsd  %xmm4,%xmm5
cvttsd2si %xmm5,%rbx
movapd %xmm1,%xmm5
mulsd  %xmm0,%xmm5
addsd  %xmm4,%xmm5
cvttsd2si %xmm5,%r12
mulsd  %xmm3,%xmm0
addsd  %xmm4,%xmm0
cvttsd2si %xmm0,%r13
cmp    %rbx,%r15
jne    11b0 <GCAzimuth+0x70>
xorpd  %xmm0,%xmm0
cmp    %r13,%r12
je     11c9 <GCAzimuth+0x89>
cmp    %rbx,%r15
jne    11d8 <GCAzimuth+0x98>
xor    %eax,%eax
cmp    %r13,%r12
setg   %al
lea    0xe6c(%rip),%rcx
movsd  (%rcx,%rax,8),%xmm0
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
cmp    %r13,%r12
jne    11ec <GCAzimuth+0xac>
cmp    %rbx,%r15
jg     12e0 <GCAzimuth+0x1a0>
xorpd  %xmm0,%xmm0
jmp    11c9 <GCAzimuth+0x89>
movsd  0xe1c(%rip),%xmm0
mulsd  %xmm0,%xmm6
movsd  %xmm6,(%rsp)
mulsd  %xmm0,%xmm1
mulsd  %xmm0,%xmm2
movsd  %xmm2,0x8(%rsp)
mulsd  %xmm0,%xmm3
subsd  %xmm1,%xmm3
movsd  %xmm3,0x10(%rsp)
movapd %xmm2,%xmm0
call   1040 <sin@plt>
mov    %eax,%r14d
movsd  (%rsp),%xmm0
call   1040 <sin@plt>
imul   %eax,%r14d
movsd  0x8(%rsp),%xmm0
call   1060 <cos@plt>
mov    %eax,%ebp
movsd  (%rsp),%xmm0
call   1060 <cos@plt>
imul   %eax,%ebp
movsd  0x10(%rsp),%xmm0
call   1060 <cos@plt>
imul   %eax,%ebp
add    %r14d,%ebp
mov    %ebp,%edi
call   1030 <acos@plt>
movsd  %xmm0,(%rsp)
movsd  0x8(%rsp),%xmm0
call   1060 <cos@plt>
mov    %eax,%r14d
movsd  0x10(%rsp),%xmm0
call   1040 <sin@plt>
mov    %eax,%ebp
imul   %r14d,%ebp
movsd  (%rsp),%xmm0
call   1040 <sin@plt>
mov    %eax,%ecx
mov    %ebp,%eax
cltd
idiv   %ecx
mov    %eax,%edi
call   1050 <asin@plt>
mulsd  0xd6f(%rip),%xmm0
cmp    %r15,%rbx
jle    12b7 <GCAzimuth+0x177>
cmp    %r12,%r13
jg     11c9 <GCAzimuth+0x89>
cmp    %r15,%rbx
jge    12c1 <GCAzimuth+0x181>
cmp    %r12,%r13
jl     12cb <GCAzimuth+0x18b>
cmp    %r15,%rbx
jge    12ed <GCAzimuth+0x1ad>
cmp    %r12,%r13
jle    12ed <GCAzimuth+0x1ad>
movsd  0xd55(%rip),%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
jmp    11c9 <GCAzimuth+0x89>
movsd  0xd40(%rip),%xmm0
jmp    11c9 <GCAzimuth+0x89>
cmp    %r12,%r13
jl     12f8 <GCAzimuth+0x1b8>
movapd %xmm0,%xmm1
jmp    1304 <GCAzimuth+0x1c4>
movsd  0xd20(%rip),%xmm1
addsd  %xmm0,%xmm1
cmp    %r15,%rbx
jg     12d7 <GCAzimuth+0x197>
movapd %xmm0,%xmm1
jmp    12d7 <GCAzimuth+0x197>

LLVM IR (-O0):
define double @GCAzimuth(double %0, double %1, double %2, double %3) {
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca i64
%14 = alloca i64
%15 = alloca i64
%16 = alloca i64
store double %0, double* %6
store double %1, double* %7
store double %2, double* %8
store double %3, double* %9
store double 0.000000e+00, double* %10
%17 = load double, double* %6
%18 = call double @llvm.fmuladd.f64(double %17, double 3.600000e+05, double 5.000000e-01)
%19 = fptosi double %18 to i64
store i64 %19, i64* %13
%20 = load double, double* %8
%21 = call double @llvm.fmuladd.f64(double %20, double 3.600000e+05, double 5.000000e-01)
%22 = fptosi double %21 to i64
store i64 %22, i64* %14
%23 = load double, double* %7
%24 = call double @llvm.fmuladd.f64(double %23, double 3.600000e+05, double 5.000000e-01)
%25 = fptosi double %24 to i64
store i64 %25, i64* %15
%26 = load double, double* %9
%27 = call double @llvm.fmuladd.f64(double %26, double 3.600000e+05, double 5.000000e-01)
%28 = fptosi double %27 to i64
store i64 %28, i64* %16
%29 = load double, double* %6
%30 = fmul double %29, 0x3F91DF46A252DD11
store double %30, double* %6
%31 = load double, double* %7
%32 = fmul double %31, 0x3F91DF46A252DD11
store double %32, double* %7
%33 = load double, double* %8
%34 = fmul double %33, 0x3F91DF46A252DD11
store double %34, double* %8
%35 = load double, double* %9
%36 = fmul double %35, 0x3F91DF46A252DD11
store double %36, double* %9
%37 = load i64, i64* %13
%38 = load i64, i64* %14
%39 = icmp eq i64 %37, %38
br i1 %39, label %40, label %46
40: ; preds = %4
%41 = load i64, i64* %15
%42 = load i64, i64* %16
%43 = icmp eq i64 %41, %42
br i1 %43, label %44, label %46
44: ; preds = %40
%45 = load double, double* %10
store double %45, double* %5
br label %147
46: ; preds = %40, %4
%47 = load i64, i64* %13
%48 = load i64, i64* %14
%49 = icmp eq i64 %47, %48
br i1 %49, label %50, label %57
50: ; preds = %46
%51 = load i64, i64* %15
%52 = load i64, i64* %16
%53 = icmp sgt i64 %51, %52
br i1 %53, label %54, label %55
54: ; preds = %50
store double 9.000000e+01, double* %10
br label %56
55: ; preds = %50
store double 2.700000e+02, double* %10
br label %56
56: ; preds = %55, %54
br label %144
57: ; preds = %46
%58 = load i64, i64* %15
%59 = load i64, i64* %16
%60 = icmp eq i64 %58, %59
br i1 %60, label %61, label %67
61: ; preds = %57
%62 = load i64, i64* %13
%63 = load i64, i64* %14
%64 = icmp sgt i64 %62, %63
br i1 %64, label %65, label %66
65: ; preds = %61
store double 1.800000e+02, double* %10
br label %66
66: ; preds = %65, %61
br label %143
67: ; preds = %57
%68 = load double, double* %8
%69 = call i32 @sin(double %68)
%70 = load double, double* %6
%71 = call i32 @sin(double %70)
%72 = mul nsw i32 %69, %71
%73 = load double, double* %8
%74 = call i32 @cos(double %73)
%75 = load double, double* %6
%76 = call i32 @cos(double %75)
%77 = mul nsw i32 %74, %76
%78 = load double, double* %9
%79 = load double, double* %7
%80 = fsub double %78, %79
%81 = call i32 @cos(double %80)
%82 = mul nsw i32 %77, %81
%83 = add nsw i32 %72, %82
%84 = call double @acos(i32 %83)
store double %84, double* %11
%85 = load double, double* %8
%86 = call i32 @cos(double %85)
%87 = load double, double* %9
%88 = load double, double* %7
%89 = fsub double %87, %88
%90 = call i32 @sin(double %89)
%91 = mul nsw i32 %86, %90
%92 = load double, double* %11
%93 = call i32 @sin(double %92)
%94 = sdiv i32 %91, %93
%95 = call double @asin(i32 %94)
store double %95, double* %12
%96 = load double, double* %12
%97 = fmul double %96, 0x404CA5DC1A635DBC
store double %97, double* %10
%98 = load i64, i64* %14
%99 = load i64, i64* %13
%100 = icmp sgt i64 %98, %99
br i1 %100, label %101, label %106
101: ; preds = %67
%102 = load i64, i64* %16
%103 = load i64, i64* %15
%104 = icmp sgt i64 %102, %103
br i1 %104, label %105, label %106
105: ; preds = %101
br label %142
106: ; preds = %101, %67
%107 = load i64, i64* %14
%108 = load i64, i64* %13
%109 = icmp slt i64 %107, %108
br i1 %109, label %110, label %117
110: ; preds = %106
%111 = load i64, i64* %16
%112 = load i64, i64* %15
%113 = icmp slt i64 %111, %112
br i1 %113, label %114, label %117
114: ; preds = %110
%115 = load double, double* %10
%116 = fsub double 1.800000e+02, %115
store double %116, double* %10
br label %141
117: ; preds = %110, %106
%118 = load i64, i64* %14
%119 = load i64, i64* %13
%120 = icmp slt i64 %118, %119
br i1 %120, label %121, label %128
121: ; preds = %117
%122 = load i64, i64* %16
%123 = load i64, i64* %15
%124 = icmp sgt i64 %122, %123
br i1 %124, label %125, label %128
125: ; preds = %121
%126 = load double, double* %10
%127 = fsub double 1.800000e+02, %126
store double %127, double* %10
br label %140
128: ; preds = %121, %117
%129 = load i64, i64* %14
%130 = load i64, i64* %13
%131 = icmp sgt i64 %129, %130
br i1 %131, label %132, label %139
132: ; preds = %128
%133 = load i64, i64* %16
%134 = load i64, i64* %15
%135 = icmp slt i64 %133, %134
br i1 %135, label %136, label %139
136: ; preds = %132
%137 = load double, double* %10
%138 = fadd double %137, 3.600000e+02
store double %138, double* %10
br label %139
139: ; preds = %136, %132, %128
br label %140
140: ; preds = %139, %125
br label %141
141: ; preds = %140, %114
br label %142
142: ; preds = %141, %105
br label %143
143: ; preds = %142, %66
br label %144
144: ; preds = %143, %56
br label %145
145: ; preds = %144
%146 = load double, double* %10
store double %146, double* %5
br label %147
147: ; preds = %145, %44
%148 = load double, double* %5
ret double %148
}

LLVM IR (-O2):
define double @GCAzimuth(double %0, double %1, double %2, double %3) {
%5 = tail call double @llvm.fmuladd.f64(double %0, double 3.600000e+05, double 5.000000e-01)
%6 = fptosi double %5 to i64
%7 = tail call double @llvm.fmuladd.f64(double %2, double 3.600000e+05, double 5.000000e-01)
%8 = fptosi double %7 to i64
%9 = tail call double @llvm.fmuladd.f64(double %1, double 3.600000e+05, double 5.000000e-01)
%10 = fptosi double %9 to i64
%11 = tail call double @llvm.fmuladd.f64(double %3, double 3.600000e+05, double 5.000000e-01)
%12 = fptosi double %11 to i64
%13 = fmul double %0, 0x3F91DF46A252DD11
%14 = fmul double %1, 0x3F91DF46A252DD11
%15 = fmul double %2, 0x3F91DF46A252DD11
%16 = fmul double %3, 0x3F91DF46A252DD11
%17 = icmp eq i64 %6, %8
%18 = icmp eq i64 %10, %12
%19 = select i1 %17, i1 %18, i1 false
br i1 %19, label %64, label %20
20: ; preds = %4
br i1 %17, label %21, label %24
21: ; preds = %20
%22 = icmp sgt i64 %10, %12
%23 = select i1 %22, double 9.000000e+01, double 2.700000e+02
br label %64
24: ; preds = %20
br i1 %18, label %25, label %28
25: ; preds = %24
%26 = icmp sgt i64 %6, %8
%27 = select i1 %26, double 1.800000e+02, double 0.000000e+00
br label %64
28: ; preds = %24
%29 = tail call i32 @sin(double %15)
%30 = tail call i32 @sin(double %13)
%31 = mul nsw i32 %30, %29
%32 = tail call i32 @cos(double %15)
%33 = tail call i32 @cos(double %13)
%34 = mul nsw i32 %33, %32
%35 = fsub double %16, %14
%36 = tail call i32 @cos(double %35)
%37 = mul nsw i32 %34, %36
%38 = add nsw i32 %37, %31
%39 = tail call double @acos(i32 %38)
%40 = tail call i32 @cos(double %15)
%41 = tail call i32 @sin(double %35)
%42 = mul nsw i32 %41, %40
%43 = tail call i32 @sin(double %39)
%44 = sdiv i32 %42, %43
%45 = tail call double @asin(i32 %44)
%46 = fmul double %45, 0x404CA5DC1A635DBC
%47 = icmp sgt i64 %8, %6
%48 = icmp sgt i64 %12, %10
%49 = select i1 %47, i1 %48, i1 false
br i1 %49, label %64, label %50
50: ; preds = %28
%51 = icmp slt i64 %8, %6
%52 = icmp slt i64 %12, %10
%53 = select i1 %51, i1 %52, i1 false
br i1 %53, label %54, label %56
54: ; preds = %50
%55 = fsub double 1.800000e+02, %46
br label %64
56: ; preds = %50
%57 = select i1 %51, i1 %48, i1 false
br i1 %57, label %58, label %60
58: ; preds = %56
%59 = fsub double 1.800000e+02, %46
br label %64
60: ; preds = %56
%61 = select i1 %47, i1 %52, i1 false
%62 = fadd double %46, 3.600000e+02
%63 = select i1 %61, double %62, double %46
br label %64
64: ; preds = %60, %25, %54, %58, %21, %28, %4
%65 = phi double [ 0.000000e+00, %4 ], [ %55, %54 ], [ %59, %58 ], [ %23, %21 ], [ %27, %25 ], [ %46, %28 ], [ %63, %60 ]
ret double %65
}