#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__ GLushort;
typedef double GLubyte;
typedef scalar_t__ GLint;
typedef double GLfloat;

/* Variables and functions */
void ConvertRGBtoYUV(GLint w, GLint h, GLint texel_bytes, const GLubyte *src,
                     GLushort *dest) {
  GLint i, j;
  for (i = 0; i < h; i++) {
    for (j = 0; j < w; j++) {
      const GLfloat r = (src[0]) / 255.0;
      const GLfloat g = (src[1]) / 255.0;
      const GLfloat b = (src[2]) / 255.0;
      GLfloat y, cr, cb;
      GLint iy, icr, icb;
      y = r * 65.481 + g * 128.553 + b * 24.966 + 16;
      cb = r * -37.797 + g * -74.203 + b * 112.0 + 128;
      cr = r * 112.0 + g * -93.786 + b * -18.214 + 128;
      iy = (GLint)((y) < (0) ? (0) : ((y) > (254) ? (254) : (y)));
      icb = (GLint)((cb) < (0) ? (0) : ((cb) > (254) ? (254) : (cb)));
      icr = (GLint)((cr) < (0) ? (0) : ((cr) > (254) ? (254) : (cr)));
      if (j & 1) {
        *dest = (iy << 8) | icr;
      } else {
        *dest = (iy << 8) | icb;
      }
      dest++;
      src += texel_bytes;
    }
  }
}


x86 assembly (clang, -O0):
<ConvertRGBtoYUV>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%rax
cmp    -0x10(%rbp),%rax
jge    1455 <ConvertRGBtoYUV+0x355>
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x8(%rbp),%rax
jge    143f <ConvertRGBtoYUV+0x33f>
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xef8(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  0xede(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm0
movsd  0xec4(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x40(%rbp),%xmm1
movsd  0xea6(%rip),%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  0xe91(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
movsd  0xe74(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xe5c(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x40(%rbp),%xmm1
movsd  0xe3e(%rip),%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  0xe29(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
movsd  0xe04(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xde4(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x40(%rbp),%xmm1
movsd  0xde6(%rip),%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  0xdd1(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
movsd  0xdb4(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xd9c(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x58(%rbp),%xmm0
jbe    128b <ConvertRGBtoYUV+0x18b>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
jmp    12d4 <ConvertRGBtoYUV+0x1d4>
movsd  -0x58(%rbp),%xmm0
movsd  0xdc0(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12b7 <ConvertRGBtoYUV+0x1b7>
movsd  0xdae(%rip),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
jmp    12c4 <ConvertRGBtoYUV+0x1c4>
movsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x88(%rbp),%xmm0
ff
cvttsd2si %xmm0,%rax
mov    %rax,-0x70(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x68(%rbp),%xmm0
jbe    1303 <ConvertRGBtoYUV+0x203>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
jmp    134c <ConvertRGBtoYUV+0x24c>
movsd  -0x68(%rbp),%xmm0
movsd  0xd48(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    132f <ConvertRGBtoYUV+0x22f>
movsd  0xd36(%rip),%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
jmp    133c <ConvertRGBtoYUV+0x23c>
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  -0xa0(%rbp),%xmm0
ff
movsd  %xmm0,-0x98(%rbp)
ff
movsd  -0x98(%rbp),%xmm0
ff
cvttsd2si %xmm0,%rax
mov    %rax,-0x80(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x60(%rbp),%xmm0
jbe    137b <ConvertRGBtoYUV+0x27b>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
jmp    13c4 <ConvertRGBtoYUV+0x2c4>
movsd  -0x60(%rbp),%xmm0
movsd  0xcd0(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    13a7 <ConvertRGBtoYUV+0x2a7>
movsd  0xcbe(%rip),%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
jmp    13b4 <ConvertRGBtoYUV+0x2b4>
movsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
movsd  -0xb0(%rbp),%xmm0
ff
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  -0xa8(%rbp),%xmm0
ff
cvttsd2si %xmm0,%rax
mov    %rax,-0x78(%rbp)
mov    -0x38(%rbp),%rax
and    $0x1,%rax
cmp    $0x0,%rax
je     13ff <ConvertRGBtoYUV+0x2ff>
mov    -0x70(%rbp),%rcx
shl    $0x8,%rcx
or     -0x78(%rbp),%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,(%rax)
jmp    1412 <ConvertRGBtoYUV+0x312>
mov    -0x70(%rbp),%rcx
shl    $0x8,%rcx
or     -0x80(%rbp),%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x28(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x3,%rax
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    113a <ConvertRGBtoYUV+0x3a>
jmp    1444 <ConvertRGBtoYUV+0x344>
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    1124 <ConvertRGBtoYUV+0x24>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ConvertRGBtoYUV>:
test   %rsi,%rsi
jle    1272 <ConvertRGBtoYUV+0x172>
shl    $0x3,%rdx
xor    %r9d,%r9d
movsd  0xee8(%rip),%xmm0
movsd  0xf07(%rip),%xmm12
movsd  0xf06(%rip),%xmm13
movsd  0xf05(%rip),%xmm14
movsd  0xf04(%rip),%xmm15
movsd  0xf04(%rip),%xmm2
movsd  0xf04(%rip),%xmm3
xorpd  %xmm4,%xmm4
movsd  0xf00(%rip),%xmm5
jmp    116d <ConvertRGBtoYUV+0x6d>
nopw   0x0(%rax,%rax,1)
add    $0x1,%r9
cmp    %rsi,%r9
je     1272 <ConvertRGBtoYUV+0x172>
test   %rdi,%rdi
jle    1160 <ConvertRGBtoYUV+0x60>
xor    %r10d,%r10d
jmp    11de <ConvertRGBtoYUV+0xde>
nopw   0x0(%rax,%rax,1)
mulsd  %xmm14,%xmm9
addsd  %xmm8,%xmm9
addsd  %xmm9,%xmm11
movapd %xmm11,%xmm6
movapd %xmm3,%xmm1
minsd  %xmm7,%xmm1
cmpltsd %xmm4,%xmm7
andnpd %xmm1,%xmm7
cvttsd2si %xmm7,%rax
addsd  %xmm5,%xmm6
movapd %xmm3,%xmm1
minsd  %xmm6,%xmm1
cmpltsd %xmm4,%xmm6
andnpd %xmm1,%xmm6
cvttsd2si %xmm6,%r11
shl    $0x8,%rax
or     %r11,%rax
mov    %rax,(%r8)
add    $0x8,%r8
add    $0x1,%r10
add    %rdx,%rcx
cmp    %r10,%rdi
je     1160 <ConvertRGBtoYUV+0x60>
movsd  (%rcx),%xmm9
movsd  0x8(%rcx),%xmm8
divsd  %xmm0,%xmm9
divsd  %xmm0,%xmm8
movsd  0x10(%rcx),%xmm6
divsd  %xmm0,%xmm6
movapd %xmm8,%xmm7
mulsd  0xdff(%rip),%xmm7
movapd %xmm9,%xmm1
mulsd  0xdfa(%rip),%xmm1
addsd  %xmm7,%xmm1
movapd %xmm6,%xmm7
mulsd  0xdf2(%rip),%xmm7
addsd  %xmm1,%xmm7
addsd  0xdee(%rip),%xmm7
movapd %xmm8,%xmm10
mulsd  %xmm12,%xmm10
movapd %xmm9,%xmm1
mulsd  %xmm13,%xmm1
mulsd  %xmm15,%xmm8
movapd %xmm6,%xmm11
mulsd  %xmm2,%xmm11
test   $0x1,%r10b
jne    1180 <ConvertRGBtoYUV+0x80>
addsd  %xmm10,%xmm1
mulsd  %xmm14,%xmm6
addsd  %xmm1,%xmm6
jmp    1194 <ConvertRGBtoYUV+0x94>
ret

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

LLVM IR (-O2):
define void @ConvertRGBtoYUV(i64 %0, i64 %1, i64 %2, double* nocapture %3, i64* nocapture writeonly %4) {
%6 = icmp sgt i64 %1, 0
br i1 %6, label %7, label %60
7: ; preds = %5
%8 = icmp sgt i64 %0, 0
br label %9
9: ; preds = %7, %55
%10 = phi double* [ %3, %7 ], [ %57, %55 ]
%11 = phi i64* [ %4, %7 ], [ %56, %55 ]
%12 = phi i64 [ 0, %7 ], [ %58, %55 ]
br i1 %8, label %13, label %55
13: ; preds = %9, %13
%14 = phi double* [ %52, %13 ], [ %10, %9 ]
%15 = phi i64* [ %51, %13 ], [ %11, %9 ]
%16 = phi i64 [ %53, %13 ], [ 0, %9 ]
%17 = load double, double* %14
%18 = fdiv double %17, 2.550000e+02
%19 = getelementptr inbounds double, double* %14, i64 1
%20 = load double, double* %19
%21 = fdiv double %20, 2.550000e+02
%22 = getelementptr inbounds double, double* %14, i64 2
%23 = load double, double* %22
%24 = fdiv double %23, 2.550000e+02
%25 = fmul double %21, 1.285530e+02
%26 = tail call double @llvm.fmuladd.f64(double %18, double 6.548100e+01, double %25)
%27 = tail call double @llvm.fmuladd.f64(double %24, double 2.496600e+01, double %26)
%28 = fadd double %27, 1.600000e+01
%29 = fmul double %21, -7.420300e+01
%30 = tail call double @llvm.fmuladd.f64(double %18, double -3.779700e+01, double %29)
%31 = tail call double @llvm.fmuladd.f64(double %24, double 1.120000e+02, double %30)
%32 = fmul double %21, -9.378600e+01
%33 = tail call double @llvm.fmuladd.f64(double %18, double 1.120000e+02, double %32)
%34 = tail call double @llvm.fmuladd.f64(double %24, double -1.821400e+01, double %33)
%35 = fcmp olt double %28, 0.000000e+00
%36 = fcmp ogt double %28, 2.540000e+02
%37 = select i1 %36, double 2.540000e+02, double %28
%38 = select i1 %35, double 0.000000e+00, double %37
%39 = fptosi double %38 to i64
%40 = and i64 %16, 1
%41 = icmp eq i64 %40, 0
%42 = select i1 %41, double %31, double %34
%43 = fadd double %42, 1.280000e+02
%44 = fcmp olt double %43, 0.000000e+00
%45 = fcmp ogt double %43, 2.540000e+02
%46 = select i1 %45, double 2.540000e+02, double %43
%47 = select i1 %44, double 0.000000e+00, double %46
%48 = fptosi double %47 to i64
%49 = shl i64 %39, 8
%50 = or i64 %49, %48
store i64 %50, i64* %15
%51 = getelementptr inbounds i64, i64* %15, i64 1
%52 = getelementptr inbounds double, double* %14, i64 %2
%53 = add nuw nsw i64 %16, 1
%54 = icmp eq i64 %53, %0
br i1 %54, label %55, label %13
55: ; preds = %13, %9
%56 = phi i64* [ %11, %9 ], [ %51, %13 ]
%57 = phi double* [ %10, %9 ], [ %52, %13 ]
%58 = add nuw nsw i64 %12, 1
%59 = icmp eq i64 %58, %1
br i1 %59, label %60, label %9
60: ; preds = %55, %5
ret void
}