#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 sqrt(double);
int line_intersect(double Ax, double Ay, double Bx, double By, double Cx,
                   double Cy, double Dx, double Dy, double *X, double *Y) {
  if ((Ax == Bx && Ay == By) || (Cx == Dx && Cy == Dy))
    return 0;
  Bx -= Ax;
  By -= Ay;
  Cx -= Ax;
  Cy -= Ay;
  Dx -= Ax;
  Dy -= Ay;
  const double distAB = sqrt(Bx * Bx + By * By);
  const double theCos = Bx / distAB;
  const double theSin = By / distAB;
  double newX = Cx * theCos + Cy * theSin;
  Cy = Cy * theCos - Cx * theSin;
  Cx = newX;
  newX = Dx * theCos + Dy * theSin;
  Dy = Dy * theCos - Dx * theSin;
  Dx = newX;
  if (Cy == Dy)
    return 0;
  const double ABpos = Dx + (Cx - Dx) * Dy / (Dy - Cy);
  *X = Ax + ABpos * theCos;
  *Y = Ay + ABpos * theSin;
  return 1;
}


x86 assembly (clang, -O0):
<line_intersect>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
movsd  %xmm4,-0x30(%rbp)
movsd  %xmm5,-0x38(%rbp)
movsd  %xmm6,-0x40(%rbp)
movsd  %xmm7,-0x48(%rbp)
mov    %rdi,-0x50(%rbp)
mov    %rsi,-0x58(%rbp)
movsd  -0x10(%rbp),%xmm0
ucomisd -0x20(%rbp),%xmm0
jne    117c <line_intersect+0x6c>
jp     117c <line_intersect+0x6c>
movsd  -0x18(%rbp),%xmm0
ucomisd -0x28(%rbp),%xmm0
jne    117c <line_intersect+0x6c>
jp     117c <line_intersect+0x6c>
jmp    11a8 <line_intersect+0x98>
movsd  -0x30(%rbp),%xmm0
ucomisd -0x40(%rbp),%xmm0
jne    11b4 <line_intersect+0xa4>
jp     11b4 <line_intersect+0xa4>
movsd  -0x38(%rbp),%xmm0
ucomisd -0x48(%rbp),%xmm0
jne    11b4 <line_intersect+0xa4>
jp     11b4 <line_intersect+0xa4>
movl   $0x0,-0x4(%rbp)
jmp    13c2 <line_intersect+0x2b2>
movsd  -0x10(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x10(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x10(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  -0x48(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm1
mulsd  -0x28(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
call   1030 <sqrt@plt>
movsd  %xmm0,-0x60(%rbp)
movsd  -0x20(%rbp),%xmm0
divsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x28(%rbp),%xmm0
divsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm1
mulsd  -0x70(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm1
mulsd  -0x70(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
movsd  -0x48(%rbp),%xmm1
mulsd  -0x70(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  -0x70(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x38(%rbp),%xmm0
ucomisd -0x48(%rbp),%xmm0
jne    1352 <line_intersect+0x242>
jp     1352 <line_intersect+0x242>
movl   $0x0,-0x4(%rbp)
jmp    13c2 <line_intersect+0x2b2>
movsd  -0x40(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm1
subsd  -0x40(%rbp),%xmm1
mulsd  -0x48(%rbp),%xmm1
movsd  -0x48(%rbp),%xmm2
subsd  -0x38(%rbp),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  -0x10(%rbp),%xmm1
movsd  -0x80(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x50(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x18(%rbp),%xmm1
movsd  -0x80(%rbp),%xmm0
movsd  -0x70(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x58(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<line_intersect>:
push   %rbp
push   %r14
push   %rbx
sub    $0x60,%rsp
mov    %rsi,%r14
mov    %rdi,%rbx
movapd %xmm0,%xmm8
xor    %ebp,%ebp
ucomisd %xmm2,%xmm0
jne    1139 <line_intersect+0x29>
jp     1139 <line_intersect+0x29>
ucomisd %xmm3,%xmm1
jne    1139 <line_intersect+0x29>
jnp    127c <line_intersect+0x16c>
ucomisd %xmm6,%xmm4
jne    114d <line_intersect+0x3d>
jp     114d <line_intersect+0x3d>
ucomisd %xmm7,%xmm5
jne    114d <line_intersect+0x3d>
jnp    127c <line_intersect+0x16c>
subsd  %xmm8,%xmm2
subsd  %xmm1,%xmm3
unpcklpd %xmm6,%xmm4
movapd %xmm8,%xmm0
unpcklpd %xmm8,%xmm0
subpd  %xmm0,%xmm4
unpcklpd %xmm7,%xmm5
movapd %xmm1,%xmm0
unpcklpd %xmm1,%xmm0
subpd  %xmm0,%xmm5
movapd %xmm3,%xmm6
mulsd  %xmm3,%xmm6
movapd %xmm2,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm6,%xmm0
xorpd  %xmm6,%xmm6
ucomisd %xmm6,%xmm0
jb     119c <line_intersect+0x8c>
sqrtsd %xmm0,%xmm0
jmp    11e9 <line_intersect+0xd9>
movapd %xmm4,0x50(%rsp)
movapd %xmm1,0x40(%rsp)
movapd %xmm3,0x30(%rsp)
movapd %xmm2,0x20(%rsp)
movapd %xmm8,0x10(%rsp)
movapd %xmm5,(%rsp)
call   1030 <sqrt@plt>
movapd (%rsp),%xmm5
movapd 0x10(%rsp),%xmm8
movapd 0x20(%rsp),%xmm2
movapd 0x30(%rsp),%xmm3
movapd 0x40(%rsp),%xmm1
movapd 0x50(%rsp),%xmm4
divsd  %xmm0,%xmm2
divsd  %xmm0,%xmm3
movapd %xmm3,%xmm6
unpcklpd %xmm3,%xmm6
mulpd  %xmm4,%xmm6
movapd %xmm2,%xmm0
unpcklpd %xmm2,%xmm0
mulpd  %xmm5,%xmm0
subpd  %xmm6,%xmm0
movapd %xmm0,%xmm7
unpckhpd %xmm0,%xmm7
ucomisd %xmm7,%xmm0
jne    121d <line_intersect+0x10d>
jnp    127c <line_intersect+0x16c>
movapd %xmm5,%xmm9
unpckhpd %xmm5,%xmm9
mulsd  %xmm3,%xmm9
movapd %xmm4,%xmm6
unpckhpd %xmm4,%xmm6
mulsd  %xmm2,%xmm6
addsd  %xmm9,%xmm6
mulsd  %xmm3,%xmm5
mulsd  %xmm2,%xmm4
addsd  %xmm5,%xmm4
subsd  %xmm6,%xmm4
mulsd  %xmm7,%xmm4
subsd  %xmm0,%xmm7
divsd  %xmm7,%xmm4
addsd  %xmm6,%xmm4
mulsd  %xmm4,%xmm2
addsd  %xmm8,%xmm2
movsd  %xmm2,(%rbx)
mulsd  %xmm3,%xmm4
addsd  %xmm1,%xmm4
movsd  %xmm4,(%r14)
mov    $0x1,%ebp
mov    %ebp,%eax
add    $0x60,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define i32 @line_intersect(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double* %8, double* %9) {
%11 = alloca i32
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca double*
%21 = alloca double*
%22 = alloca double
%23 = alloca double
%24 = alloca double
%25 = alloca double
%26 = alloca double
store double %0, double* %12
store double %1, double* %13
store double %2, double* %14
store double %3, double* %15
store double %4, double* %16
store double %5, double* %17
store double %6, double* %18
store double %7, double* %19
store double* %8, double** %20
store double* %9, double** %21
%27 = load double, double* %12
%28 = load double, double* %14
%29 = fcmp oeq double %27, %28
br i1 %29, label %30, label %34
30: ; preds = %10
%31 = load double, double* %13
%32 = load double, double* %15
%33 = fcmp oeq double %31, %32
br i1 %33, label %42, label %34
34: ; preds = %30, %10
%35 = load double, double* %16
%36 = load double, double* %18
%37 = fcmp oeq double %35, %36
br i1 %37, label %38, label %43
38: ; preds = %34
%39 = load double, double* %17
%40 = load double, double* %19
%41 = fcmp oeq double %39, %40
br i1 %41, label %42, label %43
42: ; preds = %38, %30
store i32 0, i32* %11
br label %129
43: ; preds = %38, %34
%44 = load double, double* %12
%45 = load double, double* %14
%46 = fsub double %45, %44
store double %46, double* %14
%47 = load double, double* %13
%48 = load double, double* %15
%49 = fsub double %48, %47
store double %49, double* %15
%50 = load double, double* %12
%51 = load double, double* %16
%52 = fsub double %51, %50
store double %52, double* %16
%53 = load double, double* %13
%54 = load double, double* %17
%55 = fsub double %54, %53
store double %55, double* %17
%56 = load double, double* %12
%57 = load double, double* %18
%58 = fsub double %57, %56
store double %58, double* %18
%59 = load double, double* %13
%60 = load double, double* %19
%61 = fsub double %60, %59
store double %61, double* %19
%62 = load double, double* %14
%63 = load double, double* %14
%64 = load double, double* %15
%65 = load double, double* %15
%66 = fmul double %64, %65
%67 = call double @llvm.fmuladd.f64(double %62, double %63, double %66)
%68 = call double @sqrt(double %67)
store double %68, double* %22
%69 = load double, double* %14
%70 = load double, double* %22
%71 = fdiv double %69, %70
store double %71, double* %23
%72 = load double, double* %15
%73 = load double, double* %22
%74 = fdiv double %72, %73
store double %74, double* %24
%75 = load double, double* %16
%76 = load double, double* %23
%77 = load double, double* %17
%78 = load double, double* %24
%79 = fmul double %77, %78
%80 = call double @llvm.fmuladd.f64(double %75, double %76, double %79)
store double %80, double* %25
%81 = load double, double* %17
%82 = load double, double* %23
%83 = load double, double* %16
%84 = load double, double* %24
%85 = fmul double %83, %84
%86 = fneg double %85
%87 = call double @llvm.fmuladd.f64(double %81, double %82, double %86)
store double %87, double* %17
%88 = load double, double* %25
store double %88, double* %16
%89 = load double, double* %18
%90 = load double, double* %23
%91 = load double, double* %19
%92 = load double, double* %24
%93 = fmul double %91, %92
%94 = call double @llvm.fmuladd.f64(double %89, double %90, double %93)
store double %94, double* %25
%95 = load double, double* %19
%96 = load double, double* %23
%97 = load double, double* %18
%98 = load double, double* %24
%99 = fmul double %97, %98
%100 = fneg double %99
%101 = call double @llvm.fmuladd.f64(double %95, double %96, double %100)
store double %101, double* %19
%102 = load double, double* %25
store double %102, double* %18
%103 = load double, double* %17
%104 = load double, double* %19
%105 = fcmp oeq double %103, %104
br i1 %105, label %106, label %107
106: ; preds = %43
store i32 0, i32* %11
br label %129
107: ; preds = %43
%108 = load double, double* %18
%109 = load double, double* %16
%110 = load double, double* %18
%111 = fsub double %109, %110
%112 = load double, double* %19
%113 = fmul double %111, %112
%114 = load double, double* %19
%115 = load double, double* %17
%116 = fsub double %114, %115
%117 = fdiv double %113, %116
%118 = fadd double %108, %117
store double %118, double* %26
%119 = load double, double* %12
%120 = load double, double* %26
%121 = load double, double* %23
%122 = call double @llvm.fmuladd.f64(double %120, double %121, double %119)
%123 = load double*, double** %20
store double %122, double* %123
%124 = load double, double* %13
%125 = load double, double* %26
%126 = load double, double* %24
%127 = call double @llvm.fmuladd.f64(double %125, double %126, double %124)
%128 = load double*, double** %21
store double %127, double* %128
store i32 1, i32* %11
br label %129
129: ; preds = %107, %106, %42
%130 = load i32, i32* %11
ret i32 %130
}

LLVM IR (-O2):
define i32 @line_intersect(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double* nocapture writeonly %8, double* nocapture writeonly %9) {
%11 = fcmp oeq double %0, %2
%12 = fcmp oeq double %1, %3
%13 = and i1 %11, %12
br i1 %13, label %62, label %14
14: ; preds = %10
%15 = fcmp oeq double %4, %6
%16 = fcmp oeq double %5, %7
%17 = and i1 %15, %16
br i1 %17, label %62, label %18
18: ; preds = %14
%19 = fsub double %2, %0
%20 = fsub double %3, %1
%21 = insertelement <2 x double> poison, double %4, i64 0
%22 = insertelement <2 x double> %21, double %6, i64 1
%23 = insertelement <2 x double> poison, double %0, i64 0
%24 = shufflevector <2 x double> %23, <2 x double> poison, <2 x i32> zeroinitializer
%25 = fsub <2 x double> %22, %24
%26 = insertelement <2 x double> poison, double %5, i64 0
%27 = insertelement <2 x double> %26, double %7, i64 1
%28 = insertelement <2 x double> poison, double %1, i64 0
%29 = shufflevector <2 x double> %28, <2 x double> poison, <2 x i32> zeroinitializer
%30 = fsub <2 x double> %27, %29
%31 = fmul double %20, %20
%32 = tail call double @llvm.fmuladd.f64(double %19, double %19, double %31)
%33 = tail call double @sqrt(double %32)
%34 = fdiv double %19, %33
%35 = fdiv double %20, %33
%36 = extractelement <2 x double> %30, i64 1
%37 = fmul double %36, %35
%38 = extractelement <2 x double> %25, i64 1
%39 = tail call double @llvm.fmuladd.f64(double %38, double %34, double %37)
%40 = fneg <2 x double> %25
%41 = insertelement <2 x double> poison, double %35, i64 0
%42 = shufflevector <2 x double> %41, <2 x double> poison, <2 x i32> zeroinitializer
%43 = fmul <2 x double> %42, %40
%44 = insertelement <2 x double> poison, double %34, i64 0
%45 = shufflevector <2 x double> %44, <2 x double> poison, <2 x i32> zeroinitializer
%46 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %30, <2 x double> %45, <2 x double> %43)
%47 = extractelement <2 x double> %46, i64 0
%48 = extractelement <2 x double> %46, i64 1
%49 = fcmp oeq double %47, %48
br i1 %49, label %62, label %50
50: ; preds = %18
%51 = extractelement <2 x double> %30, i64 0
%52 = fmul double %51, %35
%53 = extractelement <2 x double> %25, i64 0
%54 = tail call double @llvm.fmuladd.f64(double %53, double %34, double %52)
%55 = fsub double %54, %39
%56 = fmul double %48, %55
%57 = fsub double %48, %47
%58 = fdiv double %56, %57
%59 = fadd double %39, %58
%60 = tail call double @llvm.fmuladd.f64(double %59, double %34, double %0)
store double %60, double* %8
%61 = tail call double @llvm.fmuladd.f64(double %59, double %35, double %1)
store double %61, double* %9
br label %62
62: ; preds = %50, %18, %10, %14
%63 = phi i32 [ 0, %14 ], [ 0, %10 ], [ 1, %50 ], [ 0, %18 ]
ret i32 %63
}