#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 asin(int);
long double cos(long double);
long double sin(long double);
int sqrt(long double);
long double haversine_distance(long double *p1, long double *p2) {
  long double th1 = p1[0], ph1 = p1[1], th2 = p2[0], ph2 = p2[1];
  long double dx, dy, dz;
  ph1 -= ph2;
  ph1 *= (3.1415926536 / 180), th1 *= (3.1415926536 / 180),
      th2 *= (3.1415926536 / 180);
  dz = sin(th1) - sin(th2);
  dx = cos(ph1) * cos(th1) - cos(th2);
  dy = sin(ph1) * cos(th1);
  return asin(sqrt(dx * dx + dy * dy + dz * dz) / 2) * 2 * 6371000.;
}


x86 assembly (clang, -O0):
<haversine_distance>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
fldt   (%rax)
fstpt  -0x20(%rbp)
mov    -0x8(%rbp),%rax
fldt   0x10(%rax)
fstpt  -0x30(%rbp)
mov    -0x10(%rbp),%rax
fldt   (%rax)
fstpt  -0x40(%rbp)
mov    -0x10(%rbp),%rax
fldt   0x10(%rax)
fstpt  -0x50(%rbp)
fldt   -0x50(%rbp)
fldt   -0x30(%rbp)
fsubp  %st,%st(1)
fstpt  -0x30(%rbp)
fldt   -0x30(%rbp)
fldl   0xe73(%rip)
fmul   %st,%st(1)
fxch   %st(1)
fstpt  -0x30(%rbp)
fldt   -0x20(%rbp)
fmul   %st(1),%st
fstpt  -0x20(%rbp)
fldt   -0x40(%rbp)
fmulp  %st,%st(1)
fstpt  -0x40(%rbp)
fldt   -0x20(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1030 <sin@plt>
fstpt  -0xb8(%rbp)
fldt   -0x40(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1030 <sin@plt>
fldt   -0xb8(%rbp)
fsubp  %st,%st(1)
fstpt  -0x80(%rbp)
fldt   -0x30(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1050 <cos@plt>
fstpt  -0xa0(%rbp)
fldt   -0x20(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1050 <cos@plt>
fstpt  -0xac(%rbp)
fldt   -0x40(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1050 <cos@plt>
fldt   -0xac(%rbp)
fldt   -0xa0(%rbp)
fmulp  %st,%st(1)
fsubp  %st,%st(1)
fstpt  -0x60(%rbp)
fldt   -0x30(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1030 <sin@plt>
fstpt  -0x94(%rbp)
fldt   -0x20(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1050 <cos@plt>
fldt   -0x94(%rbp)
fmulp  %st,%st(1)
fstpt  -0x70(%rbp)
fldt   -0x60(%rbp)
fldt   -0x70(%rbp)
fmul   %st,%st(0)
fxch   %st(1)
fmul   %st,%st(0)
faddp  %st,%st(1)
fldt   -0x80(%rbp)
fmul   %st,%st(0)
faddp  %st,%st(1)
mov    %rsp,%rax
fstpt  (%rax)
call   1060 <sqrt@plt>
mov    %eax,%edi
mov    %edi,%eax
shr    $0x1f,%eax
add    %eax,%edi
sar    %edi
call   1040 <asin@plt>
add    %eax,%eax
cvtsi2sd %eax,%xmm0
movsd  0xd8b(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
fldl   -0x88(%rbp)
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<haversine_distance>:
sub    $0x68,%rsp
fldt   (%rdi)
fldt   0x10(%rdi)
fldt   (%rsi)
fldt   0x10(%rsi)
fsubrp %st,%st(2)
fldl   0xeaa(%rip)
fmul   %st,%st(2)
fxch   %st(2)
fstpt  0x24(%rsp)
fxch   %st(2)
fmul   %st(1),%st
fld    %st(0)
fstpt  0x3c(%rsp)
fxch   %st(2)
fmulp  %st,%st(1)
fstpt  0x18(%rsp)
fstpt  (%rsp)
call   1030 <sin@plt>
fstpt  0x30(%rsp)
fldt   0x18(%rsp)
fstpt  (%rsp)
call   1030 <sin@plt>
fldt   0x30(%rsp)
fsubp  %st,%st(1)
fstpt  0x30(%rsp)
fldt   0x24(%rsp)
fstpt  (%rsp)
call   1050 <cos@plt>
fstpt  0x5c(%rsp)
fldt   0x3c(%rsp)
fstpt  (%rsp)
call   1050 <cos@plt>
fstpt  0x50(%rsp)
fldt   0x18(%rsp)
fstpt  (%rsp)
call   1050 <cos@plt>
fldt   0x5c(%rsp)
fldt   0x50(%rsp)
fmulp  %st,%st(1)
fsubp  %st,%st(1)
fstpt  0x18(%rsp)
fldt   0x24(%rsp)
fstpt  (%rsp)
call   1030 <sin@plt>
fstpt  0x24(%rsp)
fldt   0x3c(%rsp)
fstpt  (%rsp)
call   1050 <cos@plt>
fldt   0x24(%rsp)
fmulp  %st,%st(1)
fmul   %st,%st(0)
fldt   0x18(%rsp)
fmul   %st,%st(0)
faddp  %st,%st(1)
fldt   0x30(%rsp)
fmul   %st,%st(0)
faddp  %st,%st(1)
fstpt  (%rsp)
call   1060 <sqrt@plt>
mov    %eax,%edi
shr    $0x1f,%edi
add    %eax,%edi
sar    %edi
call   1040 <asin@plt>
add    %eax,%eax
cvtsi2sd %eax,%xmm0
mulsd  0xde2(%rip),%xmm0
movsd  %xmm0,0x48(%rsp)
fldl   0x48(%rsp)
add    $0x68,%rsp
ret

LLVM IR (-O0):
define x86_fp80 @haversine_distance(x86_fp80* %0, x86_fp80* %1) {
%3 = alloca x86_fp80*
%4 = alloca x86_fp80*
%5 = alloca x86_fp80
%6 = alloca x86_fp80
%7 = alloca x86_fp80
%8 = alloca x86_fp80
%9 = alloca x86_fp80
%10 = alloca x86_fp80
%11 = alloca x86_fp80
store x86_fp80* %0, x86_fp80** %3
store x86_fp80* %1, x86_fp80** %4
%12 = load x86_fp80*, x86_fp80** %3
%13 = getelementptr inbounds x86_fp80, x86_fp80* %12, i64 0
%14 = load x86_fp80, x86_fp80* %13
store x86_fp80 %14, x86_fp80* %5
%15 = load x86_fp80*, x86_fp80** %3
%16 = getelementptr inbounds x86_fp80, x86_fp80* %15, i64 1
%17 = load x86_fp80, x86_fp80* %16
store x86_fp80 %17, x86_fp80* %6
%18 = load x86_fp80*, x86_fp80** %4
%19 = getelementptr inbounds x86_fp80, x86_fp80* %18, i64 0
%20 = load x86_fp80, x86_fp80* %19
store x86_fp80 %20, x86_fp80* %7
%21 = load x86_fp80*, x86_fp80** %4
%22 = getelementptr inbounds x86_fp80, x86_fp80* %21, i64 1
%23 = load x86_fp80, x86_fp80* %22
store x86_fp80 %23, x86_fp80* %8
%24 = load x86_fp80, x86_fp80* %8
%25 = load x86_fp80, x86_fp80* %6
%26 = fsub x86_fp80 %25, %24
store x86_fp80 %26, x86_fp80* %6
%27 = load x86_fp80, x86_fp80* %6
%28 = fmul x86_fp80 %27, 0xK3FF98EFA351296E88800
store x86_fp80 %28, x86_fp80* %6
%29 = load x86_fp80, x86_fp80* %5
%30 = fmul x86_fp80 %29, 0xK3FF98EFA351296E88800
store x86_fp80 %30, x86_fp80* %5
%31 = load x86_fp80, x86_fp80* %7
%32 = fmul x86_fp80 %31, 0xK3FF98EFA351296E88800
store x86_fp80 %32, x86_fp80* %7
%33 = load x86_fp80, x86_fp80* %5
%34 = call x86_fp80 @sin(x86_fp80 %33)
%35 = load x86_fp80, x86_fp80* %7
%36 = call x86_fp80 @sin(x86_fp80 %35)
%37 = fsub x86_fp80 %34, %36
store x86_fp80 %37, x86_fp80* %11
%38 = load x86_fp80, x86_fp80* %6
%39 = call x86_fp80 @cos(x86_fp80 %38)
%40 = load x86_fp80, x86_fp80* %5
%41 = call x86_fp80 @cos(x86_fp80 %40)
%42 = load x86_fp80, x86_fp80* %7
%43 = call x86_fp80 @cos(x86_fp80 %42)
%44 = fneg x86_fp80 %43
%45 = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %39, x86_fp80 %41, x86_fp80 %44)
store x86_fp80 %45, x86_fp80* %9
%46 = load x86_fp80, x86_fp80* %6
%47 = call x86_fp80 @sin(x86_fp80 %46)
%48 = load x86_fp80, x86_fp80* %5
%49 = call x86_fp80 @cos(x86_fp80 %48)
%50 = fmul x86_fp80 %47, %49
store x86_fp80 %50, x86_fp80* %10
%51 = load x86_fp80, x86_fp80* %9
%52 = load x86_fp80, x86_fp80* %9
%53 = load x86_fp80, x86_fp80* %10
%54 = load x86_fp80, x86_fp80* %10
%55 = fmul x86_fp80 %53, %54
%56 = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %51, x86_fp80 %52, x86_fp80 %55)
%57 = load x86_fp80, x86_fp80* %11
%58 = load x86_fp80, x86_fp80* %11
%59 = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %57, x86_fp80 %58, x86_fp80 %56)
%60 = call i32 @sqrt(x86_fp80 %59)
%61 = sdiv i32 %60, 2
%62 = call i32 @asin(i32 %61)
%63 = mul nsw i32 %62, 2
%64 = sitofp i32 %63 to double
%65 = fmul double %64, 6.371000e+06
%66 = fpext double %65 to x86_fp80
ret x86_fp80 %66
}

LLVM IR (-O2):
define x86_fp80 @haversine_distance(x86_fp80* nocapture %0, x86_fp80* nocapture %1) {
%3 = load x86_fp80, x86_fp80* %0
%4 = getelementptr inbounds x86_fp80, x86_fp80* %0, i64 1
%5 = load x86_fp80, x86_fp80* %4
%6 = load x86_fp80, x86_fp80* %1
%7 = getelementptr inbounds x86_fp80, x86_fp80* %1, i64 1
%8 = load x86_fp80, x86_fp80* %7
%9 = fsub x86_fp80 %5, %8
%10 = fmul x86_fp80 %9, 0xK3FF98EFA351296E88800
%11 = fmul x86_fp80 %3, 0xK3FF98EFA351296E88800
%12 = fmul x86_fp80 %6, 0xK3FF98EFA351296E88800
%13 = tail call x86_fp80 @sin(x86_fp80 %11)
%14 = tail call x86_fp80 @sin(x86_fp80 %12)
%15 = fsub x86_fp80 %13, %14
%16 = tail call x86_fp80 @cos(x86_fp80 %10)
%17 = tail call x86_fp80 @cos(x86_fp80 %11)
%18 = tail call x86_fp80 @cos(x86_fp80 %12)
%19 = fneg x86_fp80 %18
%20 = tail call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %16, x86_fp80 %17, x86_fp80 %19)
%21 = tail call x86_fp80 @sin(x86_fp80 %10)
%22 = tail call x86_fp80 @cos(x86_fp80 %11)
%23 = fmul x86_fp80 %21, %22
%24 = fmul x86_fp80 %23, %23
%25 = tail call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %20, x86_fp80 %20, x86_fp80 %24)
%26 = tail call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %15, x86_fp80 %15, x86_fp80 %25)
%27 = tail call i32 @sqrt(x86_fp80 %26)
%28 = sdiv i32 %27, 2
%29 = tail call i32 @asin(i32 %28)
%30 = shl nsw i32 %29, 1
%31 = sitofp i32 %30 to double
%32 = fmul double %31, 6.371000e+06
%33 = fpext double %32 to x86_fp80
ret x86_fp80 %33
}