void applyMatrixToPixel(unsigned char *red, unsigned char *green,
                        unsigned char *blue, float matrix[4][4]) {
  float r1, g1, b1, r2, g2, b2;
  r1 = (*red);
  g1 = (*green);
  b1 = (*blue);
  r2 = r1 * matrix[0][0] + g1 * matrix[1][0] + b1 * matrix[2][0] + matrix[3][0];
  g2 = r1 * matrix[0][1] + g1 * matrix[1][1] + b1 * matrix[2][1] + matrix[3][1];
  b2 = r1 * matrix[0][2] + g1 * matrix[1][2] + b1 * matrix[2][2] + matrix[3][2];
  if (r2 < 0)
    r2 = 0;
  if (r2 > 255)
    r2 = 255;
  if (g2 < 0)
    g2 = 0;
  if (g2 > 255)
    g2 = 255;
  if (b2 < 0)
    b2 = 0;
  if (b2 > 255)
    b2 = 255;
  (*red) = r2;
  (*green) = g2;
  (*blue) = b2;
}


x86 assembly (clang, -O0):
<applyMatrixToPixel>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x10(%rbp),%rax
movzbl (%rax),%eax
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x2c(%rbp)
movss  -0x24(%rbp),%xmm1
mov    -0x20(%rbp),%rax
movss  (%rax),%xmm2
movss  -0x28(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mulss  0x10(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x2c(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movss  0x20(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
addss  0x30(%rax),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0x24(%rbp),%xmm1
mov    -0x20(%rbp),%rax
movss  0x4(%rax),%xmm2
movss  -0x28(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mulss  0x14(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x2c(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movss  0x24(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
addss  0x34(%rax),%xmm0
movss  %xmm0,-0x34(%rbp)
movss  -0x24(%rbp),%xmm1
mov    -0x20(%rbp),%rax
movss  0x8(%rax),%xmm2
movss  -0x28(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mulss  0x18(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x2c(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movss  0x28(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
addss  0x38(%rax),%xmm0
movss  %xmm0,-0x38(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0x30(%rbp),%xmm0
jbe    1230 <applyMatrixToPixel+0x130>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0x30(%rbp),%xmm0
movss  0xdc3(%rip),%xmm1
ucomiss %xmm1,%xmm0
jbe    1253 <applyMatrixToPixel+0x153>
movss  0xdb2(%rip),%xmm0
movss  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0x34(%rbp),%xmm0
jbe    1268 <applyMatrixToPixel+0x168>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x34(%rbp)
movss  -0x34(%rbp),%xmm0
movss  0xd8b(%rip),%xmm1
ucomiss %xmm1,%xmm0
jbe    128b <applyMatrixToPixel+0x18b>
movss  0xd7a(%rip),%xmm0
movss  %xmm0,-0x34(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0x38(%rbp),%xmm0
jbe    12a0 <applyMatrixToPixel+0x1a0>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x38(%rbp),%xmm0
movss  0xd53(%rip),%xmm1
ucomiss %xmm1,%xmm0
jbe    12c3 <applyMatrixToPixel+0x1c3>
movss  0xd42(%rip),%xmm0
movss  %xmm0,-0x38(%rbp)
cvttss2si -0x30(%rbp),%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,(%rax)
cvttss2si -0x34(%rbp),%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
cvttss2si -0x38(%rbp),%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %cl,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<applyMatrixToPixel>:
movzbl (%rdi),%eax
cvtsi2ss %eax,%xmm1
movzbl (%rsi),%eax
cvtsi2ss %eax,%xmm2
movzbl (%rdx),%eax
cvtsi2ss %eax,%xmm0
movaps %xmm2,%xmm3
shufps $0x0,%xmm2,%xmm3
movsd  (%rcx),%xmm4
movsd  0x10(%rcx),%xmm5
mulps  %xmm3,%xmm5
movsd  0x20(%rcx),%xmm3
movsd  0x30(%rcx),%xmm6
movaps %xmm1,%xmm7
shufps $0x0,%xmm1,%xmm7
mulps  %xmm4,%xmm7
addps  %xmm5,%xmm7
movaps %xmm0,%xmm4
shufps $0x0,%xmm0,%xmm4
mulps  %xmm3,%xmm4
addps  %xmm7,%xmm4
mulss  0x18(%rcx),%xmm2
mulss  0x8(%rcx),%xmm1
mulss  0x28(%rcx),%xmm0
addss  %xmm2,%xmm1
addss  %xmm1,%xmm0
addss  0x38(%rcx),%xmm0
addps  %xmm6,%xmm4
xorps  %xmm1,%xmm1
maxps  %xmm4,%xmm1
movaps 0xe88(%rip),%xmm2
cmpltps %xmm1,%xmm2
unpcklps %xmm2,%xmm2
movmskpd %xmm2,%eax
xorps  %xmm2,%xmm2
maxss  %xmm0,%xmm2
movss  0xe7e(%rip),%xmm0
cvttss2si %xmm1,%ecx
test   $0x1,%al
mov    $0xff,%r8d
cmovne %r8d,%ecx
shufps $0x55,%xmm1,%xmm1
mov    %cl,(%rdi)
cvttss2si %xmm1,%ecx
minss  %xmm2,%xmm0
test   $0x2,%al
cmovne %r8d,%ecx
mov    %cl,(%rsi)
cvttss2si %xmm0,%eax
mov    %al,(%rdx)
ret

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

LLVM IR (-O2):
define void @applyMatrixToPixel(i8* nocapture %0, i8* nocapture %1, i8* nocapture %2, [4 x float]* nocapture %3) {
%5 = load i8, i8* %0
%6 = uitofp i8 %5 to float
%7 = load i8, i8* %1
%8 = uitofp i8 %7 to float
%9 = load i8, i8* %2
%10 = uitofp i8 %9 to float
%11 = getelementptr inbounds [4 x float], [4 x float]* %3, i64 1, i64 0
%12 = getelementptr inbounds [4 x float], [4 x float]* %3, i64 2, i64 0
%13 = getelementptr inbounds [4 x float], [4 x float]* %3, i64 3, i64 0
%14 = bitcast [4 x float]* %3 to <2 x float>*
%15 = load <2 x float>, <2 x float>* %14
%16 = bitcast float* %11 to <2 x float>*
%17 = load <2 x float>, <2 x float>* %16
%18 = insertelement <2 x float> poison, float %8, i64 0
%19 = shufflevector <2 x float> %18, <2 x float> poison, <2 x i32> zeroinitializer
%20 = fmul <2 x float> %17, %19
%21 = insertelement <2 x float> poison, float %6, i64 0
%22 = shufflevector <2 x float> %21, <2 x float> poison, <2 x i32> zeroinitializer
%23 = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %22, <2 x float> %15, <2 x float> %20)
%24 = bitcast float* %12 to <2 x float>*
%25 = load <2 x float>, <2 x float>* %24
%26 = insertelement <2 x float> poison, float %10, i64 0
%27 = shufflevector <2 x float> %26, <2 x float> poison, <2 x i32> zeroinitializer
%28 = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %27, <2 x float> %25, <2 x float> %23)
%29 = bitcast float* %13 to <2 x float>*
%30 = load <2 x float>, <2 x float>* %29
%31 = fadd <2 x float> %30, %28
%32 = getelementptr inbounds [4 x float], [4 x float]* %3, i64 0, i64 2
%33 = load float, float* %32
%34 = getelementptr inbounds [4 x float], [4 x float]* %3, i64 1, i64 2
%35 = load float, float* %34
%36 = fmul float %35, %8
%37 = tail call float @llvm.fmuladd.f32(float %6, float %33, float %36)
%38 = getelementptr inbounds [4 x float], [4 x float]* %3, i64 2, i64 2
%39 = load float, float* %38
%40 = tail call float @llvm.fmuladd.f32(float %10, float %39, float %37)
%41 = getelementptr inbounds [4 x float], [4 x float]* %3, i64 3, i64 2
%42 = load float, float* %41
%43 = fadd float %42, %40
%44 = fcmp olt <2 x float> %31, zeroinitializer
%45 = select <2 x i1> %44, <2 x float> zeroinitializer, <2 x float> %31
%46 = fcmp ogt <2 x float> %45, <float 2.550000e+02, float 2.550000e+02>
%47 = extractelement <2 x i1> %46, i64 0
%48 = extractelement <2 x float> %45, i64 0
%49 = extractelement <2 x i1> %46, i64 1
%50 = extractelement <2 x float> %45, i64 1
%51 = fcmp olt float %43, 0.000000e+00
%52 = select i1 %51, float 0.000000e+00, float %43
%53 = fcmp ogt float %52, 2.550000e+02
%54 = select i1 %53, float 2.550000e+02, float %52
%55 = fptoui float %48 to i8
%56 = select i1 %47, i8 -1, i8 %55
store i8 %56, i8* %0
%57 = fptoui float %50 to i8
%58 = select i1 %49, i8 -1, i8 %57
store i8 %58, i8* %1
%59 = fptoui float %54 to i8
store i8 %59, i8* %2
ret void
}