#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 */
typedef scalar_t__ uint16_t;

/* Variables and functions */
void cross(float *vertices, uint16_t *triangles, float *result, size_t amount) {
  size_t u, v, w;
  size_t triangle;
  float ux, uy, uz;
  float vx, vy, vz;
  float wx, wy, wz;
  while (amount-- > 0) {
    triangle = 3 * amount;
    u = 3 * ((size_t)triangles[triangle + 0]);
    v = 3 * ((size_t)triangles[triangle + 1]);
    w = 3 * ((size_t)triangles[triangle + 2]);
    wx = vertices[w + 0];
    wy = vertices[w + 1];
    wz = vertices[w + 2];
    ux = vertices[u + 0] - wx;
    uy = vertices[u + 1] - wy;
    uz = vertices[u + 2] - wz;
    vx = vertices[v + 0] - wx;
    vy = vertices[v + 1] - wy;
    vz = vertices[v + 2] - wz;
    result[triangle + 0] = uy * vz - uz * vy;
    result[triangle + 1] = uz * vx - ux * vz;
    result[triangle + 2] = ux * vy - uy * vx;
  }
}


x86 assembly (clang, -O0):
<cross>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x20(%rbp)
cmp    $0x0,%rax
jbe    12da <cross+0x1da>
imul   $0x3,-0x20(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x40(%rbp),%rcx
imul   $0x3,(%rax,%rcx,8),%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x40(%rbp),%rcx
imul   $0x3,0x8(%rax,%rcx,8),%rax
mov    %rax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x40(%rbp),%rcx
imul   $0x3,0x10(%rax,%rcx,8),%rax
mov    %rax,-0x38(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x5c(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
movss  0x4(%rax,%rcx,4),%xmm0
movss  %xmm0,-0x60(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
movss  0x8(%rax,%rcx,4),%xmm0
movss  %xmm0,-0x64(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
subss  -0x5c(%rbp),%xmm0
movss  %xmm0,-0x44(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  0x4(%rax,%rcx,4),%xmm0
subss  -0x60(%rbp),%xmm0
movss  %xmm0,-0x48(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  0x8(%rax,%rcx,4),%xmm0
subss  -0x64(%rbp),%xmm0
movss  %xmm0,-0x4c(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x30(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
subss  -0x5c(%rbp),%xmm0
movss  %xmm0,-0x50(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x30(%rbp),%rcx
movss  0x4(%rax,%rcx,4),%xmm0
subss  -0x60(%rbp),%xmm0
movss  %xmm0,-0x54(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x30(%rbp),%rcx
movss  0x8(%rax,%rcx,4),%xmm0
subss  -0x64(%rbp),%xmm0
movss  %xmm0,-0x58(%rbp)
movss  -0x48(%rbp),%xmm0
movss  -0x58(%rbp),%xmm2
movss  -0x4c(%rbp),%xmm1
mulss  -0x54(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
mov    -0x40(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movss  -0x4c(%rbp),%xmm0
movss  -0x50(%rbp),%xmm2
movss  -0x44(%rbp),%xmm1
mulss  -0x58(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
mov    -0x40(%rbp),%rcx
movss  %xmm0,0x4(%rax,%rcx,4)
movss  -0x44(%rbp),%xmm0
movss  -0x54(%rbp),%xmm2
movss  -0x48(%rbp),%xmm1
mulss  -0x50(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
mov    -0x40(%rbp),%rcx
movss  %xmm0,0x8(%rax,%rcx,4)
jmp    1114 <cross+0x14>
pop    %rbp
ret

x86 assembly (clang, -O2):
<cross>:
test   %rcx,%rcx
je     11ce <cross+0xce>
lea    (%rcx,%rcx,2),%rax
lea    -0x4(,%rax,4),%r10
ff
cs nopw 0x0(%rax,%rax,1)
nop
mov    -0x10(%rsi,%r10,2),%r8
mov    -0x8(%rsi,%r10,2),%r9
mov    (%rsi,%r10,2),%rax
lea    (%rax,%rax,2),%rax
movss  (%rdi,%rax,4),%xmm2
movss  0x4(%rdi,%rax,4),%xmm3
movss  0x8(%rdi,%rax,4),%xmm4
lea    (%r8,%r8,2),%rax
movss  (%rdi,%rax,4),%xmm0
movss  0x4(%rdi,%rax,4),%xmm1
subss  %xmm2,%xmm0
subss  %xmm3,%xmm1
movss  0x8(%rdi,%rax,4),%xmm5
subss  %xmm4,%xmm5
lea    (%r9,%r9,2),%rax
movss  (%rdi,%rax,4),%xmm6
movss  0x4(%rdi,%rax,4),%xmm7
subss  %xmm2,%xmm6
subss  %xmm3,%xmm7
movss  0x8(%rdi,%rax,4),%xmm2
subss  %xmm4,%xmm2
movaps %xmm7,%xmm3
mulss  %xmm5,%xmm3
mulss  %xmm6,%xmm5
mulss  %xmm1,%xmm6
mulss  %xmm2,%xmm1
subss  %xmm3,%xmm1
movss  %xmm1,-0x8(%rdx,%r10,1)
mulss  %xmm0,%xmm2
subss  %xmm2,%xmm5
movss  %xmm5,-0x4(%rdx,%r10,1)
mulss  %xmm0,%xmm7
subss  %xmm6,%xmm7
movss  %xmm7,(%rdx,%r10,1)
add    $0xfffffffffffffff4,%r10
add    $0xffffffffffffffff,%rcx
jne    1120 <cross+0x20>
ret

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

LLVM IR (-O2):
define void @cross(float* nocapture %0, i64* nocapture %1, float* nocapture writeonly %2, i64 %3) {
%5 = icmp eq i64 %3, 0
br i1 %5, label %64, label %6
6: ; preds = %4, %6
%7 = phi i64 [ %8, %6 ], [ %3, %4 ]
%8 = add i64 %7, -1
%9 = mul i64 %8, 3
%10 = getelementptr inbounds i64, i64* %1, i64 %9
%11 = load i64, i64* %10
%12 = mul i64 %11, 3
%13 = add i64 %9, 1
%14 = getelementptr inbounds i64, i64* %1, i64 %13
%15 = load i64, i64* %14
%16 = mul i64 %15, 3
%17 = add i64 %9, 2
%18 = getelementptr inbounds i64, i64* %1, i64 %17
%19 = load i64, i64* %18
%20 = mul i64 %19, 3
%21 = getelementptr inbounds float, float* %0, i64 %20
%22 = load float, float* %21
%23 = add i64 %20, 1
%24 = getelementptr inbounds float, float* %0, i64 %23
%25 = load float, float* %24
%26 = add i64 %20, 2
%27 = getelementptr inbounds float, float* %0, i64 %26
%28 = load float, float* %27
%29 = getelementptr inbounds float, float* %0, i64 %12
%30 = load float, float* %29
%31 = fsub float %30, %22
%32 = add i64 %12, 1
%33 = getelementptr inbounds float, float* %0, i64 %32
%34 = load float, float* %33
%35 = fsub float %34, %25
%36 = add i64 %12, 2
%37 = getelementptr inbounds float, float* %0, i64 %36
%38 = load float, float* %37
%39 = fsub float %38, %28
%40 = getelementptr inbounds float, float* %0, i64 %16
%41 = load float, float* %40
%42 = fsub float %41, %22
%43 = add i64 %16, 1
%44 = getelementptr inbounds float, float* %0, i64 %43
%45 = load float, float* %44
%46 = fsub float %45, %25
%47 = add i64 %16, 2
%48 = getelementptr inbounds float, float* %0, i64 %47
%49 = load float, float* %48
%50 = fsub float %49, %28
%51 = fneg float %39
%52 = fmul float %46, %51
%53 = tail call float @llvm.fmuladd.f32(float %35, float %50, float %52)
%54 = getelementptr inbounds float, float* %2, i64 %9
store float %53, float* %54
%55 = fneg float %31
%56 = fmul float %50, %55
%57 = tail call float @llvm.fmuladd.f32(float %39, float %42, float %56)
%58 = getelementptr inbounds float, float* %2, i64 %13
store float %57, float* %58
%59 = fneg float %35
%60 = fmul float %42, %59
%61 = tail call float @llvm.fmuladd.f32(float %31, float %46, float %60)
%62 = getelementptr inbounds float, float* %2, i64 %17
store float %61, float* %62
%63 = icmp eq i64 %8, 0
br i1 %63, label %64, label %6
64: ; preds = %6, %4
ret void
}