int on_left_side(_Complex double *z, _Complex double *z0, _Complex double *z1,
                 double eps) {
  double delta = cimag((*z1 - *z) * conj(*z0 - *z));
  if (delta > eps)
    return 1;
  else if (delta < -eps)
    return -1;
  return 0;
}


x86 assembly (clang, -O0):
<on_left_side>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
movsd  %xmm0,-0x28(%rbp)
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm1
movsd  0x8(%rax),%xmm2
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm3
movsd  0x8(%rax),%xmm0
subsd  %xmm3,%xmm1
movsd  %xmm1,-0x60(%rbp)
subsd  %xmm0,%xmm2
movsd  %xmm2,-0x58(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm4
movsd  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm5
movsd  0x8(%rax),%xmm3
subsd  %xmm5,%xmm4
movsd  %xmm4,-0x50(%rbp)
subsd  %xmm3,%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm5
movsd  %xmm5,-0x48(%rbp)
movaps %xmm1,%xmm0
mulsd  %xmm4,%xmm0
movaps %xmm2,%xmm3
mulsd  %xmm5,%xmm3
mulsd  %xmm5,%xmm1
mulsd  %xmm4,%xmm2
subsd  %xmm3,%xmm0
addsd  %xmm2,%xmm1
movsd  %xmm1,-0x40(%rbp)
ucomisd %xmm0,%xmm0
movsd  %xmm1,-0x38(%rbp)
jnp    11ec <on_left_side+0xec>
movsd  -0x40(%rbp),%xmm1
ucomisd %xmm1,%xmm1
movsd  %xmm1,-0x38(%rbp)
jnp    11ec <on_left_side+0xec>
movsd  -0x48(%rbp),%xmm3
movsd  -0x50(%rbp),%xmm2
movsd  -0x58(%rbp),%xmm1
movsd  -0x60(%rbp),%xmm0
call   1260 <__muldc3>
movsd  %xmm1,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
ucomisd -0x28(%rbp),%xmm0
jbe    1212 <on_left_side+0x112>
movl   $0x1,-0x4(%rbp)
jmp    1255 <on_left_side+0x155>
movsd  -0x30(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
ucomisd %xmm1,%xmm0
jbe    1249 <on_left_side+0x149>
movl   $0xffffffff,-0x4(%rbp)
jmp    1255 <on_left_side+0x155>
jmp    124e <on_left_side+0x14e>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret
xchg   %ax,%ax

x86 assembly (clang, -O2):
<on_left_side>:
sub    $0x18,%rsp
movapd %xmm0,%xmm5
movupd (%rdx),%xmm0
movupd (%rdi),%xmm3
subpd  %xmm3,%xmm0
movapd %xmm0,%xmm1
shufpd $0x1,%xmm0,%xmm1
movupd (%rsi),%xmm2
subpd  %xmm3,%xmm2
movapd %xmm0,%xmm3
mulpd  %xmm2,%xmm3
movapd %xmm3,%xmm4
unpckhpd %xmm3,%xmm4
addsd  %xmm3,%xmm4
mulpd  %xmm2,%xmm1
movapd %xmm1,%xmm3
unpckhpd %xmm1,%xmm3
subsd  %xmm3,%xmm1
ucomisd %xmm4,%xmm4
jp     1177 <on_left_side+0x77>
movapd 0xea9(%rip),%xmm0
xorpd  %xmm5,%xmm0
xor    %ecx,%ecx
ucomisd %xmm1,%xmm0
seta   %cl
neg    %ecx
ucomisd %xmm5,%xmm1
mov    $0x1,%eax
cmovbe %ecx,%eax
add    $0x18,%rsp
ret
ucomisd %xmm1,%xmm1
jnp    114f <on_left_side+0x4f>
movapd %xmm2,%xmm3
unpckhpd %xmm2,%xmm3
xorpd  0xe73(%rip),%xmm3
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
movapd %xmm5,(%rsp)
call   11b0 <__muldc3>
movapd (%rsp),%xmm5
jmp    114f <on_left_side+0x4f>
cs nopw 0x0(%rax,%rax,1)

LLVM IR (-O0):
define i32 @on_left_side({ double, double }* %0, { double, double }* %1, { double, double }* %2, double %3) {
%5 = alloca i32
%6 = alloca { double, double }*
%7 = alloca { double, double }*
%8 = alloca { double, double }*
%9 = alloca double
%10 = alloca double
store { double, double }* %0, { double, double }** %6
store { double, double }* %1, { double, double }** %7
store { double, double }* %2, { double, double }** %8
store double %3, double* %9
%11 = load { double, double }*, { double, double }** %8
%12 = getelementptr inbounds { double, double }, { double, double }* %11, i32 0, i32 0
%13 = load double, double* %12
%14 = getelementptr inbounds { double, double }, { double, double }* %11, i32 0, i32 1
%15 = load double, double* %14
%16 = load { double, double }*, { double, double }** %6
%17 = getelementptr inbounds { double, double }, { double, double }* %16, i32 0, i32 0
%18 = load double, double* %17
%19 = getelementptr inbounds { double, double }, { double, double }* %16, i32 0, i32 1
%20 = load double, double* %19
%21 = fsub double %13, %18
%22 = fsub double %15, %20
%23 = load { double, double }*, { double, double }** %7
%24 = getelementptr inbounds { double, double }, { double, double }* %23, i32 0, i32 0
%25 = load double, double* %24
%26 = getelementptr inbounds { double, double }, { double, double }* %23, i32 0, i32 1
%27 = load double, double* %26
%28 = load { double, double }*, { double, double }** %6
%29 = getelementptr inbounds { double, double }, { double, double }* %28, i32 0, i32 0
%30 = load double, double* %29
%31 = getelementptr inbounds { double, double }, { double, double }* %28, i32 0, i32 1
%32 = load double, double* %31
%33 = fsub double %25, %30
%34 = fsub double %27, %32
%35 = fneg double %34
%36 = fmul double %21, %33
%37 = fmul double %22, %35
%38 = fmul double %21, %35
%39 = fmul double %22, %33
%40 = fsub double %36, %37
%41 = fadd double %38, %39
%42 = fcmp uno double %40, %40
br i1 %42, label %43, label %49
43: ; preds = %4
%44 = fcmp uno double %41, %41
br i1 %44, label %45, label %49
45: ; preds = %43
%46 = call { double, double } @__muldc3(double %21, double %22, double %33, double %35)
%47 = extractvalue { double, double } %46, 0
%48 = extractvalue { double, double } %46, 1
br label %49
49: ; preds = %45, %43, %4
%50 = phi double [ %40, %4 ], [ %40, %43 ], [ %47, %45 ]
%51 = phi double [ %41, %4 ], [ %41, %43 ], [ %48, %45 ]
store double %51, double* %10
%52 = load double, double* %10
%53 = load double, double* %9
%54 = fcmp ogt double %52, %53
br i1 %54, label %55, label %56
55: ; preds = %49
store i32 1, i32* %5
br label %64
56: ; preds = %49
%57 = load double, double* %10
%58 = load double, double* %9
%59 = fneg double %58
%60 = fcmp olt double %57, %59
br i1 %60, label %61, label %62
61: ; preds = %56
store i32 -1, i32* %5
br label %64
62: ; preds = %56
br label %63
63: ; preds = %62
store i32 0, i32* %5
br label %64
64: ; preds = %63, %61, %55
%65 = load i32, i32* %5
ret i32 %65
}

LLVM IR (-O2):
define i32 @on_left_side({ double, double }* nocapture %0, { double, double }* nocapture %1, { double, double }* nocapture %2, double %3) {
%5 = bitcast { double, double }* %2 to <2 x double>*
%6 = load <2 x double>, <2 x double>* %5
%7 = bitcast { double, double }* %0 to <2 x double>*
%8 = load <2 x double>, <2 x double>* %7
%9 = fsub <2 x double> %6, %8
%10 = shufflevector <2 x double> %9, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%11 = bitcast { double, double }* %1 to <2 x double>*
%12 = load <2 x double>, <2 x double>* %11
%13 = fsub <2 x double> %12, %8
%14 = extractelement <2 x double> %13, i64 1
%15 = fneg double %14
%16 = fmul <2 x double> %9, %13
%17 = shufflevector <2 x double> %16, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%18 = fadd <2 x double> %16, %17
%19 = extractelement <2 x double> %18, i64 0
%20 = fmul <2 x double> %10, %13
%21 = shufflevector <2 x double> %20, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%22 = fsub <2 x double> %20, %21
%23 = extractelement <2 x double> %22, i64 0
%24 = fcmp uno double %19, 0.000000e+00
br i1 %24, label %25, label %33
25: ; preds = %4
%26 = fcmp uno double %23, 0.000000e+00
br i1 %26, label %27, label %33
27: ; preds = %25
%28 = extractelement <2 x double> %9, i64 0
%29 = extractelement <2 x double> %9, i64 1
%30 = extractelement <2 x double> %13, i64 0
%31 = tail call { double, double } @__muldc3(double %28, double %29, double %30, double %15)
%32 = extractvalue { double, double } %31, 1
br label %33
33: ; preds = %27, %25, %4
%34 = phi double [ %23, %4 ], [ %23, %25 ], [ %32, %27 ]
%35 = fcmp ogt double %34, %3
%36 = fneg double %3
%37 = fcmp olt double %34, %36
%38 = sext i1 %37 to i32
%39 = select i1 %35, i32 1, i32 %38
ret i32 %39
}