int lineseg_colide(double *p1, double *p2, double *p3, double *p4) {
  double a1, a2, a3, a4;
  a1 = (p2[0] - p1[0]) * (p3[1] - p2[1]) - (p2[1] - p1[1]) * (p3[0] - p2[0]);
  a2 = (p2[0] - p1[0]) * (p4[1] - p2[1]) - (p2[1] - p1[1]) * (p4[0] - p2[0]);
  a3 = (p4[0] - p3[0]) * (p1[1] - p4[1]) - (p4[1] - p3[1]) * (p1[0] - p4[0]);
  a4 = (p4[0] - p3[0]) * (p2[1] - p4[1]) - (p4[1] - p3[1]) * (p2[0] - p4[0]);
  if ((a1 > 0 && a2 > 0) || (a1 < 0 && a2 < 0) || (a3 > 0 && a4 > 0) ||
      (a3 < 0 && a4 < 0))
    return 0;
  return 1;
}


x86 assembly (clang, -O0):
<lineseg_colide>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x10(%rbp),%rax
subsd  (%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x18(%rbp),%rax
subsd  0x8(%rax),%xmm2
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm1
mov    -0x10(%rbp),%rax
subsd  0x8(%rax),%xmm1
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm3
mov    -0x18(%rbp),%rax
subsd  (%rax),%xmm3
mulsd  %xmm3,%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x10(%rbp),%rax
subsd  (%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x18(%rbp),%rax
subsd  0x8(%rax),%xmm2
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm1
mov    -0x10(%rbp),%rax
subsd  0x8(%rax),%xmm1
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm3
mov    -0x18(%rbp),%rax
subsd  (%rax),%xmm3
mulsd  %xmm3,%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x20(%rbp),%rax
subsd  (%rax),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x28(%rbp),%rax
subsd  0x8(%rax),%xmm2
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm1
mov    -0x20(%rbp),%rax
subsd  0x8(%rax),%xmm1
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm3
mov    -0x28(%rbp),%rax
subsd  (%rax),%xmm3
mulsd  %xmm3,%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x20(%rbp),%rax
subsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x28(%rbp),%rax
subsd  0x8(%rax),%xmm2
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm1
mov    -0x20(%rbp),%rax
subsd  0x8(%rax),%xmm1
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm3
mov    -0x28(%rbp),%rax
subsd  (%rax),%xmm3
mulsd  %xmm3,%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x30(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    12e8 <lineseg_colide+0x1e8>
movsd  -0x38(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
ja     1344 <lineseg_colide+0x244>
xorps  %xmm0,%xmm0
ucomisd -0x30(%rbp),%xmm0
jbe    1304 <lineseg_colide+0x204>
xorps  %xmm0,%xmm0
ucomisd -0x38(%rbp),%xmm0
ja     1344 <lineseg_colide+0x244>
movsd  -0x40(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1328 <lineseg_colide+0x228>
movsd  -0x48(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
ja     1344 <lineseg_colide+0x244>
xorps  %xmm0,%xmm0
ucomisd -0x40(%rbp),%xmm0
jbe    1350 <lineseg_colide+0x250>
xorps  %xmm0,%xmm0
ucomisd -0x48(%rbp),%xmm0
jbe    1350 <lineseg_colide+0x250>
movl   $0x0,-0x4(%rbp)
jmp    1357 <lineseg_colide+0x257>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<lineseg_colide>:
movsd  (%rsi),%xmm2
movsd  0x8(%rsi),%xmm3
movsd  (%rdi),%xmm11
movsd  0x8(%rdi),%xmm10
movapd %xmm2,%xmm1
subsd  %xmm11,%xmm1
movsd  (%rdx),%xmm9
movsd  0x8(%rdx),%xmm8
movapd %xmm8,%xmm4
subsd  %xmm3,%xmm4
movapd %xmm3,%xmm0
subsd  %xmm10,%xmm0
movapd %xmm9,%xmm5
subsd  %xmm2,%xmm5
mulsd  %xmm0,%xmm5
mulsd  %xmm1,%xmm4
subsd  %xmm5,%xmm4
movsd  (%rcx),%xmm12
movsd  0x8(%rcx),%xmm7
movapd %xmm7,%xmm5
subsd  %xmm3,%xmm5
movapd %xmm12,%xmm6
subsd  %xmm2,%xmm6
mulsd  %xmm0,%xmm6
mulsd  %xmm1,%xmm5
subsd  %xmm6,%xmm5
xor    %eax,%eax
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm4
jbe    1189 <lineseg_colide+0x89>
ucomisd %xmm1,%xmm5
jbe    1189 <lineseg_colide+0x89>
ret
ucomisd %xmm4,%xmm1
jbe    1199 <lineseg_colide+0x99>
xorpd  %xmm0,%xmm0
ucomisd %xmm5,%xmm0
ja     1188 <lineseg_colide+0x88>
movapd %xmm12,%xmm0
subsd  %xmm9,%xmm0
subsd  %xmm7,%xmm10
subsd  %xmm7,%xmm3
subsd  %xmm8,%xmm7
subsd  %xmm12,%xmm11
mulsd  %xmm7,%xmm11
mulsd  %xmm0,%xmm10
subsd  %xmm11,%xmm10
subsd  %xmm12,%xmm2
mulsd  %xmm7,%xmm2
mulsd  %xmm0,%xmm3
subsd  %xmm2,%xmm3
xorpd  %xmm2,%xmm2
ucomisd %xmm2,%xmm10
jbe    11e7 <lineseg_colide+0xe7>
ucomisd %xmm2,%xmm3
ja     1188 <lineseg_colide+0x88>
ucomisd %xmm10,%xmm2
setbe  %al
ucomisd %xmm3,%xmm2
setbe  %cl
or     %al,%cl
movzbl %cl,%eax
ret

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

LLVM IR (-O2):
define i32 @lineseg_colide(double* nocapture %0, double* nocapture %1, double* nocapture %2, double* nocapture %3) {
%5 = load double, double* %1
%6 = load double, double* %0
%7 = fsub double %5, %6
%8 = getelementptr inbounds double, double* %2, i64 1
%9 = load double, double* %8
%10 = getelementptr inbounds double, double* %1, i64 1
%11 = load double, double* %10
%12 = fsub double %9, %11
%13 = getelementptr inbounds double, double* %0, i64 1
%14 = load double, double* %13
%15 = fsub double %11, %14
%16 = load double, double* %2
%17 = fsub double %16, %5
%18 = fneg double %15
%19 = fmul double %17, %18
%20 = tail call double @llvm.fmuladd.f64(double %7, double %12, double %19)
%21 = getelementptr inbounds double, double* %3, i64 1
%22 = load double, double* %21
%23 = fsub double %22, %11
%24 = load double, double* %3
%25 = fsub double %24, %5
%26 = fmul double %25, %18
%27 = tail call double @llvm.fmuladd.f64(double %7, double %23, double %26)
%28 = fsub double %24, %16
%29 = fsub double %14, %22
%30 = fsub double %22, %9
%31 = fsub double %6, %24
%32 = fneg double %30
%33 = fmul double %31, %32
%34 = tail call double @llvm.fmuladd.f64(double %28, double %29, double %33)
%35 = fsub double %11, %22
%36 = fsub double %5, %24
%37 = fmul double %36, %32
%38 = tail call double @llvm.fmuladd.f64(double %28, double %35, double %37)
%39 = fcmp ogt double %20, 0.000000e+00
%40 = fcmp ogt double %27, 0.000000e+00
%41 = select i1 %39, i1 %40, i1 false
br i1 %41, label %55, label %42
42: ; preds = %4
%43 = fcmp olt double %20, 0.000000e+00
%44 = fcmp olt double %27, 0.000000e+00
%45 = select i1 %43, i1 %44, i1 false
br i1 %45, label %55, label %46
46: ; preds = %42
%47 = fcmp ogt double %34, 0.000000e+00
%48 = fcmp ogt double %38, 0.000000e+00
%49 = select i1 %47, i1 %48, i1 false
br i1 %49, label %55, label %50
50: ; preds = %46
%51 = fcmp uge double %34, 0.000000e+00
%52 = fcmp uge double %38, 0.000000e+00
%53 = select i1 %51, i1 true, i1 %52
%54 = zext i1 %53 to i32
br label %55
55: ; preds = %50, %4, %42, %46
%56 = phi i32 [ 0, %46 ], [ 0, %42 ], [ 0, %4 ], [ %54, %50 ]
ret i32 %56
}