#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 */
struct rpc {
  int dummy;
};

/* Variables and functions */
int /*<<< orphan*/ eval_rpc_pair(double *, struct rpc *, struct rpc *, double,
                                 double, double);
double fabs(double);
double hypot(double, double);
double rpc_height(struct rpc *rpca, struct rpc *rpcb, double xa, double ya,
                  double xb, double yb, double *outerr) {
  double x[2] = {xa, ya};
  double y[2] = {xb, yb};
  double h = 0;
  for (int t = 0; t < 100; t++) {
    double hstep = 1;
    double p[2], q[2];
    eval_rpc_pair(p, rpca, rpcb, x[0], x[1], h);
    eval_rpc_pair(q, rpca, rpcb, x[0], x[1], h + hstep);
    double a[2] = {q[0] - p[0], q[1] - p[1]};
    double b[2] = {y[0] - p[0], y[1] - p[1]};
    double a2 = a[0] * a[0] + a[1] * a[1];
    double lambda = (a[0] * b[0] + a[1] * b[1]) / a2;
    double z[2] = {p[0] + lambda * a[0], p[1] + lambda * a[1]};
    double err = hypot(z[0] - y[0], z[1] - y[1]);
    if (outerr)
      *outerr = err;
    h += lambda * hstep;
    if (fabs(lambda) < 0.00001)
      break;
  }
  return h;
}


x86 assembly (clang, -O0):
<rpc_height>:
push   %rbp
mov    %rsp,%rbp
sub    $0xf0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
movsd  %xmm2,-0x28(%rbp)
movsd  %xmm3,-0x30(%rbp)
mov    %rdx,-0x38(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x68(%rbp)
movl   $0x0,-0x6c(%rbp)
cmpl   $0x64,-0x6c(%rbp)
jge    1394 <rpc_height+0x274>
movsd  0xe6c(%rip),%xmm0
movsd  %xmm0,-0x78(%rbp)
lea    -0x90(%rbp),%rdi
mov    -0x8(%rbp),%rsi
mov    -0x10(%rbp),%rdx
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x68(%rbp),%xmm2
call   1040 <eval_rpc_pair@plt>
lea    -0xa0(%rbp),%rdi
mov    -0x8(%rbp),%rsi
mov    -0x10(%rbp),%rdx
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
movsd  -0x68(%rbp),%xmm2
addsd  -0x78(%rbp),%xmm2
call   1040 <eval_rpc_pair@plt>
movsd  -0xa0(%rbp),%xmm0
ff
subsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0xb0(%rbp)
ff
movsd  -0x98(%rbp),%xmm0
ff
subsd  -0x88(%rbp),%xmm0
ff
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  -0x60(%rbp),%xmm0
subsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0xc0(%rbp)
ff
movsd  -0x58(%rbp),%xmm0
subsd  -0x88(%rbp),%xmm0
ff
movsd  %xmm0,-0xb8(%rbp)
ff
movsd  -0xb0(%rbp),%xmm0
ff
movsd  -0xb0(%rbp),%xmm2
ff
movsd  -0xa8(%rbp),%xmm1
ff
mulsd  -0xa8(%rbp),%xmm1
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0xc8(%rbp)
ff
movsd  -0xb0(%rbp),%xmm0
ff
movsd  -0xc0(%rbp),%xmm2
ff
movsd  -0xa8(%rbp),%xmm1
ff
mulsd  -0xb8(%rbp),%xmm1
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
divsd  -0xc8(%rbp),%xmm0
ff
movsd  %xmm0,-0xd0(%rbp)
ff
movsd  -0x90(%rbp),%xmm1
ff
movsd  -0xd0(%rbp),%xmm0
ff
movsd  -0xb0(%rbp),%xmm2
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0xe0(%rbp)
ff
movsd  -0x88(%rbp),%xmm1
ff
movsd  -0xd0(%rbp),%xmm0
ff
movsd  -0xa8(%rbp),%xmm2
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0xd8(%rbp)
ff
movsd  -0xe0(%rbp),%xmm0
ff
subsd  -0x60(%rbp),%xmm0
movsd  -0xd8(%rbp),%xmm1
ff
subsd  -0x58(%rbp),%xmm1
call   1030 <hypot@plt>
movsd  %xmm0,-0xe8(%rbp)
ff
cmpq   $0x0,-0x38(%rbp)
je     1338 <rpc_height+0x218>
movsd  -0xe8(%rbp),%xmm0
ff
mov    -0x38(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0xd0(%rbp),%xmm0
ff
movsd  -0x78(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0xd0(%rbp),%xmm1
ff
movaps 0xcaa(%rip),%xmm0
pand   %xmm0,%xmm1
movsd  0xc96(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    1381 <rpc_height+0x261>
jmp    1394 <rpc_height+0x274>
jmp    1386 <rpc_height+0x266>
mov    -0x6c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x6c(%rbp)
jmp    1182 <rpc_height+0x62>
movsd  -0x68(%rbp),%xmm0
add    $0xf0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rpc_height>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x68,%rsp
mov    %rdx,%r14
movsd  %xmm3,0x28(%rsp)
movsd  %xmm2,0x20(%rsp)
movsd  %xmm1,0x10(%rsp)
movsd  %xmm0,0x8(%rsp)
mov    %rsi,%r15
mov    %rdi,%rbx
xorpd  %xmm2,%xmm2
mov    $0x63,%ebp
lea    0x40(%rsp),%r12
lea    0x30(%rsp),%r13
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    %r12,%rdi
mov    %rbx,%rsi
mov    %r15,%rdx
movsd  0x8(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  %xmm2,0x18(%rsp)
call   1040 <eval_rpc_pair@plt>
movsd  0x18(%rsp),%xmm2
addsd  0xe62(%rip),%xmm2
mov    %r13,%rdi
mov    %rbx,%rsi
mov    %r15,%rdx
movsd  0x8(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
call   1040 <eval_rpc_pair@plt>
movsd  0x30(%rsp),%xmm0
movsd  0x38(%rsp),%xmm1
movsd  0x40(%rsp),%xmm2
movsd  0x48(%rsp),%xmm3
subsd  %xmm2,%xmm0
subsd  %xmm3,%xmm1
movsd  0x20(%rsp),%xmm8
movapd %xmm8,%xmm7
subsd  %xmm2,%xmm7
movsd  0x28(%rsp),%xmm9
movapd %xmm9,%xmm4
subsd  %xmm3,%xmm4
movapd %xmm1,%xmm5
mulsd  %xmm1,%xmm5
movapd %xmm0,%xmm6
mulsd  %xmm0,%xmm6
addsd  %xmm5,%xmm6
mulsd  %xmm1,%xmm4
mulsd  %xmm0,%xmm7
addsd  %xmm4,%xmm7
divsd  %xmm6,%xmm7
mulsd  %xmm7,%xmm0
addsd  %xmm2,%xmm0
movapd %xmm7,0x50(%rsp)
mulsd  %xmm7,%xmm1
addsd  %xmm3,%xmm1
subsd  %xmm8,%xmm0
subsd  %xmm9,%xmm1
call   1030 <hypot@plt>
test   %r14,%r14
je     124b <rpc_height+0x12b>
movsd  %xmm0,(%r14)
movsd  0x18(%rsp),%xmm2
movapd 0x50(%rsp),%xmm1
addsd  %xmm1,%xmm2
andpd  0xdad(%rip),%xmm1
sub    $0x1,%ebp
setb   %al
movsd  0xd97(%rip),%xmm0
ucomisd %xmm1,%xmm0
ja     127f <rpc_height+0x15f>
test   %al,%al
je     1170 <rpc_height+0x50>
movapd %xmm2,%xmm0
add    $0x68,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
%struct.rpc = type { i32 }
define double @rpc_height(%struct.rpc* %0, %struct.rpc* %1, double %2, double %3, double %4, double %5, double* writeonly %6) {
%8 = alloca [2 x double]
%9 = alloca [2 x double]
%10 = bitcast [2 x double]* %8 to i8*
%11 = bitcast [2 x double]* %9 to i8*
%12 = getelementptr inbounds [2 x double], [2 x double]* %8, i64 0, i64 0
%13 = getelementptr inbounds [2 x double], [2 x double]* %9, i64 0, i64 0
%14 = getelementptr inbounds [2 x double], [2 x double]* %9, i64 0, i64 1
%15 = getelementptr inbounds [2 x double], [2 x double]* %8, i64 0, i64 1
%16 = icmp eq double* %6, null
br label %17
17: ; preds = %42, %7
%18 = phi double [ 0.000000e+00, %7 ], [ %43, %42 ]
%19 = phi i32 [ 0, %7 ], [ %46, %42 ]
%20 = call i32 @eval_rpc_pair(double* %12, %struct.rpc* %0, %struct.rpc* %1, double %2, double %3, double %18)
%21 = fadd double %18, 1.000000e+00
%22 = call i32 @eval_rpc_pair(double* %13, %struct.rpc* %0, %struct.rpc* %1, double %2, double %3, double %21)
%23 = load double, double* %13
%24 = load double, double* %12
%25 = fsub double %23, %24
%26 = load double, double* %14
%27 = load double, double* %15
%28 = fsub double %26, %27
%29 = fsub double %4, %24
%30 = fsub double %5, %27
%31 = fmul double %28, %28
%32 = call double @llvm.fmuladd.f64(double %25, double %25, double %31)
%33 = fmul double %28, %30
%34 = call double @llvm.fmuladd.f64(double %25, double %29, double %33)
%35 = fdiv double %34, %32
%36 = call double @llvm.fmuladd.f64(double %35, double %25, double %24)
%37 = call double @llvm.fmuladd.f64(double %35, double %28, double %27)
%38 = fsub double %36, %4
%39 = fsub double %37, %5
%40 = call double @hypot(double %38, double %39)
br i1 %16, label %42, label %41
41: ; preds = %17
store double %40, double* %6
br label %42
42: ; preds = %41, %17
%43 = fadd double %18, %35
%44 = call double @llvm.fabs.f64(double %35)
%45 = fcmp olt double %44, 1.000000e-05
%46 = add nuw nsw i32 %19, 1
%47 = icmp eq i32 %46, 100
%48 = select i1 %45, i1 true, i1 %47
br i1 %48, label %49, label %17
49: ; preds = %42
ret double %43
}