#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 fabs(double);
double sqrt(double);
double edgedf(double gx, double gy, double a) {
  double df, glength, temp, a1;
  if ((gx == 0) || (gy == 0)) {
    df = 0.5 - a;
  } else {
    glength = sqrt(gx * gx + gy * gy);
    if (glength > 0) {
      gx = gx / glength;
      gy = gy / glength;
    }
    gx = fabs(gx);
    gy = fabs(gy);
    if (gx < gy) {
      temp = gx;
      gx = gy;
      gy = temp;
    }
    a1 = 0.5 * gy / gx;
    if (a < a1) {
      df = 0.5 * (gx + gy) - sqrt(2.0 * gx * gy * a);
    } else if (a < (1.0 - a1)) {
      df = (0.5 - a) * gx;
    } else {
      df = -0.5 * (gx + gy) + sqrt(2.0 * gx * gy * (1.0 - a));
    }
  }
  return df;
}


x86 assembly (clang, -O0):
<edgedf>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
movsd  %xmm2,-0x18(%rbp)
movsd  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1144 <edgedf+0x34>
jp     1144 <edgedf+0x34>
jmp    115c <edgedf+0x4c>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1173 <edgedf+0x63>
jp     1173 <edgedf+0x63>
movsd  0xeac(%rip),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    134a <edgedf+0x23a>
movsd  -0x8(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm2
movsd  -0x10(%rbp),%xmm1
mulsd  -0x10(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
call   1030 <sqrt@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    11c9 <edgedf+0xb9>
movsd  -0x8(%rbp),%xmm0
divsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x10(%rbp),%xmm0
divsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x8(%rbp),%xmm0
movaps 0xe2b(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x10(%rbp),%xmm0
movaps 0xe16(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x8(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1225 <edgedf+0x115>
movsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xde3(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
divsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    12b4 <edgedf+0x1a4>
movsd  -0x8(%rbp),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xdc1(%rip),%xmm0
mulsd  -0x8(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
call   1030 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  -0x40(%rbp),%xmm0
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
movsd  0xd6e(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    1345 <edgedf+0x235>
movsd  -0x18(%rbp),%xmm1
movsd  0xd57(%rip),%xmm0
subsd  -0x38(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    12ec <edgedf+0x1dc>
movsd  0xd38(%rip),%xmm0
subsd  -0x18(%rbp),%xmm0
mulsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    1340 <edgedf+0x230>
movsd  -0x8(%rbp),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  0xd25(%rip),%xmm0
mulsd  -0x8(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  0xd03(%rip),%xmm1
subsd  -0x18(%rbp),%xmm1
mulsd  %xmm1,%xmm0
call   1030 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
movsd  0xced(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    1345 <edgedf+0x235>
jmp    134a <edgedf+0x23a>
movsd  -0x20(%rbp),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<edgedf>:
sub    $0x38,%rsp
movapd %xmm0,%xmm4
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm4
jne    1124 <edgedf+0x14>
jnp    1150 <edgedf+0x40>
ucomisd %xmm0,%xmm1
jne    112c <edgedf+0x1c>
jnp    1150 <edgedf+0x40>
movapd %xmm1,%xmm3
mulsd  %xmm1,%xmm3
movapd %xmm4,%xmm0
mulsd  %xmm4,%xmm0
addsd  %xmm3,%xmm0
xorpd  %xmm3,%xmm3
ucomisd %xmm3,%xmm0
jb     1161 <edgedf+0x51>
sqrtsd %xmm0,%xmm0
jmp    118c <edgedf+0x7c>
movsd  0xeb8(%rip),%xmm0
subsd  %xmm2,%xmm0
add    $0x38,%rsp
ret
movapd %xmm1,(%rsp)
movsd  %xmm2,0x18(%rsp)
movapd %xmm4,0x20(%rsp)
call   1030 <sqrt@plt>
xorpd  %xmm3,%xmm3
movapd 0x20(%rsp),%xmm4
movsd  0x18(%rsp),%xmm2
movapd (%rsp),%xmm1
ucomisd %xmm3,%xmm0
unpcklpd %xmm4,%xmm1
jbe    119e <edgedf+0x8e>
unpcklpd %xmm0,%xmm0
divpd  %xmm0,%xmm1
andpd  0xe5a(%rip),%xmm1
pshufd $0xee,%xmm1,%xmm0
movdqa %xmm0,%xmm4
minsd  %xmm1,%xmm4
maxsd  %xmm0,%xmm1
movsd  0xe51(%rip),%xmm5
mulsd  %xmm4,%xmm5
divsd  %xmm1,%xmm5
ucomisd %xmm2,%xmm5
jbe    11f4 <edgedf+0xe4>
movapd %xmm1,%xmm3
addsd  %xmm4,%xmm3
addsd  %xmm1,%xmm1
mulsd  %xmm4,%xmm1
mulsd  %xmm2,%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jb     121f <edgedf+0x10f>
xorps  %xmm0,%xmm0
sqrtsd %xmm1,%xmm0
jmp    1232 <edgedf+0x122>
movsd  0xe1c(%rip),%xmm0
movapd %xmm0,%xmm3
subsd  %xmm5,%xmm3
ucomisd %xmm2,%xmm3
jbe    1240 <edgedf+0x130>
movsd  0xdfe(%rip),%xmm0
subsd  %xmm2,%xmm0
mulsd  %xmm1,%xmm0
add    $0x38,%rsp
ret
movapd %xmm1,%xmm0
movapd %xmm3,(%rsp)
call   1030 <sqrt@plt>
movapd (%rsp),%xmm3
mulsd  0xdd6(%rip),%xmm3
subsd  %xmm0,%xmm3
jmp    1283 <edgedf+0x173>
movapd %xmm1,%xmm3
addsd  %xmm4,%xmm3
addsd  %xmm1,%xmm1
mulsd  %xmm4,%xmm1
subsd  %xmm2,%xmm0
mulsd  %xmm1,%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     1268 <edgedf+0x158>
sqrtsd %xmm0,%xmm0
jmp    1277 <edgedf+0x167>
movapd %xmm3,(%rsp)
call   1030 <sqrt@plt>
movapd (%rsp),%xmm3
mulsd  0xda1(%rip),%xmm3
addsd  %xmm0,%xmm3
movapd %xmm3,%xmm0
add    $0x38,%rsp
ret

LLVM IR (-O0):
define double @edgedf(double %0, double %1, double %2) {
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
store double %0, double* %4
store double %1, double* %5
store double %2, double* %6
%11 = load double, double* %4
%12 = fcmp oeq double %11, 0.000000e+00
br i1 %12, label %16, label %13
13: ; preds = %3
%14 = load double, double* %5
%15 = fcmp oeq double %14, 0.000000e+00
br i1 %15, label %16, label %19
16: ; preds = %13, %3
%17 = load double, double* %6
%18 = fsub double 5.000000e-01, %17
store double %18, double* %7
br label %94
19: ; preds = %13
%20 = load double, double* %4
%21 = load double, double* %4
%22 = load double, double* %5
%23 = load double, double* %5
%24 = fmul double %22, %23
%25 = call double @llvm.fmuladd.f64(double %20, double %21, double %24)
%26 = call double @sqrt(double %25)
store double %26, double* %8
%27 = load double, double* %8
%28 = fcmp ogt double %27, 0.000000e+00
br i1 %28, label %29, label %36
29: ; preds = %19
%30 = load double, double* %4
%31 = load double, double* %8
%32 = fdiv double %30, %31
store double %32, double* %4
%33 = load double, double* %5
%34 = load double, double* %8
%35 = fdiv double %33, %34
store double %35, double* %5
br label %36
36: ; preds = %29, %19
%37 = load double, double* %4
%38 = call double @llvm.fabs.f64(double %37)
store double %38, double* %4
%39 = load double, double* %5
%40 = call double @llvm.fabs.f64(double %39)
store double %40, double* %5
%41 = load double, double* %4
%42 = load double, double* %5
%43 = fcmp olt double %41, %42
br i1 %43, label %44, label %48
44: ; preds = %36
%45 = load double, double* %4
store double %45, double* %9
%46 = load double, double* %5
store double %46, double* %4
%47 = load double, double* %9
store double %47, double* %5
br label %48
48: ; preds = %44, %36
%49 = load double, double* %5
%50 = fmul double 5.000000e-01, %49
%51 = load double, double* %4
%52 = fdiv double %50, %51
store double %52, double* %10
%53 = load double, double* %6
%54 = load double, double* %10
%55 = fcmp olt double %53, %54
br i1 %55, label %56, label %69
56: ; preds = %48
%57 = load double, double* %4
%58 = load double, double* %5
%59 = fadd double %57, %58
%60 = load double, double* %4
%61 = fmul double 2.000000e+00, %60
%62 = load double, double* %5
%63 = fmul double %61, %62
%64 = load double, double* %6
%65 = fmul double %63, %64
%66 = call double @sqrt(double %65)
%67 = fneg double %66
%68 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %59, double %67)
store double %68, double* %7
br label %93
69: ; preds = %48
%70 = load double, double* %6
%71 = load double, double* %10
%72 = fsub double 1.000000e+00, %71
%73 = fcmp olt double %70, %72
br i1 %73, label %74, label %79
74: ; preds = %69
%75 = load double, double* %6
%76 = fsub double 5.000000e-01, %75
%77 = load double, double* %4
%78 = fmul double %76, %77
store double %78, double* %7
br label %92
79: ; preds = %69
%80 = load double, double* %4
%81 = load double, double* %5
%82 = fadd double %80, %81
%83 = load double, double* %4
%84 = fmul double 2.000000e+00, %83
%85 = load double, double* %5
%86 = fmul double %84, %85
%87 = load double, double* %6
%88 = fsub double 1.000000e+00, %87
%89 = fmul double %86, %88
%90 = call double @sqrt(double %89)
%91 = call double @llvm.fmuladd.f64(double -5.000000e-01, double %82, double %90)
store double %91, double* %7
br label %92
92: ; preds = %79, %74
br label %93
93: ; preds = %92, %56
br label %94
94: ; preds = %93, %16
%95 = load double, double* %7
ret double %95
}

LLVM IR (-O2):
define double @edgedf(double %0, double %1, double %2) {
%4 = fcmp oeq double %0, 0.000000e+00
%5 = fcmp oeq double %1, 0.000000e+00
%6 = or i1 %4, %5
br i1 %6, label %7, label %9
7: ; preds = %3
%8 = fsub double 5.000000e-01, %2
br label %53
9: ; preds = %3
%10 = fmul double %1, %1
%11 = tail call double @llvm.fmuladd.f64(double %0, double %0, double %10)
%12 = tail call double @sqrt(double %11)
%13 = fcmp ogt double %12, 0.000000e+00
%14 = insertelement <2 x double> poison, double %1, i64 0
%15 = insertelement <2 x double> %14, double %0, i64 1
br i1 %13, label %16, label %20
16: ; preds = %9
%17 = insertelement <2 x double> poison, double %12, i64 0
%18 = shufflevector <2 x double> %17, <2 x double> poison, <2 x i32> zeroinitializer
%19 = fdiv <2 x double> %15, %18
br label %20
20: ; preds = %16, %9
%21 = phi <2 x double> [ %19, %16 ], [ %15, %9 ]
%22 = call <2 x double> @llvm.fabs.v2f64(<2 x double> %21)
%23 = extractelement <2 x double> %22, i64 0
%24 = extractelement <2 x double> %22, i64 1
%25 = fcmp olt double %24, %23
%26 = select i1 %25, double %24, double %23
%27 = select i1 %25, double %23, double %24
%28 = fmul double %26, 5.000000e-01
%29 = fdiv double %28, %27
%30 = fcmp ogt double %29, %2
br i1 %30, label %31, label %39
31: ; preds = %20
%32 = fadd double %27, %26
%33 = fmul double %27, 2.000000e+00
%34 = fmul double %26, %33
%35 = fmul double %34, %2
%36 = tail call double @sqrt(double %35)
%37 = fneg double %36
%38 = tail call double @llvm.fmuladd.f64(double %32, double 5.000000e-01, double %37)
br label %53
39: ; preds = %20
%40 = fsub double 1.000000e+00, %29
%41 = fcmp ogt double %40, %2
br i1 %41, label %42, label %45
42: ; preds = %39
%43 = fsub double 5.000000e-01, %2
%44 = fmul double %43, %27
br label %53
45: ; preds = %39
%46 = fadd double %27, %26
%47 = fmul double %27, 2.000000e+00
%48 = fmul double %26, %47
%49 = fsub double 1.000000e+00, %2
%50 = fmul double %49, %48
%51 = tail call double @sqrt(double %50)
%52 = tail call double @llvm.fmuladd.f64(double %46, double -5.000000e-01, double %51)
br label %53
53: ; preds = %31, %45, %42, %7
%54 = phi double [ %8, %7 ], [ %38, %31 ], [ %44, %42 ], [ %52, %45 ]
ret double %54
}