#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 */
float sqrt(float);
void calc_normal(float v1[3], float v2[3], float v3[3], float normal[3]) {
  int i;
  float vec1[3], vec2[3];
  float norm;
  for (i = 0; i < 3; i++) {
    vec1[i] = v2[i] - v1[i];
    vec2[i] = v3[i] - v1[i];
  }
  normal[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
  normal[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
  normal[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
  norm = sqrt(normal[0] * normal[0] + normal[1] * normal[1] +
              normal[2] * normal[2]);
  for (i = 0; i < 3; i++) {
    normal[i] /= norm;
  }
}


x86 assembly (clang, -O0):
<calc_normal>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
cmpl   $0x3,-0x24(%rbp)
jge    118f <calc_normal+0x7f>
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
subss  (%rax,%rcx,4),%xmm0
movslq -0x24(%rbp),%rax
movss  %xmm0,-0x30(%rbp,%rax,4)
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
subss  (%rax,%rcx,4),%xmm0
movslq -0x24(%rbp),%rax
movss  %xmm0,-0x3c(%rbp,%rax,4)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    112f <calc_normal+0x1f>
movss  -0x2c(%rbp),%xmm0
movss  -0x34(%rbp),%xmm2
movss  -0x28(%rbp),%xmm1
mulss  -0x38(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x28(%rbp),%xmm0
movss  -0x3c(%rbp),%xmm2
movss  -0x30(%rbp),%xmm1
mulss  -0x34(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x30(%rbp),%xmm0
movss  -0x38(%rbp),%xmm2
movss  -0x2c(%rbp),%xmm1
mulss  -0x3c(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movss  %xmm0,0x8(%rax)
mov    -0x20(%rbp),%rax
movss  (%rax),%xmm1
mov    -0x20(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x20(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x20(%rbp),%rax
mulss  0x4(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x20(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x20(%rbp),%rax
movss  0x8(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
call   1030 <sqrt@plt>
movss  %xmm0,-0x40(%rbp)
movl   $0x0,-0x24(%rbp)
cmpl   $0x3,-0x24(%rbp)
jge    12ac <calc_normal+0x19c>
movss  -0x40(%rbp),%xmm1
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
divss  %xmm1,%xmm0
movss  %xmm0,(%rax,%rcx,4)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1279 <calc_normal+0x169>
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<calc_normal>:
push   %rbx
mov    %rcx,%rbx
movss  (%rsi),%xmm2
movss  0x4(%rsi),%xmm1
movss  (%rdi),%xmm3
movss  0x4(%rdi),%xmm4
subss  %xmm3,%xmm2
movss  (%rdx),%xmm5
movss  0x4(%rdx),%xmm0
subss  %xmm3,%xmm5
subss  %xmm4,%xmm1
subss  %xmm4,%xmm0
movss  0x8(%rsi),%xmm3
movss  0x8(%rdi),%xmm4
subss  %xmm4,%xmm3
movss  0x8(%rdx),%xmm6
subss  %xmm4,%xmm6
movaps %xmm0,%xmm4
mulss  %xmm3,%xmm4
movaps %xmm1,%xmm7
mulss  %xmm6,%xmm7
subss  %xmm4,%xmm7
movss  %xmm7,(%rcx)
mulss  %xmm2,%xmm6
mulss  %xmm5,%xmm3
subss  %xmm6,%xmm3
movss  %xmm3,0x4(%rcx)
mulss  %xmm5,%xmm1
mulss  %xmm2,%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,0x8(%rcx)
mulss  %xmm3,%xmm3
mulss  %xmm7,%xmm7
addss  %xmm3,%xmm7
mulss  %xmm0,%xmm0
addss  %xmm7,%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jb     11b0 <calc_normal+0xa0>
sqrtss %xmm0,%xmm0
jmp    11b5 <calc_normal+0xa5>
call   1030 <sqrt@plt>
movss  (%rbx),%xmm1
movss  0x4(%rbx),%xmm2
divss  %xmm0,%xmm1
movss  %xmm1,(%rbx)
divss  %xmm0,%xmm2
movss  %xmm2,0x4(%rbx)
movss  0x8(%rbx),%xmm1
divss  %xmm0,%xmm1
movss  %xmm1,0x8(%rbx)
pop    %rbx
ret

LLVM IR (-O0):
define void @calc_normal(float* %0, float* %1, float* %2, float* %3) {
%5 = alloca float*
%6 = alloca float*
%7 = alloca float*
%8 = alloca float*
%9 = alloca i32
%10 = alloca [3 x float]
%11 = alloca [3 x float]
%12 = alloca 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* %9
br label %13
13: ; preds = %45, %4
%14 = load i32, i32* %9
%15 = icmp slt i32 %14, 3
br i1 %15, label %16, label %48
16: ; preds = %13
%17 = load float*, float** %6
%18 = load i32, i32* %9
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds float, float* %17, i64 %19
%21 = load float, float* %20
%22 = load float*, float** %5
%23 = load i32, i32* %9
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds float, float* %22, i64 %24
%26 = load float, float* %25
%27 = fsub float %21, %26
%28 = load i32, i32* %9
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 %29
store float %27, float* %30
%31 = load float*, float** %7
%32 = load i32, i32* %9
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds float, float* %31, i64 %33
%35 = load float, float* %34
%36 = load float*, float** %5
%37 = load i32, i32* %9
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds float, float* %36, i64 %38
%40 = load float, float* %39
%41 = fsub float %35, %40
%42 = load i32, i32* %9
%43 = sext i32 %42 to i64
%44 = getelementptr inbounds [3 x float], [3 x float]* %11, i64 0, i64 %43
store float %41, float* %44
br label %45
45: ; preds = %16
%46 = load i32, i32* %9
%47 = add nsw i32 %46, 1
store i32 %47, i32* %9
br label %13
48: ; preds = %13
%49 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 1
%50 = load float, float* %49
%51 = getelementptr inbounds [3 x float], [3 x float]* %11, i64 0, i64 2
%52 = load float, float* %51
%53 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 2
%54 = load float, float* %53
%55 = getelementptr inbounds [3 x float], [3 x float]* %11, i64 0, i64 1
%56 = load float, float* %55
%57 = fmul float %54, %56
%58 = fneg float %57
%59 = call float @llvm.fmuladd.f32(float %50, float %52, float %58)
%60 = load float*, float** %8
%61 = getelementptr inbounds float, float* %60, i64 0
store float %59, float* %61
%62 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 2
%63 = load float, float* %62
%64 = getelementptr inbounds [3 x float], [3 x float]* %11, i64 0, i64 0
%65 = load float, float* %64
%66 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 0
%67 = load float, float* %66
%68 = getelementptr inbounds [3 x float], [3 x float]* %11, i64 0, i64 2
%69 = load float, float* %68
%70 = fmul float %67, %69
%71 = fneg float %70
%72 = call float @llvm.fmuladd.f32(float %63, float %65, float %71)
%73 = load float*, float** %8
%74 = getelementptr inbounds float, float* %73, i64 1
store float %72, float* %74
%75 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 0
%76 = load float, float* %75
%77 = getelementptr inbounds [3 x float], [3 x float]* %11, i64 0, i64 1
%78 = load float, float* %77
%79 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 1
%80 = load float, float* %79
%81 = getelementptr inbounds [3 x float], [3 x float]* %11, i64 0, i64 0
%82 = load float, float* %81
%83 = fmul float %80, %82
%84 = fneg float %83
%85 = call float @llvm.fmuladd.f32(float %76, float %78, float %84)
%86 = load float*, float** %8
%87 = getelementptr inbounds float, float* %86, i64 2
store float %85, float* %87
%88 = load float*, float** %8
%89 = getelementptr inbounds float, float* %88, i64 0
%90 = load float, float* %89
%91 = load float*, float** %8
%92 = getelementptr inbounds float, float* %91, i64 0
%93 = load float, float* %92
%94 = load float*, float** %8
%95 = getelementptr inbounds float, float* %94, i64 1
%96 = load float, float* %95
%97 = load float*, float** %8
%98 = getelementptr inbounds float, float* %97, i64 1
%99 = load float, float* %98
%100 = fmul float %96, %99
%101 = call float @llvm.fmuladd.f32(float %90, float %93, float %100)
%102 = load float*, float** %8
%103 = getelementptr inbounds float, float* %102, i64 2
%104 = load float, float* %103
%105 = load float*, float** %8
%106 = getelementptr inbounds float, float* %105, i64 2
%107 = load float, float* %106
%108 = call float @llvm.fmuladd.f32(float %104, float %107, float %101)
%109 = call float @sqrt(float %108)
store float %109, float* %12
store i32 0, i32* %9
br label %110
110: ; preds = %121, %48
%111 = load i32, i32* %9
%112 = icmp slt i32 %111, 3
br i1 %112, label %113, label %124
113: ; preds = %110
%114 = load float, float* %12
%115 = load float*, float** %8
%116 = load i32, i32* %9
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds float, float* %115, i64 %117
%119 = load float, float* %118
%120 = fdiv float %119, %114
store float %120, float* %118
br label %121
121: ; preds = %113
%122 = load i32, i32* %9
%123 = add nsw i32 %122, 1
store i32 %123, i32* %9
br label %110
124: ; preds = %110
ret void
}

LLVM IR (-O2):
define void @calc_normal(float* nocapture %0, float* nocapture %1, float* nocapture %2, float* nocapture %3) {
%5 = load float, float* %1
%6 = load float, float* %0
%7 = fsub float %5, %6
%8 = load float, float* %2
%9 = fsub float %8, %6
%10 = getelementptr inbounds float, float* %1, i64 1
%11 = load float, float* %10
%12 = getelementptr inbounds float, float* %0, i64 1
%13 = load float, float* %12
%14 = fsub float %11, %13
%15 = getelementptr inbounds float, float* %2, i64 1
%16 = load float, float* %15
%17 = fsub float %16, %13
%18 = getelementptr inbounds float, float* %1, i64 2
%19 = load float, float* %18
%20 = getelementptr inbounds float, float* %0, i64 2
%21 = load float, float* %20
%22 = fsub float %19, %21
%23 = getelementptr inbounds float, float* %2, i64 2
%24 = load float, float* %23
%25 = fsub float %24, %21
%26 = fneg float %22
%27 = fmul float %17, %26
%28 = tail call float @llvm.fmuladd.f32(float %14, float %25, float %27)
store float %28, float* %3
%29 = fneg float %7
%30 = fmul float %25, %29
%31 = tail call float @llvm.fmuladd.f32(float %22, float %9, float %30)
%32 = getelementptr inbounds float, float* %3, i64 1
store float %31, float* %32
%33 = fneg float %14
%34 = fmul float %9, %33
%35 = tail call float @llvm.fmuladd.f32(float %7, float %17, float %34)
%36 = getelementptr inbounds float, float* %3, i64 2
store float %35, float* %36
%37 = fmul float %31, %31
%38 = tail call float @llvm.fmuladd.f32(float %28, float %28, float %37)
%39 = tail call float @llvm.fmuladd.f32(float %35, float %35, float %38)
%40 = tail call float @sqrt(float %39)
%41 = load float, float* %3
%42 = fdiv float %41, %40
store float %42, float* %3
%43 = load float, float* %32
%44 = fdiv float %43, %40
store float %44, float* %32
%45 = load float, float* %36
%46 = fdiv float %45, %40
store float %46, float* %36
ret void
}