int correct_orientation(double *p1, double *p2, double *p3, double *inp,
                        double *outp) {
  double normal[3];
  double v1[3], v2[3];
  double xcross, ycross, zcross;
  int numplus = 0, numminus = 0;
  normal[0] = outp[0] - inp[0];
  normal[1] = outp[1] - inp[1];
  normal[2] = outp[2] - inp[2];
  v1[0] = p2[0] - p1[0];
  v1[1] = p2[1] - p1[1];
  v1[2] = p2[2] - p1[2];
  v2[0] = p3[0] - p2[0];
  v2[1] = p3[1] - p2[1];
  v2[2] = p3[2] - p2[2];
  xcross = v1[1] * v2[2] - v1[2] * v2[1];
  ycross = v1[2] * v2[0] - v1[0] * v2[2];
  zcross = v1[0] * v2[1] - v1[1] * v2[0];
  if ((xcross * normal[0]) > 0)
    numplus++;
  else
    numminus++;
  if ((ycross * normal[1]) > 0)
    numplus++;
  else
    numminus++;
  if ((zcross * normal[2]) > 0)
    numplus++;
  else
    numminus++;
  if (numplus > numminus)
    return 1;
  else
    return 0;
}


x86 assembly (clang, -O0):
<correct_orientation>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
movl   $0x0,-0xac(%rbp)
movl   $0x0,-0xb0(%rbp)
mov    -0x30(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x28(%rbp),%rax
subsd  (%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x30(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x28(%rbp),%rax
subsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x30(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x28(%rbp),%rax
subsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x10(%rbp),%rax
subsd  (%rax),%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
subsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x10(%rbp),%rax
subsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
subsd  (%rax),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
subsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x18(%rbp),%rax
subsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  -0x80(%rbp),%xmm2
movsd  -0x60(%rbp),%xmm1
mulsd  -0x88(%rbp),%xmm1
ff
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
movsd  -0x60(%rbp),%xmm0
movsd  -0x90(%rbp),%xmm2
ff
movsd  -0x70(%rbp),%xmm1
mulsd  -0x80(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  -0x70(%rbp),%xmm0
movsd  -0x88(%rbp),%xmm2
ff
movsd  -0x68(%rbp),%xmm1
mulsd  -0x90(%rbp),%xmm1
ff
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  -0x98(%rbp),%xmm0
ff
mulsd  -0x50(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    12ea <correct_orientation+0x1ea>
mov    -0xac(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xac(%rbp)
jmp    12f9 <correct_orientation+0x1f9>
mov    -0xb0(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb0(%rbp)
movsd  -0xa0(%rbp),%xmm0
mulsd  -0x48(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1327 <correct_orientation+0x227>
mov    -0xac(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xac(%rbp)
jmp    1336 <correct_orientation+0x236>
mov    -0xb0(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb0(%rbp)
movsd  -0xa8(%rbp),%xmm0
ff
mulsd  -0x40(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1364 <correct_orientation+0x264>
mov    -0xac(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xac(%rbp)
jmp    1373 <correct_orientation+0x273>
mov    -0xb0(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb0(%rbp)
mov    -0xac(%rbp),%eax
cmp    -0xb0(%rbp),%eax
jle    1391 <correct_orientation+0x291>
movl   $0x1,-0x4(%rbp)
jmp    1398 <correct_orientation+0x298>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<correct_orientation>:
movsd  (%r8),%xmm2
subsd  (%rcx),%xmm2
movupd 0x8(%r8),%xmm8
movupd 0x8(%rcx),%xmm1
subpd  %xmm1,%xmm8
movupd (%rsi),%xmm3
movapd %xmm3,%xmm4
movupd (%rdx),%xmm0
subpd  %xmm3,%xmm0
unpckhpd %xmm3,%xmm3
subsd  0x8(%rdi),%xmm3
movsd  0x10(%rsi),%xmm5
unpcklpd %xmm5,%xmm4
movsd  (%rdi),%xmm6
movhpd 0x10(%rdi),%xmm6
subpd  %xmm6,%xmm4
movapd %xmm4,%xmm6
shufpd $0x1,%xmm4,%xmm6
movsd  0x10(%rdx),%xmm7
subsd  %xmm5,%xmm7
movapd %xmm4,%xmm5
unpckhpd %xmm4,%xmm5
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
mulsd  %xmm5,%xmm1
unpcklpd %xmm3,%xmm4
mulsd  %xmm7,%xmm3
subsd  %xmm1,%xmm3
mulsd  %xmm2,%xmm3
unpcklpd %xmm0,%xmm7
mulpd  %xmm4,%xmm7
mulpd  %xmm6,%xmm0
subpd  %xmm7,%xmm0
xorpd  %xmm1,%xmm1
xor    %r8d,%r8d
xor    %ecx,%ecx
ucomisd %xmm1,%xmm3
setbe  %r8b
seta   %cl
mulpd  %xmm8,%xmm0
lea    0x1(%rcx),%r9d
mov    $0x2,%esi
sub    %ecx,%esi
xorpd  %xmm1,%xmm1
cmpltpd %xmm0,%xmm1
movmskpd %xmm1,%edi
mov    %edi,%eax
and    $0x2,%al
mov    %eax,%edx
shr    %dl
test   $0x1,%dil
cmove  %ecx,%r9d
cmovne %r8d,%esi
movzbl %dl,%ecx
add    %r9d,%ecx
cmp    $0x1,%al
adc    $0x0,%esi
xor    %eax,%eax
cmp    %esi,%ecx
seta   %al
ret

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

LLVM IR (-O2):
define i32 @correct_orientation(double* nocapture %0, double* nocapture %1, double* nocapture %2, double* nocapture %3, double* nocapture %4) {
%6 = load double, double* %4
%7 = load double, double* %3
%8 = fsub double %6, %7
%9 = getelementptr inbounds double, double* %4, i64 1
%10 = getelementptr inbounds double, double* %3, i64 1
%11 = bitcast double* %9 to <2 x double>*
%12 = load <2 x double>, <2 x double>* %11
%13 = bitcast double* %10 to <2 x double>*
%14 = load <2 x double>, <2 x double>* %13
%15 = fsub <2 x double> %12, %14
%16 = load double, double* %0
%17 = bitcast double* %1 to <2 x double>*
%18 = load <2 x double>, <2 x double>* %17
%19 = getelementptr inbounds double, double* %0, i64 1
%20 = load double, double* %19
%21 = extractelement <2 x double> %18, i64 1
%22 = fsub double %21, %20
%23 = getelementptr inbounds double, double* %1, i64 2
%24 = load double, double* %23
%25 = getelementptr inbounds double, double* %0, i64 2
%26 = load double, double* %25
%27 = insertelement <2 x double> %18, double %24, i64 1
%28 = insertelement <2 x double> poison, double %16, i64 0
%29 = insertelement <2 x double> %28, double %26, i64 1
%30 = fsub <2 x double> %27, %29
%31 = shufflevector <2 x double> %30, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%32 = bitcast double* %2 to <2 x double>*
%33 = load <2 x double>, <2 x double>* %32
%34 = fsub <2 x double> %33, %18
%35 = getelementptr inbounds double, double* %2, i64 2
%36 = load double, double* %35
%37 = fsub double %36, %24
%38 = extractelement <2 x double> %30, i64 1
%39 = fneg double %38
%40 = extractelement <2 x double> %34, i64 1
%41 = fmul double %40, %39
%42 = tail call double @llvm.fmuladd.f64(double %22, double %37, double %41)
%43 = insertelement <2 x double> %30, double %22, i64 1
%44 = fneg <2 x double> %43
%45 = insertelement <2 x double> poison, double %37, i64 0
%46 = shufflevector <2 x double> %45, <2 x double> %34, <2 x i32> <i32 0, i32 2>
%47 = fmul <2 x double> %46, %44
%48 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %31, <2 x double> %34, <2 x double> %47)
%49 = fmul double %8, %42
%50 = fcmp ogt double %49, 0.000000e+00
%51 = zext i1 %50 to i32
%52 = xor i1 %50, true
%53 = zext i1 %52 to i32
%54 = select i1 %50, i32 2, i32 1
%55 = select i1 %50, i32 1, i32 2
%56 = fmul <2 x double> %15, %48
%57 = fcmp ogt <2 x double> %56, zeroinitializer
%58 = extractelement <2 x i1> %57, i64 0
%59 = select i1 %58, i32 %54, i32 %51
%60 = select i1 %58, i32 %53, i32 %55
%61 = extractelement <2 x i1> %57, i64 1
%62 = zext i1 %61 to i32
%63 = add nuw nsw i32 %59, %62
%64 = xor i1 %61, true
%65 = zext i1 %64 to i32
%66 = add nuw nsw i32 %60, %65
%67 = icmp ugt i32 %63, %66
%68 = zext i1 %67 to i32
ret i32 %68
}