#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 */
void calculate_row(float *principal_components, float *pc_deviations,
                   float coefficient_difference, size_t row, float *face,
                   size_t dimensions, size_t vertices) {
  while (vertices-- > 0) {
    face[vertices] += principal_components[vertices * dimensions + row] *
                      coefficient_difference * pc_deviations[row];
  }
}


x86 assembly (clang, -O0):
<calculate_row>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movss  %xmm0,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x38(%rbp)
cmp    $0x0,%rax
jbe    1181 <calculate_row+0x81>
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
imul   -0x30(%rbp),%rcx
add    -0x20(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mulss  -0x14(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,(%rax,%rcx,4)
jmp    1121 <calculate_row+0x21>
pop    %rbp
ret

x86 assembly (clang, -O2):
<calculate_row>:
push   %rbx
test   %r9,%r9
je     11b5 <calculate_row+0xb5>
mov    %r9,%rbx
test   $0x1,%r9b
je     113d <calculate_row+0x3d>
lea    -0x1(%r9),%rbx
mov    %rbx,%rax
imul   %r8,%rax
add    %rdx,%rax
movss  (%rdi,%rax,4),%xmm1
mulss  %xmm0,%xmm1
mulss  (%rsi,%rdx,4),%xmm1
addss  -0x4(%rcx,%r9,4),%xmm1
movss  %xmm1,-0x4(%rcx,%r9,4)
cmp    $0x1,%r9
je     11b5 <calculate_row+0xb5>
lea    -0x2(%rbx),%r9
imul   %r8,%r9
lea    (%rdi,%rdx,4),%rdi
lea    0x0(,%r8,8),%r10
neg    %r10
lea    -0x1(%rbx),%r11
imul   %r8,%r11
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movss  (%rdi,%r11,4),%xmm1
mulss  %xmm0,%xmm1
mulss  (%rsi,%rdx,4),%xmm1
addss  -0x4(%rcx,%rbx,4),%xmm1
movss  %xmm1,-0x4(%rcx,%rbx,4)
movss  (%rdi,%r9,4),%xmm1
mulss  %xmm0,%xmm1
mulss  (%rsi,%rdx,4),%xmm1
addss  -0x8(%rcx,%rbx,4),%xmm1
movss  %xmm1,-0x8(%rcx,%rbx,4)
lea    -0x2(%rbx),%rax
add    %r10,%rdi
mov    %rax,%rbx
test   %rax,%rax
jne    1170 <calculate_row+0x70>
pop    %rbx
ret

LLVM IR (-O0):
define void @calculate_row(float* %0, float* %1, float %2, i64 %3, float* %4, i64 %5, i64 %6) {
%8 = alloca float*
%9 = alloca float*
%10 = alloca float
%11 = alloca i64
%12 = alloca float*
%13 = alloca i64
%14 = alloca i64
store float* %0, float** %8
store float* %1, float** %9
store float %2, float* %10
store i64 %3, i64* %11
store float* %4, float** %12
store i64 %5, i64* %13
store i64 %6, i64* %14
br label %15
15: ; preds = %19, %7
%16 = load i64, i64* %14
%17 = add i64 %16, -1
store i64 %17, i64* %14
%18 = icmp ugt i64 %16, 0
br i1 %18, label %19, label %39
19: ; preds = %15
%20 = load float*, float** %8
%21 = load i64, i64* %14
%22 = load i64, i64* %13
%23 = mul i64 %21, %22
%24 = load i64, i64* %11
%25 = add i64 %23, %24
%26 = getelementptr inbounds float, float* %20, i64 %25
%27 = load float, float* %26
%28 = load float, float* %10
%29 = fmul float %27, %28
%30 = load float*, float** %9
%31 = load i64, i64* %11
%32 = getelementptr inbounds float, float* %30, i64 %31
%33 = load float, float* %32
%34 = load float*, float** %12
%35 = load i64, i64* %14
%36 = getelementptr inbounds float, float* %34, i64 %35
%37 = load float, float* %36
%38 = call float @llvm.fmuladd.f32(float %29, float %33, float %37)
store float %38, float* %36
br label %15
39: ; preds = %15
ret void
}

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