#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*/ fail(char *);
int vector_rgb2gray(float *r, float *a, int n) {
  if (n != 3)
    fail("vgray needs a 3-vector");
  *r = 0.299 * a[0] + 0.587 * a[1] + 0.114 * a[2];
  return 1;
}


x86 assembly (clang, -O0):
<vector_rgb2gray>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
cmpl   $0x3,-0x14(%rbp)
je     1139 <vector_rgb2gray+0x29>
lea    0xee4(%rip),%rdi
call   1030 <fail@plt>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
cvtss2sd %xmm0,%xmm2
movsd  0xeb6(%rip),%xmm0
mulsd  %xmm2,%xmm0
movsd  0xea2(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe7d(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
mov    $0x1,%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<vector_rgb2gray>:
push   %r14
push   %rbx
push   %rax
mov    %rsi,%rbx
mov    %rdi,%r14
cmp    $0x3,%edx
je     112b <vector_rgb2gray+0x1b>
lea    0xef2(%rip),%rdi
call   1030 <fail@plt>
movss  (%rbx),%xmm0
movss  0x4(%rbx),%xmm1
cvtss2sd %xmm0,%xmm0
cvtss2sd %xmm1,%xmm1
mulsd  0xebc(%rip),%xmm1
mulsd  0xebc(%rip),%xmm0
addsd  %xmm1,%xmm0
movss  0x8(%rbx),%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  0xeaf(%rip),%xmm1
addsd  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
movss  %xmm0,(%r14)
mov    $0x1,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
@.str = [23 x i8] c"vgray needs a 3-vector\00"
define i32 @vector_rgb2gray(float* %0, float* %1, i32 %2) {
%4 = alloca float*
%5 = alloca float*
%6 = alloca i32
store float* %0, float** %4
store float* %1, float** %5
store i32 %2, i32* %6
%7 = load i32, i32* %6
%8 = icmp ne i32 %7, 3
br i1 %8, label %9, label %11
9: ; preds = %3
%10 = call i32 @fail(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i64 0, i64 0))
br label %11
11: ; preds = %9, %3
%12 = load float*, float** %5
%13 = getelementptr inbounds float, float* %12, i64 0
%14 = load float, float* %13
%15 = fpext float %14 to double
%16 = load float*, float** %5
%17 = getelementptr inbounds float, float* %16, i64 1
%18 = load float, float* %17
%19 = fpext float %18 to double
%20 = fmul double 5.870000e-01, %19
%21 = call double @llvm.fmuladd.f64(double 2.990000e-01, double %15, double %20)
%22 = load float*, float** %5
%23 = getelementptr inbounds float, float* %22, i64 2
%24 = load float, float* %23
%25 = fpext float %24 to double
%26 = call double @llvm.fmuladd.f64(double 1.140000e-01, double %25, double %21)
%27 = fptrunc double %26 to float
%28 = load float*, float** %4
store float %27, float* %28
ret i32 1
}

LLVM IR (-O2):
@.str = [23 x i8] c"vgray needs a 3-vector\00"
define i32 @vector_rgb2gray(float* nocapture writeonly %0, float* nocapture %1, i32 %2) {
%4 = icmp eq i32 %2, 3
br i1 %4, label %7, label %5
5: ; preds = %3
%6 = tail call i32 @fail(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i64 0, i64 0))
br label %7
7: ; preds = %5, %3
%8 = load float, float* %1
%9 = fpext float %8 to double
%10 = getelementptr inbounds float, float* %1, i64 1
%11 = load float, float* %10
%12 = fpext float %11 to double
%13 = fmul double %12, 5.870000e-01
%14 = tail call double @llvm.fmuladd.f64(double %9, double 2.990000e-01, double %13)
%15 = getelementptr inbounds float, float* %1, i64 2
%16 = load float, float* %15
%17 = fpext float %16 to double
%18 = tail call double @llvm.fmuladd.f64(double %17, double 1.140000e-01, double %14)
%19 = fptrunc double %18 to float
store float %19, float* %0
ret i32 1
}