#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 */
int /*<<< orphan*/ linalg_crossProduct(float *, float *, float *);
int /*<<< orphan*/ linalg_normalize(float *);
void linalg_getFaceNormal(float *norm, float *pointa, float *pointb,
                          float *pointc) {
  float vect[2][3];
  int a, b;
  float point[3][3];
  for (a = 0; a < 3; ++a) {
    point[0][a] = pointa[a];
    point[1][a] = pointb[a];
    point[2][a] = pointc[a];
  }
  for (a = 0; a < 2; ++a) {
    for (b = 0; b < 3; ++b) {
      vect[a][b] = point[2 - a][b] - point[0][b];
    }
  }
  linalg_crossProduct(norm, vect[0], vect[1]);
  linalg_normalize(norm);
}


x86 assembly (clang, -O0):
<linalg_getFaceNormal>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
movl   $0x0,-0x44(%rbp)
cmpl   $0x3,-0x44(%rbp)
jge    119c <linalg_getFaceNormal+0x7c>
mov    -0x10(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movslq -0x44(%rbp),%rax
movss  %xmm0,-0x70(%rbp,%rax,4)
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movslq -0x44(%rbp),%rax
movss  %xmm0,-0x64(%rbp,%rax,4)
mov    -0x20(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movslq -0x44(%rbp),%rax
movss  %xmm0,-0x58(%rbp,%rax,4)
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    113f <linalg_getFaceNormal+0x1f>
movl   $0x0,-0x44(%rbp)
cmpl   $0x2,-0x44(%rbp)
jge    1220 <linalg_getFaceNormal+0x100>
movl   $0x0,-0x48(%rbp)
cmpl   $0x3,-0x48(%rbp)
jge    120d <linalg_getFaceNormal+0xed>
mov    $0x2,%eax
sub    -0x44(%rbp),%eax
movslq %eax,%rcx
lea    -0x70(%rbp),%rax
imul   $0xc,%rcx,%rcx
add    %rcx,%rax
movslq -0x48(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movslq -0x48(%rbp),%rax
subss  -0x70(%rbp,%rax,4),%xmm0
movslq -0x44(%rbp),%rcx
lea    -0x40(%rbp),%rax
imul   $0xc,%rcx,%rcx
add    %rcx,%rax
movslq -0x48(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x48(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x48(%rbp)
jmp    11b4 <linalg_getFaceNormal+0x94>
jmp    1212 <linalg_getFaceNormal+0xf2>
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    11a3 <linalg_getFaceNormal+0x83>
mov    -0x8(%rbp),%rdi
lea    -0x40(%rbp),%rsi
lea    -0x40(%rbp),%rdx
add    $0xc,%rdx
call   1040 <linalg_crossProduct@plt>
mov    -0x8(%rbp),%rdi
call   1030 <linalg_normalize@plt>
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<linalg_getFaceNormal>:
push   %rbx
sub    $0x20,%rsp
mov    %rdi,%rbx
movsd  0x4(%rsi),%xmm0
movss  0x4(%rdx),%xmm1
movss  0x8(%rdx),%xmm2
movsd  0x4(%rcx),%xmm3
movss  (%rcx),%xmm4
movlhps %xmm3,%xmm4
movss  (%rdx),%xmm5
shufps $0xd4,%xmm3,%xmm5
shufps $0x28,%xmm5,%xmm4
movss  (%rsi),%xmm3
movaps %xmm3,%xmm5
movlhps %xmm0,%xmm5
shufps $0xd4,%xmm0,%xmm3
shufps $0x28,%xmm3,%xmm5
subps  %xmm5,%xmm4
lea    0xc(%rsp),%rdx
movaps %xmm4,(%rsp)
subss  %xmm0,%xmm1
movss  %xmm1,0x10(%rsp)
shufps $0x55,%xmm0,%xmm0
subss  %xmm0,%xmm2
movss  %xmm2,0x14(%rsp)
mov    %rsp,%rsi
call   1040 <linalg_crossProduct@plt>
mov    %rbx,%rdi
call   1030 <linalg_normalize@plt>
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define void @linalg_getFaceNormal(float* %0, float* %1, float* %2, float* %3) {
%5 = alloca float*
%6 = alloca float*
%7 = alloca float*
%8 = alloca float*
%9 = alloca [2 x [3 x float]]
%10 = alloca i32
%11 = alloca i32
%12 = alloca [3 x [3 x float]]
store float* %0, float** %5
store float* %1, float** %6
store float* %2, float** %7
store float* %3, float** %8
store i32 0, i32* %10
br label %13
13: ; preds = %44, %4
%14 = load i32, i32* %10
%15 = icmp slt i32 %14, 3
br i1 %15, label %16, label %47
16: ; preds = %13
%17 = load float*, float** %6
%18 = load i32, i32* %10
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds float, float* %17, i64 %19
%21 = load float, float* %20
%22 = getelementptr inbounds [3 x [3 x float]], [3 x [3 x float]]* %12, i64 0, i64 0
%23 = load i32, i32* %10
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds [3 x float], [3 x float]* %22, i64 0, i64 %24
store float %21, float* %25
%26 = load float*, float** %7
%27 = load i32, i32* %10
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds float, float* %26, i64 %28
%30 = load float, float* %29
%31 = getelementptr inbounds [3 x [3 x float]], [3 x [3 x float]]* %12, i64 0, i64 1
%32 = load i32, i32* %10
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds [3 x float], [3 x float]* %31, i64 0, i64 %33
store float %30, float* %34
%35 = load float*, float** %8
%36 = load i32, i32* %10
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds float, float* %35, i64 %37
%39 = load float, float* %38
%40 = getelementptr inbounds [3 x [3 x float]], [3 x [3 x float]]* %12, i64 0, i64 2
%41 = load i32, i32* %10
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds [3 x float], [3 x float]* %40, i64 0, i64 %42
store float %39, float* %43
br label %44
44: ; preds = %16
%45 = load i32, i32* %10
%46 = add nsw i32 %45, 1
store i32 %46, i32* %10
br label %13
47: ; preds = %13
store i32 0, i32* %10
br label %48
48: ; preds = %80, %47
%49 = load i32, i32* %10
%50 = icmp slt i32 %49, 2
br i1 %50, label %51, label %83
51: ; preds = %48
store i32 0, i32* %11
br label %52
52: ; preds = %76, %51
%53 = load i32, i32* %11
%54 = icmp slt i32 %53, 3
br i1 %54, label %55, label %79
55: ; preds = %52
%56 = load i32, i32* %10
%57 = sub nsw i32 2, %56
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds [3 x [3 x float]], [3 x [3 x float]]* %12, i64 0, i64 %58
%60 = load i32, i32* %11
%61 = sext i32 %60 to i64
%62 = getelementptr inbounds [3 x float], [3 x float]* %59, i64 0, i64 %61
%63 = load float, float* %62
%64 = getelementptr inbounds [3 x [3 x float]], [3 x [3 x float]]* %12, i64 0, i64 0
%65 = load i32, i32* %11
%66 = sext i32 %65 to i64
%67 = getelementptr inbounds [3 x float], [3 x float]* %64, i64 0, i64 %66
%68 = load float, float* %67
%69 = fsub float %63, %68
%70 = load i32, i32* %10
%71 = sext i32 %70 to i64
%72 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %9, i64 0, i64 %71
%73 = load i32, i32* %11
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds [3 x float], [3 x float]* %72, i64 0, i64 %74
store float %69, float* %75
br label %76
76: ; preds = %55
%77 = load i32, i32* %11
%78 = add nsw i32 %77, 1
store i32 %78, i32* %11
br label %52
79: ; preds = %52
br label %80
80: ; preds = %79
%81 = load i32, i32* %10
%82 = add nsw i32 %81, 1
store i32 %82, i32* %10
br label %48
83: ; preds = %48
%84 = load float*, float** %5
%85 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %9, i64 0, i64 0
%86 = getelementptr inbounds [3 x float], [3 x float]* %85, i64 0, i64 0
%87 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %9, i64 0, i64 1
%88 = getelementptr inbounds [3 x float], [3 x float]* %87, i64 0, i64 0
%89 = call i32 @linalg_crossProduct(float* %84, float* %86, float* %88)
%90 = load float*, float** %5
%91 = call i32 @linalg_normalize(float* %90)
ret void
}

LLVM IR (-O2):
define void @linalg_getFaceNormal(float* %0, float* nocapture %1, float* nocapture %2, float* nocapture %3) {
%5 = alloca [2 x [3 x float]]
%6 = bitcast [2 x [3 x float]]* %5 to i8*
%7 = load float, float* %1
%8 = getelementptr inbounds float, float* %1, i64 1
%9 = bitcast float* %8 to <2 x float>*
%10 = load <2 x float>, <2 x float>* %9
%11 = load float, float* %2
%12 = getelementptr inbounds float, float* %2, i64 1
%13 = load float, float* %12
%14 = getelementptr inbounds float, float* %2, i64 2
%15 = load float, float* %14
%16 = load float, float* %3
%17 = getelementptr inbounds float, float* %3, i64 1
%18 = bitcast float* %17 to <2 x float>*
%19 = load <2 x float>, <2 x float>* %18
%20 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %5, i64 0, i64 0, i64 0
%21 = insertelement <4 x float> poison, float %16, i64 0
%22 = shufflevector <2 x float> %19, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
%23 = shufflevector <4 x float> %21, <4 x float> %22, <4 x i32> <i32 0, i32 4, i32 5, i32 undef>
%24 = insertelement <4 x float> %23, float %11, i64 3
%25 = insertelement <4 x float> poison, float %7, i64 0
%26 = shufflevector <2 x float> %10, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
%27 = shufflevector <4 x float> %25, <4 x float> %26, <4 x i32> <i32 0, i32 4, i32 5, i32 undef>
%28 = insertelement <4 x float> %27, float %7, i64 3
%29 = fsub <4 x float> %24, %28
%30 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %5, i64 0, i64 1, i64 0
%31 = bitcast [2 x [3 x float]]* %5 to <4 x float>*
store <4 x float> %29, <4 x float>* %31
%32 = extractelement <2 x float> %10, i64 0
%33 = fsub float %13, %32
%34 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %5, i64 0, i64 1, i64 1
store float %33, float* %34
%35 = extractelement <2 x float> %10, i64 1
%36 = fsub float %15, %35
%37 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %5, i64 0, i64 1, i64 2
store float %36, float* %37
%38 = call i32 @linalg_crossProduct(float* %0, float* %20, float* %30)
%39 = call i32 @linalg_normalize(float* %0)
ret void
}