#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 */
long double _max(long double, long double);
long double _min(long double, long double);
long double haversine_distance(long double *, long double *);
int /*<<< orphan*/ proj_point_to_circle(long double *, long double *,
                                        long double *, long double *,
                                        long double *);
long double distance_point_segment(long double *a, long double *b,
                                   long double *p) {
  long double d, c[2];
  proj_point_to_circle(a, b, p, c, &d);
  if (c[0] >= _min(a[0], b[0]) && c[0] <= _max(a[0], b[0]) &&
      c[1] >= _min(a[1], b[1]) && c[1] <= _max(a[1], b[1]))
    return d;
  long double d2 = haversine_distance(a, p);
  d = haversine_distance(b, p);
  if (d2 < d)
    return d2;
  else
    return d;
}


x86 assembly (clang, -O0):
<distance_point_segment>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
mov    %rdi,-0x18(%rbp)
mov    %rsi,-0x20(%rbp)
mov    %rdx,-0x28(%rbp)
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rdx
lea    -0x60(%rbp),%rcx
lea    -0x40(%rbp),%r8
call   1050 <proj_point_to_circle@plt>
fldt   -0x60(%rbp)
fstpt  -0x7c(%rbp)
mov    -0x18(%rbp),%rax
fldt   (%rax)
mov    -0x20(%rbp),%rax
fldt   (%rax)
mov    %rsp,%rax
fstpt  0x10(%rax)
fstpt  (%rax)
call   1060 <_min@plt>
fldt   -0x7c(%rbp)
fucomip %st(1),%st
fstp   %st(0)
jb     1261 <distance_point_segment+0x121>
jmp    11a1 <distance_point_segment+0x61>
fldt   -0x60(%rbp)
fstpt  -0x88(%rbp)
mov    -0x18(%rbp),%rax
fldt   (%rax)
mov    -0x20(%rbp),%rax
fldt   (%rax)
mov    %rsp,%rax
fstpt  0x10(%rax)
fstpt  (%rax)
call   1040 <_max@plt>
fldt   -0x88(%rbp)
fld    %st(1)
fstp   %st(0)
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
jb     1261 <distance_point_segment+0x121>
jmp    11de <distance_point_segment+0x9e>
fldt   -0x50(%rbp)
fstpt  -0x94(%rbp)
mov    -0x18(%rbp),%rax
fldt   0x10(%rax)
mov    -0x20(%rbp),%rax
fldt   0x10(%rax)
mov    %rsp,%rax
fstpt  0x10(%rax)
fstpt  (%rax)
call   1060 <_min@plt>
fldt   -0x94(%rbp)
fucomip %st(1),%st
fstp   %st(0)
jb     1261 <distance_point_segment+0x121>
jmp    1217 <distance_point_segment+0xd7>
fldt   -0x50(%rbp)
fstpt  -0xa0(%rbp)
mov    -0x18(%rbp),%rax
fldt   0x10(%rax)
mov    -0x20(%rbp),%rax
fldt   0x10(%rax)
mov    %rsp,%rax
fstpt  0x10(%rax)
fstpt  (%rax)
call   1040 <_max@plt>
fldt   -0xa0(%rbp)
fld    %st(1)
fstp   %st(0)
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
jb     1261 <distance_point_segment+0x121>
jmp    1256 <distance_point_segment+0x116>
fldt   -0x40(%rbp)
fstpt  -0x10(%rbp)
jmp    12a7 <distance_point_segment+0x167>
mov    -0x18(%rbp),%rdi
mov    -0x28(%rbp),%rsi
call   1030 <haversine_distance@plt>
fstpt  -0x70(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0x28(%rbp),%rsi
call   1030 <haversine_distance@plt>
fstpt  -0x40(%rbp)
fldt   -0x70(%rbp)
fldt   -0x40(%rbp)
fucomip %st(1),%st
fstp   %st(0)
jbe    12a1 <distance_point_segment+0x161>
jmp    1296 <distance_point_segment+0x156>
fldt   -0x70(%rbp)
fstpt  -0x10(%rbp)
jmp    12a7 <distance_point_segment+0x167>
fldt   -0x40(%rbp)
fstpt  -0x10(%rbp)
fldt   -0x10(%rbp)
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<distance_point_segment>:
push   %r15
push   %r14
push   %rbx
sub    $0x60,%rsp
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%rbx
lea    0x30(%rsp),%rcx
lea    0x50(%rsp),%r8
call   1050 <proj_point_to_circle@plt>
fldt   0x30(%rsp)
fstpt  0x24(%rsp)
fldt   (%rbx)
fldt   (%r15)
fstpt  0x10(%rsp)
fstpt  (%rsp)
call   1060 <_min@plt>
fldt   0x24(%rsp)
fucomip %st(1),%st
fstp   %st(0)
jb     11f5 <distance_point_segment+0xb5>
fldt   0x30(%rsp)
fstpt  0x24(%rsp)
fldt   (%rbx)
fldt   (%r15)
fstpt  0x10(%rsp)
fstpt  (%rsp)
call   1040 <_max@plt>
fldt   0x24(%rsp)
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
jb     11f5 <distance_point_segment+0xb5>
fldt   0x40(%rsp)
fstpt  0x24(%rsp)
fldt   0x10(%rbx)
fldt   0x10(%r15)
fstpt  0x10(%rsp)
fstpt  (%rsp)
call   1060 <_min@plt>
fldt   0x24(%rsp)
fucomip %st(1),%st
fstp   %st(0)
jb     11f5 <distance_point_segment+0xb5>
fldt   0x40(%rsp)
fstpt  0x24(%rsp)
fldt   0x10(%rbx)
fldt   0x10(%r15)
fstpt  0x10(%rsp)
fstpt  (%rsp)
call   1040 <_max@plt>
fldt   0x24(%rsp)
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
jae    1225 <distance_point_segment+0xe5>
mov    %rbx,%rdi
mov    %r14,%rsi
call   1030 <haversine_distance@plt>
fstpt  0x24(%rsp)
mov    %r15,%rdi
mov    %r14,%rsi
call   1030 <haversine_distance@plt>
fldt   0x24(%rsp)
fxch   %st(1)
fucomi %st(1),%st
fcmovnbe %st(1),%st
fstp   %st(1)
add    $0x60,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret
fldt   0x50(%rsp)
jmp    121b <distance_point_segment+0xdb>

LLVM IR (-O0):
define x86_fp80 @distance_point_segment(x86_fp80* %0, x86_fp80* %1, x86_fp80* %2) {
%4 = alloca x86_fp80
%5 = alloca x86_fp80*
%6 = alloca x86_fp80*
%7 = alloca x86_fp80*
%8 = alloca x86_fp80
%9 = alloca [2 x x86_fp80]
%10 = alloca x86_fp80
store x86_fp80* %0, x86_fp80** %5
store x86_fp80* %1, x86_fp80** %6
store x86_fp80* %2, x86_fp80** %7
%11 = load x86_fp80*, x86_fp80** %5
%12 = load x86_fp80*, x86_fp80** %6
%13 = load x86_fp80*, x86_fp80** %7
%14 = getelementptr inbounds [2 x x86_fp80], [2 x x86_fp80]* %9, i64 0, i64 0
%15 = call i32 @proj_point_to_circle(x86_fp80* %11, x86_fp80* %12, x86_fp80* %13, x86_fp80* %14, x86_fp80* %8)
%16 = getelementptr inbounds [2 x x86_fp80], [2 x x86_fp80]* %9, i64 0, i64 0
%17 = load x86_fp80, x86_fp80* %16
%18 = load x86_fp80*, x86_fp80** %5
%19 = getelementptr inbounds x86_fp80, x86_fp80* %18, i64 0
%20 = load x86_fp80, x86_fp80* %19
%21 = load x86_fp80*, x86_fp80** %6
%22 = getelementptr inbounds x86_fp80, x86_fp80* %21, i64 0
%23 = load x86_fp80, x86_fp80* %22
%24 = call x86_fp80 @_min(x86_fp80 %20, x86_fp80 %23)
%25 = fcmp oge x86_fp80 %17, %24
br i1 %25, label %26, label %61
26: ; preds = %3
%27 = getelementptr inbounds [2 x x86_fp80], [2 x x86_fp80]* %9, i64 0, i64 0
%28 = load x86_fp80, x86_fp80* %27
%29 = load x86_fp80*, x86_fp80** %5
%30 = getelementptr inbounds x86_fp80, x86_fp80* %29, i64 0
%31 = load x86_fp80, x86_fp80* %30
%32 = load x86_fp80*, x86_fp80** %6
%33 = getelementptr inbounds x86_fp80, x86_fp80* %32, i64 0
%34 = load x86_fp80, x86_fp80* %33
%35 = call x86_fp80 @_max(x86_fp80 %31, x86_fp80 %34)
%36 = fcmp ole x86_fp80 %28, %35
br i1 %36, label %37, label %61
37: ; preds = %26
%38 = getelementptr inbounds [2 x x86_fp80], [2 x x86_fp80]* %9, i64 0, i64 1
%39 = load x86_fp80, x86_fp80* %38
%40 = load x86_fp80*, x86_fp80** %5
%41 = getelementptr inbounds x86_fp80, x86_fp80* %40, i64 1
%42 = load x86_fp80, x86_fp80* %41
%43 = load x86_fp80*, x86_fp80** %6
%44 = getelementptr inbounds x86_fp80, x86_fp80* %43, i64 1
%45 = load x86_fp80, x86_fp80* %44
%46 = call x86_fp80 @_min(x86_fp80 %42, x86_fp80 %45)
%47 = fcmp oge x86_fp80 %39, %46
br i1 %47, label %48, label %61
48: ; preds = %37
%49 = getelementptr inbounds [2 x x86_fp80], [2 x x86_fp80]* %9, i64 0, i64 1
%50 = load x86_fp80, x86_fp80* %49
%51 = load x86_fp80*, x86_fp80** %5
%52 = getelementptr inbounds x86_fp80, x86_fp80* %51, i64 1
%53 = load x86_fp80, x86_fp80* %52
%54 = load x86_fp80*, x86_fp80** %6
%55 = getelementptr inbounds x86_fp80, x86_fp80* %54, i64 1
%56 = load x86_fp80, x86_fp80* %55
%57 = call x86_fp80 @_max(x86_fp80 %53, x86_fp80 %56)
%58 = fcmp ole x86_fp80 %50, %57
br i1 %58, label %59, label %61
59: ; preds = %48
%60 = load x86_fp80, x86_fp80* %8
store x86_fp80 %60, x86_fp80* %4
br label %75
61: ; preds = %48, %37, %26, %3
%62 = load x86_fp80*, x86_fp80** %5
%63 = load x86_fp80*, x86_fp80** %7
%64 = call x86_fp80 @haversine_distance(x86_fp80* %62, x86_fp80* %63)
store x86_fp80 %64, x86_fp80* %10
%65 = load x86_fp80*, x86_fp80** %6
%66 = load x86_fp80*, x86_fp80** %7
%67 = call x86_fp80 @haversine_distance(x86_fp80* %65, x86_fp80* %66)
store x86_fp80 %67, x86_fp80* %8
%68 = load x86_fp80, x86_fp80* %10
%69 = load x86_fp80, x86_fp80* %8
%70 = fcmp olt x86_fp80 %68, %69
br i1 %70, label %71, label %73
71: ; preds = %61
%72 = load x86_fp80, x86_fp80* %10
store x86_fp80 %72, x86_fp80* %4
br label %75
73: ; preds = %61
%74 = load x86_fp80, x86_fp80* %8
store x86_fp80 %74, x86_fp80* %4
br label %75
75: ; preds = %73, %71, %59
%76 = load x86_fp80, x86_fp80* %4
ret x86_fp80 %76
}

LLVM IR (-O2):
define x86_fp80 @distance_point_segment(x86_fp80* %0, x86_fp80* %1, x86_fp80* %2) {
%4 = alloca x86_fp80
%5 = alloca [2 x x86_fp80]
%6 = bitcast x86_fp80* %4 to i8*
%7 = bitcast [2 x x86_fp80]* %5 to i8*
%8 = getelementptr inbounds [2 x x86_fp80], [2 x x86_fp80]* %5, i64 0, i64 0
%9 = call i32 @proj_point_to_circle(x86_fp80* %0, x86_fp80* %1, x86_fp80* %2, x86_fp80* %8, x86_fp80* %4)
%10 = load x86_fp80, x86_fp80* %8
%11 = load x86_fp80, x86_fp80* %0
%12 = load x86_fp80, x86_fp80* %1
%13 = call x86_fp80 @_min(x86_fp80 %11, x86_fp80 %12)
%14 = fcmp ult x86_fp80 %10, %13
br i1 %14, label %38, label %15
15: ; preds = %3
%16 = load x86_fp80, x86_fp80* %8
%17 = load x86_fp80, x86_fp80* %0
%18 = load x86_fp80, x86_fp80* %1
%19 = call x86_fp80 @_max(x86_fp80 %17, x86_fp80 %18)
%20 = fcmp ugt x86_fp80 %16, %19
br i1 %20, label %38, label %21
21: ; preds = %15
%22 = getelementptr inbounds [2 x x86_fp80], [2 x x86_fp80]* %5, i64 0, i64 1
%23 = load x86_fp80, x86_fp80* %22
%24 = getelementptr inbounds x86_fp80, x86_fp80* %0, i64 1
%25 = load x86_fp80, x86_fp80* %24
%26 = getelementptr inbounds x86_fp80, x86_fp80* %1, i64 1
%27 = load x86_fp80, x86_fp80* %26
%28 = call x86_fp80 @_min(x86_fp80 %25, x86_fp80 %27)
%29 = fcmp ult x86_fp80 %23, %28
br i1 %29, label %38, label %30
30: ; preds = %21
%31 = load x86_fp80, x86_fp80* %22
%32 = load x86_fp80, x86_fp80* %24
%33 = load x86_fp80, x86_fp80* %26
%34 = call x86_fp80 @_max(x86_fp80 %32, x86_fp80 %33)
%35 = fcmp ugt x86_fp80 %31, %34
br i1 %35, label %38, label %36
36: ; preds = %30
%37 = load x86_fp80, x86_fp80* %4
br label %43
38: ; preds = %30, %21, %15, %3
%39 = call x86_fp80 @haversine_distance(x86_fp80* %0, x86_fp80* %2)
%40 = call x86_fp80 @haversine_distance(x86_fp80* %1, x86_fp80* %2)
%41 = fcmp olt x86_fp80 %39, %40
%42 = select i1 %41, x86_fp80 %39, x86_fp80 %40
br label %43
43: ; preds = %38, %36
%44 = phi x86_fp80 [ %37, %36 ], [ %42, %38 ]
ret x86_fp80 %44
}