#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 */
scalar_t__ round(double);
void rgb2yuv(unsigned char *img, int size) {
  int r, g, b, i;
  double y, u, v;
  for (i = 0; i < size; i += 3) {
    r = (int)img[i];
    g = (int)img[i + 1];
    b = (int)img[i + 2];
    r = (r << 16) - 32768;
    g = (g << 16) - 32768;
    b = (b << 16) - 32768;
    y = (0.2124997 * r + 0.7153988 * g + 0.0721015 * b) / 76309 + 16;
    u = (-0.1171202 * r - 0.3942953 * g + 0.5114155 * b) / 76309 + 128;
    v = (0.5114155 * r - 0.4645915 * g - 0.0468239 * b) / 76309 + 128;
    if (y > 255)
      y = 255;
    if (y < 0)
      y = 0;
    if (u > 255)
      u = 255;
    if (u < 0)
      u = 0;
    if (v > 255)
      v = 255;
    if (v < 0)
      v = 0;
    img[i] = (unsigned char)round(y);
    img[i + 1] = (unsigned char)round(u);
    img[i + 2] = (unsigned char)round(v);
  }
}


x86 assembly (clang, -O0):
<rgb2yuv>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    13d4 <rgb2yuv+0x2c4>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x18(%rbp)
mov    -0x10(%rbp),%eax
shl    $0x10,%eax
sub    $0x8000,%eax
mov    %eax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
shl    $0x10,%eax
sub    $0x8000,%eax
mov    %eax,-0x14(%rbp)
mov    -0x18(%rbp),%eax
shl    $0x10,%eax
sub    $0x8000,%eax
mov    %eax,-0x18(%rbp)
cvtsi2sdl -0x10(%rbp),%xmm1
cvtsi2sdl -0x14(%rbp),%xmm2
movsd  0xeb3(%rip),%xmm0
mulsd  %xmm2,%xmm0
movsd  0xe9f(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
cvtsi2sdl -0x18(%rbp),%xmm0
movsd  0xe82(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xe3a(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  0xe5e(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
cvtsi2sdl -0x10(%rbp),%xmm1
cvtsi2sdl -0x14(%rbp),%xmm2
movsd  0xe3b(%rip),%xmm0
mulsd  %xmm2,%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xe10(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
cvtsi2sdl -0x18(%rbp),%xmm0
movsd  0xdeb(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xdcb(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  0xdb7(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
cvtsi2sdl -0x10(%rbp),%xmm1
cvtsi2sdl -0x14(%rbp),%xmm2
movsd  0xdbc(%rip),%xmm0
mulsd  %xmm2,%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xd91(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
cvtsi2sdl -0x18(%rbp),%xmm0
movsd  0xd74(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xd5c(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  0xd48(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xd2a(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12ed <rgb2yuv+0x1dd>
movsd  0xd18(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x28(%rbp),%xmm0
jbe    1303 <rgb2yuv+0x1f3>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  0xcf0(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1327 <rgb2yuv+0x217>
movsd  0xcde(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x30(%rbp),%xmm0
jbe    133d <rgb2yuv+0x22d>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  0xcb6(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1361 <rgb2yuv+0x251>
movsd  0xca4(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x38(%rbp),%xmm0
jbe    1377 <rgb2yuv+0x267>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
call   1030 <round@plt>
mov    %al,%dl
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
movsd  -0x30(%rbp),%xmm0
call   1030 <round@plt>
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
movsd  -0x38(%rbp),%xmm0
call   1030 <round@plt>
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x1c(%rbp)
jmp    1126 <rgb2yuv+0x16>
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rgb2yuv>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
test   %esi,%esi
jle    1279 <rgb2yuv+0x169>
mov    %esi,%r14d
mov    %rdi,%rbx
xor    %ebp,%ebp
jmp    1178 <rgb2yuv+0x68>
nopw   0x0(%rax,%rax,1)
movsd  %xmm3,0x8(%rsp)
movsd  0xeea(%rip),%xmm2
minsd  %xmm1,%xmm2
maxsd  %xmm2,%xmm0
call   1030 <round@plt>
mov    %al,(%rbx,%rbp,1)
movaps 0x10(%rsp),%xmm0
call   1030 <round@plt>
mov    %al,0x1(%rbx,%rbp,1)
movsd  0x8(%rsp),%xmm0
call   1030 <round@plt>
mov    %al,0x2(%rbx,%rbp,1)
add    $0x3,%rbp
cmp    %r14d,%ebp
jge    1279 <rgb2yuv+0x169>
movzbl (%rbx,%rbp,1),%eax
movzbl 0x1(%rbx,%rbp,1),%ecx
movzbl 0x2(%rbx,%rbp,1),%edx
shl    $0x10,%eax
add    $0xffff8000,%eax
shl    $0x10,%ecx
add    $0xffff8000,%ecx
shl    $0x10,%edx
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
add    $0xffff8000,%edx
xorps  %xmm2,%xmm2
cvtsi2sd %ecx,%xmm2
movapd %xmm2,%xmm1
mulsd  0xe46(%rip),%xmm1
movapd %xmm0,%xmm3
mulsd  0xe42(%rip),%xmm3
addsd  %xmm1,%xmm3
xorps  %xmm4,%xmm4
cvtsi2sd %edx,%xmm4
movapd %xmm4,%xmm1
mulsd  0xe33(%rip),%xmm1
addsd  %xmm3,%xmm1
divsd  0xe2f(%rip),%xmm1
addsd  0xe2f(%rip),%xmm1
unpcklpd %xmm2,%xmm2
mulpd  0xe33(%rip),%xmm2
unpcklpd %xmm0,%xmm0
mulpd  0xe37(%rip),%xmm0
addpd  %xmm2,%xmm0
unpcklpd %xmm4,%xmm4
mulpd  0xe37(%rip),%xmm4
addpd  %xmm0,%xmm4
divpd  0xe3b(%rip),%xmm4
addpd  0xe43(%rip),%xmm4
movapd 0xe4b(%rip),%xmm2
minpd  %xmm4,%xmm2
xorpd  %xmm0,%xmm0
movapd %xmm2,%xmm3
cmpltpd 0xe46(%rip),%xmm3
movmskpd %xmm3,%eax
xorpd  %xmm3,%xmm3
test   $0x2,%al
jne    125e <rgb2yuv+0x14e>
movapd %xmm2,%xmm3
unpckhpd %xmm2,%xmm3
movapd %xmm3,0x10(%rsp)
xorpd  %xmm3,%xmm3
test   $0x1,%al
jne    1130 <rgb2yuv+0x20>
movapd %xmm2,%xmm3
jmp    1130 <rgb2yuv+0x20>
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define void @rgb2yuv(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca double
%10 = alloca double
%11 = alloca double
store i8* %0, i8** %3
store i32 %1, i32* %4
store i32 0, i32* %8
br label %12
12: ; preds = %128, %2
%13 = load i32, i32* %8
%14 = load i32, i32* %4
%15 = icmp slt i32 %13, %14
br i1 %15, label %16, label %131
16: ; preds = %12
%17 = load i8*, i8** %3
%18 = load i32, i32* %8
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds i8, i8* %17, i64 %19
%21 = load i8, i8* %20
%22 = zext i8 %21 to i32
store i32 %22, i32* %5
%23 = load i8*, i8** %3
%24 = load i32, i32* %8
%25 = add nsw i32 %24, 1
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds i8, i8* %23, i64 %26
%28 = load i8, i8* %27
%29 = zext i8 %28 to i32
store i32 %29, i32* %6
%30 = load i8*, i8** %3
%31 = load i32, i32* %8
%32 = add nsw i32 %31, 2
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds i8, i8* %30, i64 %33
%35 = load i8, i8* %34
%36 = zext i8 %35 to i32
store i32 %36, i32* %7
%37 = load i32, i32* %5
%38 = shl i32 %37, 16
%39 = sub nsw i32 %38, 32768
store i32 %39, i32* %5
%40 = load i32, i32* %6
%41 = shl i32 %40, 16
%42 = sub nsw i32 %41, 32768
store i32 %42, i32* %6
%43 = load i32, i32* %7
%44 = shl i32 %43, 16
%45 = sub nsw i32 %44, 32768
store i32 %45, i32* %7
%46 = load i32, i32* %5
%47 = sitofp i32 %46 to double
%48 = load i32, i32* %6
%49 = sitofp i32 %48 to double
%50 = fmul double 0x3FE6E48C06331FE8, %49
%51 = call double @llvm.fmuladd.f64(double 0x3FCB3330AEF474B2, double %47, double %50)
%52 = load i32, i32* %7
%53 = sitofp i32 %52 to double
%54 = call double @llvm.fmuladd.f64(double 0x3FB2753E707E175D, double %53, double %51)
%55 = fdiv double %54, 7.630900e+04
%56 = fadd double %55, 1.600000e+01
store double %56, double* %9
%57 = load i32, i32* %5
%58 = sitofp i32 %57 to double
%59 = load i32, i32* %6
%60 = sitofp i32 %59 to double
%61 = fmul double 0x3FD93C225A9DDB48, %60
%62 = fneg double %61
%63 = call double @llvm.fmuladd.f64(double 0xBFBDFB96E4B3735F, double %58, double %62)
%64 = load i32, i32* %7
%65 = sitofp i32 %64 to double
%66 = call double @llvm.fmuladd.f64(double 0x3FE05D8409E55C10, double %65, double %63)
%67 = fdiv double %66, 7.630900e+04
%68 = fadd double %67, 1.280000e+02
store double %68, double* %10
%69 = load i32, i32* %5
%70 = sitofp i32 %69 to double
%71 = load i32, i32* %6
%72 = sitofp i32 %71 to double
%73 = fmul double 0x3FDDBBDDFC9FF92F, %72
%74 = fneg double %73
%75 = call double @llvm.fmuladd.f64(double 0x3FE05D8409E55C10, double %70, double %74)
%76 = load i32, i32* %7
%77 = sitofp i32 %76 to double
%78 = call double @llvm.fmuladd.f64(double -4.682390e-02, double %77, double %75)
%79 = fdiv double %78, 7.630900e+04
%80 = fadd double %79, 1.280000e+02
store double %80, double* %11
%81 = load double, double* %9
%82 = fcmp ogt double %81, 2.550000e+02
br i1 %82, label %83, label %84
83: ; preds = %16
store double 2.550000e+02, double* %9
br label %84
84: ; preds = %83, %16
%85 = load double, double* %9
%86 = fcmp olt double %85, 0.000000e+00
br i1 %86, label %87, label %88
87: ; preds = %84
store double 0.000000e+00, double* %9
br label %88
88: ; preds = %87, %84
%89 = load double, double* %10
%90 = fcmp ogt double %89, 2.550000e+02
br i1 %90, label %91, label %92
91: ; preds = %88
store double 2.550000e+02, double* %10
br label %92
92: ; preds = %91, %88
%93 = load double, double* %10
%94 = fcmp olt double %93, 0.000000e+00
br i1 %94, label %95, label %96
95: ; preds = %92
store double 0.000000e+00, double* %10
br label %96
96: ; preds = %95, %92
%97 = load double, double* %11
%98 = fcmp ogt double %97, 2.550000e+02
br i1 %98, label %99, label %100
99: ; preds = %96
store double 2.550000e+02, double* %11
br label %100
100: ; preds = %99, %96
%101 = load double, double* %11
%102 = fcmp olt double %101, 0.000000e+00
br i1 %102, label %103, label %104
103: ; preds = %100
store double 0.000000e+00, double* %11
br label %104
104: ; preds = %103, %100
%105 = load double, double* %9
%106 = call i64 @round(double %105)
%107 = trunc i64 %106 to i8
%108 = load i8*, i8** %3
%109 = load i32, i32* %8
%110 = sext i32 %109 to i64
%111 = getelementptr inbounds i8, i8* %108, i64 %110
store i8 %107, i8* %111
%112 = load double, double* %10
%113 = call i64 @round(double %112)
%114 = trunc i64 %113 to i8
%115 = load i8*, i8** %3
%116 = load i32, i32* %8
%117 = add nsw i32 %116, 1
%118 = sext i32 %117 to i64
%119 = getelementptr inbounds i8, i8* %115, i64 %118
store i8 %114, i8* %119
%120 = load double, double* %11
%121 = call i64 @round(double %120)
%122 = trunc i64 %121 to i8
%123 = load i8*, i8** %3
%124 = load i32, i32* %8
%125 = add nsw i32 %124, 2
%126 = sext i32 %125 to i64
%127 = getelementptr inbounds i8, i8* %123, i64 %126
store i8 %122, i8* %127
br label %128
128: ; preds = %104
%129 = load i32, i32* %8
%130 = add nsw i32 %129, 3
store i32 %130, i32* %8
br label %12
131: ; preds = %12
ret void
}

LLVM IR (-O2):
define void @rgb2yuv(i8* nocapture %0, i32 %1) {
%3 = icmp sgt i32 %1, 0
br i1 %3, label %4, label %64
4: ; preds = %2, %4
%5 = phi i64 [ %61, %4 ], [ 0, %2 ]
%6 = getelementptr inbounds i8, i8* %0, i64 %5
%7 = load i8, i8* %6
%8 = zext i8 %7 to i32
%9 = add nuw nsw i64 %5, 1
%10 = getelementptr inbounds i8, i8* %0, i64 %9
%11 = load i8, i8* %10
%12 = zext i8 %11 to i32
%13 = add nuw nsw i64 %5, 2
%14 = getelementptr inbounds i8, i8* %0, i64 %13
%15 = load i8, i8* %14
%16 = zext i8 %15 to i32
%17 = shl nuw nsw i32 %8, 16
%18 = add nsw i32 %17, -32768
%19 = shl nuw nsw i32 %12, 16
%20 = add nsw i32 %19, -32768
%21 = shl nuw nsw i32 %16, 16
%22 = add nsw i32 %21, -32768
%23 = sitofp i32 %18 to double
%24 = sitofp i32 %20 to double
%25 = fmul double %24, 0x3FE6E48C06331FE8
%26 = tail call double @llvm.fmuladd.f64(double %23, double 0x3FCB3330AEF474B2, double %25)
%27 = sitofp i32 %22 to double
%28 = tail call double @llvm.fmuladd.f64(double %27, double 0x3FB2753E707E175D, double %26)
%29 = fdiv double %28, 7.630900e+04
%30 = fadd double %29, 1.600000e+01
%31 = insertelement <2 x double> poison, double %24, i64 0
%32 = shufflevector <2 x double> %31, <2 x double> poison, <2 x i32> zeroinitializer
%33 = fmul <2 x double> %32, <double 0xBFDDBBDDFC9FF92F, double 0xBFD93C225A9DDB48>
%34 = insertelement <2 x double> poison, double %23, i64 0
%35 = shufflevector <2 x double> %34, <2 x double> poison, <2 x i32> zeroinitializer
%36 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %35, <2 x double> <double 0x3FE05D8409E55C10, double 0xBFBDFB96E4B3735F>, <2 x double> %33)
%37 = insertelement <2 x double> poison, double %27, i64 0
%38 = shufflevector <2 x double> %37, <2 x double> poison, <2 x i32> zeroinitializer
%39 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %38, <2 x double> <double -4.682390e-02, double 0x3FE05D8409E55C10>, <2 x double> %36)
%40 = fdiv <2 x double> %39, <double 7.630900e+04, double 7.630900e+04>
%41 = fadd <2 x double> %40, <double 1.280000e+02, double 1.280000e+02>
%42 = fcmp ogt double %30, 2.550000e+02
%43 = select i1 %42, double 2.550000e+02, double %30
%44 = fcmp olt double %43, 0.000000e+00
%45 = select i1 %44, double 0.000000e+00, double %43
%46 = fcmp ogt <2 x double> %41, <double 2.550000e+02, double 2.550000e+02>
%47 = select <2 x i1> %46, <2 x double> <double 2.550000e+02, double 2.550000e+02>, <2 x double> %41
%48 = fcmp olt <2 x double> %47, zeroinitializer
%49 = extractelement <2 x i1> %48, i64 1
%50 = extractelement <2 x double> %47, i64 1
%51 = select i1 %49, double 0.000000e+00, double %50
%52 = extractelement <2 x i1> %48, i64 0
%53 = extractelement <2 x double> %47, i64 0
%54 = select i1 %52, double 0.000000e+00, double %53
%55 = tail call i64 @round(double %45)
%56 = trunc i64 %55 to i8
store i8 %56, i8* %6
%57 = tail call i64 @round(double %51)
%58 = trunc i64 %57 to i8
store i8 %58, i8* %10
%59 = tail call i64 @round(double %54)
%60 = trunc i64 %59 to i8
store i8 %60, i8* %14
%61 = add nuw i64 %5, 3
%62 = trunc i64 %61 to i32
%63 = icmp slt i32 %62, %1
br i1 %63, label %4, label %64
64: ; preds = %4, %2
ret void
}