#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 lldet3(long double, long double, long double, long double, long double,
              long double, long double, long double, long double);
double orient3d(double *pa, double *pb, double *pc, double *pd) {
  long double a = pa[0] - pd[0], b = pb[0] - pd[0], c = pc[0] - pd[0];
  long double d = pa[1] - pd[1], e = pb[1] - pd[1], f = pc[1] - pd[1];
  long double g = pa[2] - pd[2], h = pb[2] - pd[2], i = pc[2] - pd[2];
  return lldet3(a, b, c, d, e, f, g, h, i);
}


x86 assembly (clang, -O0):
<orient3d>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1a0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xb8(%rbp)
ff
fldl   -0xb8(%rbp)
fstpt  -0x30(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xc0(%rbp)
ff
fldl   -0xc0(%rbp)
fstpt  -0x40(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xc8(%rbp)
ff
fldl   -0xc8(%rbp)
fstpt  -0x50(%rbp)
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xd0(%rbp)
ff
fldl   -0xd0(%rbp)
fstpt  -0x60(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xd8(%rbp)
ff
fldl   -0xd8(%rbp)
fstpt  -0x70(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xe0(%rbp)
ff
fldl   -0xe0(%rbp)
fstpt  -0x80(%rbp)
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xe8(%rbp)
ff
fldl   -0xe8(%rbp)
fstpt  -0x90(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xf0(%rbp)
ff
fldl   -0xf0(%rbp)
fstpt  -0xa0(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xf8(%rbp)
ff
fldl   -0xf8(%rbp)
fstpt  -0xb0(%rbp)
fldt   -0x30(%rbp)
fstpt  -0x104(%rbp)
fldt   -0x40(%rbp)
fldt   -0x50(%rbp)
fldt   -0x60(%rbp)
fldt   -0x70(%rbp)
fldt   -0x80(%rbp)
fldt   -0x90(%rbp)
fldt   -0xa0(%rbp)
fstpt  -0x110(%rbp)
fldt   -0xb0(%rbp)
mov    %rsp,%rax
fstpt  0x80(%rax)
fldt   -0x110(%rbp)
fstpt  0x70(%rax)
fldt   -0x104(%rbp)
fxch   %st(1)
fstpt  0x60(%rax)
fxch   %st(1)
fstpt  0x50(%rax)
fxch   %st(1)
fstpt  0x40(%rax)
fxch   %st(1)
fstpt  0x30(%rax)
fxch   %st(1)
fstpt  0x20(%rax)
fxch   %st(1)
fstpt  0x10(%rax)
fstpt  (%rax)
call   1030 <lldet3@plt>
add    $0x1a0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<orient3d>:
sub    $0xf8,%rsp
movsd  (%rdi),%xmm0
movsd  0x8(%rdi),%xmm1
movsd  (%rcx),%xmm2
movsd  0x8(%rcx),%xmm3
subsd  %xmm2,%xmm0
movsd  %xmm0,0xc8(%rsp)
fldl   0xc8(%rsp)
fstpt  0xec(%rsp)
movsd  (%rsi),%xmm0
movsd  0x8(%rsi),%xmm4
subsd  %xmm2,%xmm0
movsd  %xmm0,0xd0(%rsp)
fldl   0xd0(%rsp)
fstpt  0xe0(%rsp)
movsd  (%rdx),%xmm0
movsd  0x8(%rdx),%xmm5
subsd  %xmm2,%xmm0
movsd  %xmm0,0xd8(%rsp)
fldl   0xd8(%rsp)
subsd  %xmm3,%xmm1
movsd  %xmm1,0x98(%rsp)
fldl   0x98(%rsp)
subsd  %xmm3,%xmm4
movsd  %xmm4,0xa0(%rsp)
fldl   0xa0(%rsp)
subsd  %xmm3,%xmm5
movsd  %xmm5,0xa8(%rsp)
fldl   0xa8(%rsp)
movsd  0x10(%rdi),%xmm0
movsd  0x10(%rcx),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,0xb0(%rsp)
fldl   0xb0(%rsp)
movsd  0x10(%rsi),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,0xb8(%rsp)
movsd  0x10(%rdx),%xmm0
subsd  %xmm1,%xmm0
fldl   0xb8(%rsp)
movsd  %xmm0,0xc0(%rsp)
fldl   0xc0(%rsp)
fstpt  0x80(%rsp)
fstpt  0x70(%rsp)
fstpt  0x60(%rsp)
fstpt  0x50(%rsp)
fstpt  0x40(%rsp)
fstpt  0x30(%rsp)
fstpt  0x20(%rsp)
fldt   0xe0(%rsp)
fstpt  0x10(%rsp)
fldt   0xec(%rsp)
fstpt  (%rsp)
call   1030 <lldet3@plt>
add    $0xf8,%rsp
ret

LLVM IR (-O0):
define double @orient3d(double* %0, double* %1, double* %2, double* %3) {
%5 = alloca double*
%6 = alloca double*
%7 = alloca double*
%8 = alloca double*
%9 = alloca x86_fp80
%10 = alloca x86_fp80
%11 = alloca x86_fp80
%12 = alloca x86_fp80
%13 = alloca x86_fp80
%14 = alloca x86_fp80
%15 = alloca x86_fp80
%16 = alloca x86_fp80
%17 = alloca x86_fp80
store double* %0, double** %5
store double* %1, double** %6
store double* %2, double** %7
store double* %3, double** %8
%18 = load double*, double** %5
%19 = getelementptr inbounds double, double* %18, i64 0
%20 = load double, double* %19
%21 = load double*, double** %8
%22 = getelementptr inbounds double, double* %21, i64 0
%23 = load double, double* %22
%24 = fsub double %20, %23
%25 = fpext double %24 to x86_fp80
store x86_fp80 %25, x86_fp80* %9
%26 = load double*, double** %6
%27 = getelementptr inbounds double, double* %26, i64 0
%28 = load double, double* %27
%29 = load double*, double** %8
%30 = getelementptr inbounds double, double* %29, i64 0
%31 = load double, double* %30
%32 = fsub double %28, %31
%33 = fpext double %32 to x86_fp80
store x86_fp80 %33, x86_fp80* %10
%34 = load double*, double** %7
%35 = getelementptr inbounds double, double* %34, i64 0
%36 = load double, double* %35
%37 = load double*, double** %8
%38 = getelementptr inbounds double, double* %37, i64 0
%39 = load double, double* %38
%40 = fsub double %36, %39
%41 = fpext double %40 to x86_fp80
store x86_fp80 %41, x86_fp80* %11
%42 = load double*, double** %5
%43 = getelementptr inbounds double, double* %42, i64 1
%44 = load double, double* %43
%45 = load double*, double** %8
%46 = getelementptr inbounds double, double* %45, i64 1
%47 = load double, double* %46
%48 = fsub double %44, %47
%49 = fpext double %48 to x86_fp80
store x86_fp80 %49, x86_fp80* %12
%50 = load double*, double** %6
%51 = getelementptr inbounds double, double* %50, i64 1
%52 = load double, double* %51
%53 = load double*, double** %8
%54 = getelementptr inbounds double, double* %53, i64 1
%55 = load double, double* %54
%56 = fsub double %52, %55
%57 = fpext double %56 to x86_fp80
store x86_fp80 %57, x86_fp80* %13
%58 = load double*, double** %7
%59 = getelementptr inbounds double, double* %58, i64 1
%60 = load double, double* %59
%61 = load double*, double** %8
%62 = getelementptr inbounds double, double* %61, i64 1
%63 = load double, double* %62
%64 = fsub double %60, %63
%65 = fpext double %64 to x86_fp80
store x86_fp80 %65, x86_fp80* %14
%66 = load double*, double** %5
%67 = getelementptr inbounds double, double* %66, i64 2
%68 = load double, double* %67
%69 = load double*, double** %8
%70 = getelementptr inbounds double, double* %69, i64 2
%71 = load double, double* %70
%72 = fsub double %68, %71
%73 = fpext double %72 to x86_fp80
store x86_fp80 %73, x86_fp80* %15
%74 = load double*, double** %6
%75 = getelementptr inbounds double, double* %74, i64 2
%76 = load double, double* %75
%77 = load double*, double** %8
%78 = getelementptr inbounds double, double* %77, i64 2
%79 = load double, double* %78
%80 = fsub double %76, %79
%81 = fpext double %80 to x86_fp80
store x86_fp80 %81, x86_fp80* %16
%82 = load double*, double** %7
%83 = getelementptr inbounds double, double* %82, i64 2
%84 = load double, double* %83
%85 = load double*, double** %8
%86 = getelementptr inbounds double, double* %85, i64 2
%87 = load double, double* %86
%88 = fsub double %84, %87
%89 = fpext double %88 to x86_fp80
store x86_fp80 %89, x86_fp80* %17
%90 = load x86_fp80, x86_fp80* %9
%91 = load x86_fp80, x86_fp80* %10
%92 = load x86_fp80, x86_fp80* %11
%93 = load x86_fp80, x86_fp80* %12
%94 = load x86_fp80, x86_fp80* %13
%95 = load x86_fp80, x86_fp80* %14
%96 = load x86_fp80, x86_fp80* %15
%97 = load x86_fp80, x86_fp80* %16
%98 = load x86_fp80, x86_fp80* %17
%99 = call double @lldet3(x86_fp80 %90, x86_fp80 %91, x86_fp80 %92, x86_fp80 %93, x86_fp80 %94, x86_fp80 %95, x86_fp80 %96, x86_fp80 %97, x86_fp80 %98)
ret double %99
}

LLVM IR (-O2):
define double @orient3d(double* nocapture %0, double* nocapture %1, double* nocapture %2, double* nocapture %3) {
%5 = load double, double* %0
%6 = load double, double* %3
%7 = fsub double %5, %6
%8 = fpext double %7 to x86_fp80
%9 = load double, double* %1
%10 = fsub double %9, %6
%11 = fpext double %10 to x86_fp80
%12 = load double, double* %2
%13 = fsub double %12, %6
%14 = fpext double %13 to x86_fp80
%15 = getelementptr inbounds double, double* %0, i64 1
%16 = load double, double* %15
%17 = getelementptr inbounds double, double* %3, i64 1
%18 = load double, double* %17
%19 = fsub double %16, %18
%20 = fpext double %19 to x86_fp80
%21 = getelementptr inbounds double, double* %1, i64 1
%22 = load double, double* %21
%23 = fsub double %22, %18
%24 = fpext double %23 to x86_fp80
%25 = getelementptr inbounds double, double* %2, i64 1
%26 = load double, double* %25
%27 = fsub double %26, %18
%28 = fpext double %27 to x86_fp80
%29 = getelementptr inbounds double, double* %0, i64 2
%30 = load double, double* %29
%31 = getelementptr inbounds double, double* %3, i64 2
%32 = load double, double* %31
%33 = fsub double %30, %32
%34 = fpext double %33 to x86_fp80
%35 = getelementptr inbounds double, double* %1, i64 2
%36 = load double, double* %35
%37 = fsub double %36, %32
%38 = fpext double %37 to x86_fp80
%39 = getelementptr inbounds double, double* %2, i64 2
%40 = load double, double* %39
%41 = fsub double %40, %32
%42 = fpext double %41 to x86_fp80
%43 = tail call double @lldet3(x86_fp80 %8, x86_fp80 %11, x86_fp80 %14, x86_fp80 %20, x86_fp80 %24, x86_fp80 %28, x86_fp80 %34, x86_fp80 %38, x86_fp80 %42)
ret double %43
}