void blend(int rows, int columns, unsigned char buffer[rows][columns],
           unsigned char bufferOne[rows][columns],
           unsigned char bufferTwo[rows][columns]) {
  int r, c;
  for (r = 0; r < rows; r++) {
    for (c = 0; c < columns; c++) {
      buffer[r][c] = (bufferOne[r][c] + bufferTwo[r][c]) / 2;
    }
  }
}


x86 assembly (clang, -O0):
<blend>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %rdx,-0x10(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8,-0x20(%rbp)
mov    -0x8(%rbp),%eax
mov    %rax,-0x40(%rbp)
mov    -0x8(%rbp),%eax
mov    %rax,-0x38(%rbp)
mov    -0x8(%rbp),%eax
mov    %rax,-0x30(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11ce <blend+0xce>
movl   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    11bb <blend+0xbb>
mov    -0x40(%rbp),%rsi
mov    -0x30(%rbp),%rdi
mov    -0x38(%rbp),%rdx
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
imul   %rdx,%rcx
add    %rcx,%rax
movslq -0x28(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    -0x20(%rbp),%rcx
movslq -0x24(%rbp),%rdx
imul   %rdi,%rdx
add    %rdx,%rcx
movslq -0x28(%rbp),%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %al,%dl
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
imul   %rsi,%rcx
add    %rcx,%rax
movslq -0x28(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    1145 <blend+0x45>
jmp    11c0 <blend+0xc0>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1132 <blend+0x32>
pop    %rbp
ret

x86 assembly (clang, -O2):
<blend>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %r8,-0x40(%rsp)
mov    %rcx,-0x48(%rsp)
mov    %esi,-0x4c(%rsp)
test   %edi,%edi
jle    13c2 <blend+0x2c2>
mov    -0x4c(%rsp),%eax
mov    %edi,%ecx
mov    %rcx,-0x8(%rsp)
mov    %eax,%ecx
and    $0xffffffe0,%ecx
mov    %rcx,-0x38(%rsp)
mov    %eax,%ecx
and    $0xfffffff8,%ecx
mov    %rcx,-0x20(%rsp)
mov    %rax,%rcx
neg    %rcx
mov    %rcx,-0x18(%rsp)
mov    -0x48(%rsp),%r10
lea    0x10(%r10),%r15
mov    -0x40(%rsp),%rbp
lea    0x10(%rbp),%r13
lea    0x10(%rdx),%r11
xor    %r8d,%r8d
pxor   %xmm0,%xmm0
mov    %rdx,%rdi
mov    %rdx,-0x30(%rsp)
jmp    11a1 <blend+0xa1>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
add    $0x1,%r8
add    %rax,%r15
add    %rax,%r13
add    %rax,%r11
add    %rax,%r10
add    %rax,%rbp
add    %rax,%rdi
cmp    -0x8(%rsp),%r8
je     13c2 <blend+0x2c2>
cmpl   $0x0,-0x4c(%rsp)
jle    1180 <blend+0x80>
mov    %r8,%r12
imul   %rax,%r12
lea    (%rdx,%r12,1),%rbx
mov    -0x48(%rsp),%rcx
lea    (%rcx,%r12,1),%rsi
mov    -0x40(%rsp),%rcx
lea    (%rcx,%r12,1),%r9
cmpl   $0x8,-0x4c(%rsp)
mov    %rsi,-0x10(%rsp)
jae    11e0 <blend+0xe0>
xor    %r14d,%r14d
jmp    1350 <blend+0x250>
nopl   0x0(%rax)
add    %rax,%r12
lea    (%rdx,%r12,1),%rcx
mov    -0x48(%rsp),%rdx
lea    (%rdx,%r12,1),%r14
mov    -0x40(%rsp),%rdx
add    %rdx,%r12
cmp    %r14,%rbx
setb   %r14b
cmp    %rcx,%rsi
setb   %sil
mov    %rbx,-0x28(%rsp)
cmp    %r12,%rbx
setb   %dl
cmp    %rcx,%r9
setb   %cl
test   %sil,%r14b
jne    1242 <blend+0x142>
mov    $0x0,%r14d
and    %cl,%dl
mov    -0x30(%rsp),%rdx
mov    -0x28(%rsp),%rbx
jne    1350 <blend+0x250>
cmpl   $0x20,-0x4c(%rsp)
jae    1254 <blend+0x154>
xor    %ecx,%ecx
jmp    1306 <blend+0x206>
xor    %r14d,%r14d
mov    -0x30(%rsp),%rdx
mov    -0x28(%rsp),%rbx
jmp    1350 <blend+0x250>
xor    %ecx,%ecx
mov    -0x38(%rsp),%rsi
nopl   0x0(%rax,%rax,1)
movdqu -0x10(%r15,%rcx,1),%xmm1
movdqu (%r15,%rcx,1),%xmm2
movdqa %xmm1,%xmm3
punpckhbw %xmm0,%xmm3
punpcklbw %xmm0,%xmm1
movdqa %xmm2,%xmm4
punpckhbw %xmm0,%xmm4
punpcklbw %xmm0,%xmm2
movdqu -0x10(%r13,%rcx,1),%xmm5
movdqu 0x0(%r13,%rcx,1),%xmm6
movdqa %xmm5,%xmm7
punpckhbw %xmm0,%xmm7
paddw  %xmm3,%xmm7
punpcklbw %xmm0,%xmm5
paddw  %xmm1,%xmm5
movdqa %xmm6,%xmm1
punpckhbw %xmm0,%xmm1
paddw  %xmm4,%xmm1
punpcklbw %xmm0,%xmm6
paddw  %xmm2,%xmm6
psrlw  $0x1,%xmm7
psrlw  $0x1,%xmm5
packuswb %xmm7,%xmm5
psrlw  $0x1,%xmm1
psrlw  $0x1,%xmm6
packuswb %xmm1,%xmm6
movdqu %xmm5,-0x10(%r11,%rcx,1)
movdqu %xmm6,(%r11,%rcx,1)
add    $0x20,%rcx
cmp    %rcx,%rsi
jne    1260 <blend+0x160>
cmp    %rax,%rsi
je     1180 <blend+0x80>
mov    -0x38(%rsp),%r14
mov    %r14,%rcx
test   $0x18,%al
je     1350 <blend+0x250>
mov    -0x20(%rsp),%rsi
nopl   0x0(%rax,%rax,1)
movq   (%r10,%rcx,1),%xmm1
punpcklbw %xmm0,%xmm1
movq   0x0(%rbp,%rcx,1),%xmm2
punpcklbw %xmm0,%xmm2
paddw  %xmm1,%xmm2
psrlw  $0x1,%xmm2
packuswb %xmm2,%xmm2
movq   %xmm2,(%rdi,%rcx,1)
add    $0x8,%rcx
cmp    %rcx,%rsi
jne    1310 <blend+0x210>
mov    %rsi,%r14
cmp    %rax,%rsi
je     1180 <blend+0x80>
nopl   0x0(%rax,%rax,1)
mov    %r14,%rcx
test   $0x1,%al
je     1375 <blend+0x275>
mov    -0x10(%rsp),%rcx
movzbl (%rcx,%r14,1),%ecx
movzbl (%r9,%r14,1),%esi
add    %ecx,%esi
shr    %esi
mov    %sil,(%rbx,%r14,1)
mov    %r14,%rcx
or     $0x1,%rcx
not    %r14
cmp    -0x18(%rsp),%r14
je     1180 <blend+0x80>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movzbl (%r10,%rcx,1),%esi
movzbl 0x0(%rbp,%rcx,1),%ebx
add    %esi,%ebx
shr    %ebx
mov    %bl,(%rdi,%rcx,1)
movzbl 0x1(%r10,%rcx,1),%esi
movzbl 0x1(%rbp,%rcx,1),%ebx
add    %esi,%ebx
shr    %ebx
mov    %bl,0x1(%rdi,%rcx,1)
add    $0x2,%rcx
cmp    %rcx,%rax
jne    1390 <blend+0x290>
jmp    1180 <blend+0x80>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @blend(i32 %0, i32 %1, i8* %2, i8* %3, i8* %4) {
%6 = alloca i32
%7 = alloca i32
%8 = alloca i8*
%9 = alloca i8*
%10 = alloca i8*
%11 = alloca i32
%12 = alloca i32
store i32 %0, i32* %6
store i32 %1, i32* %7
store i8* %2, i8** %8
store i8* %3, i8** %9
store i8* %4, i8** %10
%13 = load i32, i32* %6
%14 = zext i32 %13 to i64
%15 = load i32, i32* %7
%16 = zext i32 %15 to i64
%17 = load i32, i32* %6
%18 = zext i32 %17 to i64
%19 = load i32, i32* %7
%20 = zext i32 %19 to i64
%21 = load i32, i32* %6
%22 = zext i32 %21 to i64
%23 = load i32, i32* %7
%24 = zext i32 %23 to i64
store i32 0, i32* %11
br label %25
25: ; preds = %70, %5
%26 = load i32, i32* %11
%27 = load i32, i32* %6
%28 = icmp slt i32 %26, %27
br i1 %28, label %29, label %73
29: ; preds = %25
store i32 0, i32* %12
br label %30
30: ; preds = %66, %29
%31 = load i32, i32* %12
%32 = load i32, i32* %7
%33 = icmp slt i32 %31, %32
br i1 %33, label %34, label %69
34: ; preds = %30
%35 = load i8*, i8** %9
%36 = load i32, i32* %11
%37 = sext i32 %36 to i64
%38 = mul nsw i64 %37, %20
%39 = getelementptr inbounds i8, i8* %35, i64 %38
%40 = load i32, i32* %12
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %39, i64 %41
%43 = load i8, i8* %42
%44 = zext i8 %43 to i32
%45 = load i8*, i8** %10
%46 = load i32, i32* %11
%47 = sext i32 %46 to i64
%48 = mul nsw i64 %47, %24
%49 = getelementptr inbounds i8, i8* %45, i64 %48
%50 = load i32, i32* %12
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds i8, i8* %49, i64 %51
%53 = load i8, i8* %52
%54 = zext i8 %53 to i32
%55 = add nsw i32 %44, %54
%56 = sdiv i32 %55, 2
%57 = trunc i32 %56 to i8
%58 = load i8*, i8** %8
%59 = load i32, i32* %11
%60 = sext i32 %59 to i64
%61 = mul nsw i64 %60, %16
%62 = getelementptr inbounds i8, i8* %58, i64 %61
%63 = load i32, i32* %12
%64 = sext i32 %63 to i64
%65 = getelementptr inbounds i8, i8* %62, i64 %64
store i8 %57, i8* %65
br label %66
66: ; preds = %34
%67 = load i32, i32* %12
%68 = add nsw i32 %67, 1
store i32 %68, i32* %12
br label %30
69: ; preds = %30
br label %70
70: ; preds = %69
%71 = load i32, i32* %11
%72 = add nsw i32 %71, 1
store i32 %72, i32* %11
br label %25
73: ; preds = %25
ret void
}

LLVM IR (-O2):
define void @blend(i32 %0, i32 %1, i8* nocapture writeonly %2, i8* nocapture %3, i8* nocapture %4) {
%6 = zext i32 %1 to i64
%7 = icmp sgt i32 %0, 0
br i1 %7, label %8, label %144
8: ; preds = %5
%9 = icmp sgt i32 %1, 0
%10 = zext i32 %0 to i64
%11 = icmp ult i32 %1, 8
%12 = icmp ult i32 %1, 32
%13 = and i64 %6, 4294967264
%14 = icmp eq i64 %13, %6
%15 = and i64 %6, 24
%16 = icmp eq i64 %15, 0
%17 = and i64 %6, 4294967288
%18 = icmp eq i64 %17, %6
%19 = and i64 %6, 1
%20 = icmp eq i64 %19, 0
%21 = sub nsw i64 0, %6
br label %22
22: ; preds = %8, %141
%23 = phi i64 [ 0, %8 ], [ %142, %141 ]
%24 = mul i64 %23, %6
%25 = getelementptr i8, i8* %2, i64 %24
%26 = add i64 %24, %6
%27 = getelementptr i8, i8* %2, i64 %26
%28 = getelementptr i8, i8* %3, i64 %24
%29 = getelementptr i8, i8* %3, i64 %26
%30 = getelementptr i8, i8* %4, i64 %24
%31 = getelementptr i8, i8* %4, i64 %26
br i1 %9, label %32, label %141
32: ; preds = %22
%33 = mul nuw nsw i64 %23, %6
%34 = getelementptr inbounds i8, i8* %3, i64 %33
%35 = getelementptr inbounds i8, i8* %4, i64 %33
%36 = getelementptr inbounds i8, i8* %2, i64 %33
br i1 %11, label %98, label %37
37: ; preds = %32
%38 = icmp ult i8* %25, %29
%39 = icmp ult i8* %28, %27
%40 = and i1 %38, %39
%41 = icmp ult i8* %25, %31
%42 = icmp ult i8* %30, %27
%43 = and i1 %41, %42
%44 = or i1 %40, %43
br i1 %44, label %98, label %45
45: ; preds = %37
br i1 %12, label %78, label %46
46: ; preds = %45, %46
%47 = phi i64 [ %74, %46 ], [ 0, %45 ]
%48 = getelementptr inbounds i8, i8* %34, i64 %47
%49 = bitcast i8* %48 to <16 x i8>*
%50 = load <16 x i8>, <16 x i8>* %49
%51 = getelementptr inbounds i8, i8* %48, i64 16
%52 = bitcast i8* %51 to <16 x i8>*
%53 = load <16 x i8>, <16 x i8>* %52
%54 = zext <16 x i8> %50 to <16 x i16>
%55 = zext <16 x i8> %53 to <16 x i16>
%56 = getelementptr inbounds i8, i8* %35, i64 %47
%57 = bitcast i8* %56 to <16 x i8>*
%58 = load <16 x i8>, <16 x i8>* %57
%59 = getelementptr inbounds i8, i8* %56, i64 16
%60 = bitcast i8* %59 to <16 x i8>*
%61 = load <16 x i8>, <16 x i8>* %60
%62 = zext <16 x i8> %58 to <16 x i16>
%63 = zext <16 x i8> %61 to <16 x i16>
%64 = add nuw nsw <16 x i16> %62, %54
%65 = add nuw nsw <16 x i16> %63, %55
%66 = lshr <16 x i16> %64, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%67 = lshr <16 x i16> %65, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%68 = trunc <16 x i16> %66 to <16 x i8>
%69 = trunc <16 x i16> %67 to <16 x i8>
%70 = getelementptr inbounds i8, i8* %36, i64 %47
%71 = bitcast i8* %70 to <16 x i8>*
store <16 x i8> %68, <16 x i8>* %71
%72 = getelementptr inbounds i8, i8* %70, i64 16
%73 = bitcast i8* %72 to <16 x i8>*
store <16 x i8> %69, <16 x i8>* %73
%74 = add nuw i64 %47, 32
%75 = icmp eq i64 %74, %13
br i1 %75, label %76, label %46
76: ; preds = %46
br i1 %14, label %141, label %77
77: ; preds = %76
br i1 %16, label %98, label %78
78: ; preds = %45, %77
%79 = phi i64 [ %13, %77 ], [ 0, %45 ]
br label %80
80: ; preds = %80, %78
%81 = phi i64 [ %79, %78 ], [ %95, %80 ]
%82 = getelementptr inbounds i8, i8* %34, i64 %81
%83 = bitcast i8* %82 to <8 x i8>*
%84 = load <8 x i8>, <8 x i8>* %83
%85 = zext <8 x i8> %84 to <8 x i16>
%86 = getelementptr inbounds i8, i8* %35, i64 %81
%87 = bitcast i8* %86 to <8 x i8>*
%88 = load <8 x i8>, <8 x i8>* %87
%89 = zext <8 x i8> %88 to <8 x i16>
%90 = add nuw nsw <8 x i16> %89, %85
%91 = lshr <8 x i16> %90, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%92 = trunc <8 x i16> %91 to <8 x i8>
%93 = getelementptr inbounds i8, i8* %36, i64 %81
%94 = bitcast i8* %93 to <8 x i8>*
store <8 x i8> %92, <8 x i8>* %94
%95 = add nuw i64 %81, 8
%96 = icmp eq i64 %95, %17
br i1 %96, label %97, label %80
97: ; preds = %80
br i1 %18, label %141, label %98
98: ; preds = %37, %32, %77, %97
%99 = phi i64 [ 0, %32 ], [ 0, %37 ], [ %13, %77 ], [ %17, %97 ]
%100 = xor i64 %99, -1
br i1 %20, label %113, label %101
101: ; preds = %98
%102 = getelementptr inbounds i8, i8* %34, i64 %99
%103 = load i8, i8* %102
%104 = zext i8 %103 to i16
%105 = getelementptr inbounds i8, i8* %35, i64 %99
%106 = load i8, i8* %105
%107 = zext i8 %106 to i16
%108 = add nuw nsw i16 %107, %104
%109 = lshr i16 %108, 1
%110 = trunc i16 %109 to i8
%111 = getelementptr inbounds i8, i8* %36, i64 %99
store i8 %110, i8* %111
%112 = or i64 %99, 1
br label %113
113: ; preds = %101, %98
%114 = phi i64 [ %99, %98 ], [ %112, %101 ]
%115 = icmp eq i64 %100, %21
br i1 %115, label %141, label %116
116: ; preds = %113, %116
%117 = phi i64 [ %139, %116 ], [ %114, %113 ]
%118 = getelementptr inbounds i8, i8* %34, i64 %117
%119 = load i8, i8* %118
%120 = zext i8 %119 to i16
%121 = getelementptr inbounds i8, i8* %35, i64 %117
%122 = load i8, i8* %121
%123 = zext i8 %122 to i16
%124 = add nuw nsw i16 %123, %120
%125 = lshr i16 %124, 1
%126 = trunc i16 %125 to i8
%127 = getelementptr inbounds i8, i8* %36, i64 %117
store i8 %126, i8* %127
%128 = add nuw nsw i64 %117, 1
%129 = getelementptr inbounds i8, i8* %34, i64 %128
%130 = load i8, i8* %129
%131 = zext i8 %130 to i16
%132 = getelementptr inbounds i8, i8* %35, i64 %128
%133 = load i8, i8* %132
%134 = zext i8 %133 to i16
%135 = add nuw nsw i16 %134, %131
%136 = lshr i16 %135, 1
%137 = trunc i16 %136 to i8
%138 = getelementptr inbounds i8, i8* %36, i64 %128
store i8 %137, i8* %138
%139 = add nuw nsw i64 %117, 2
%140 = icmp eq i64 %139, %6
br i1 %140, label %141, label %116
141: ; preds = %113, %116, %76, %97, %22
%142 = add nuw nsw i64 %23, 1
%143 = icmp eq i64 %142, %10
br i1 %143, label %144, label %22
144: ; preds = %141, %5
ret void
}