void boxBlur(unsigned int *lineBufferOut, unsigned char *lineBufferIn,
             int width, int windowLength) {
  int windowSize = windowLength << 2;
  long rs = 0, gs = 0, bs = 0, as = 0;
  unsigned char *ptr = lineBufferIn;
  unsigned char *ptrEnd = lineBufferIn + windowSize;
  while (ptr < ptrEnd) {
    rs += *ptr;
    gs += *(ptr + 1);
    bs += *(ptr + 2);
    as += *(ptr + 3);
    ptr += 4;
  }
  unsigned char *pLast = lineBufferIn;
  unsigned char *pNext = lineBufferIn + windowSize;
  unsigned char alpha;
  for (int x = 0; x < width; ++x) {
    alpha = as / windowLength;
    if (alpha != 0) {
      *lineBufferOut = (rs / windowLength) | (gs / windowLength) << 8 |
                       (bs / windowLength) << 16 | alpha << 24;
    } else {
      *lineBufferOut = 0;
    }
    rs += *pNext - *pLast;
    gs += *(pNext + 1) - *(pLast + 1);
    bs += *(pNext + 2) - *(pLast + 2);
    as += *(pNext + 3) - *(pLast + 3);
    pNext += 4;
    pLast += 4;
    lineBufferOut++;
  }
}


x86 assembly (clang, -O0):
<boxBlur>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    -0x18(%rbp),%eax
shl    $0x2,%eax
mov    %eax,-0x1c(%rbp)
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x50(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x50(%rbp),%rax
jae    11b0 <boxBlur+0xb0>
mov    -0x48(%rbp),%rax
movzbl (%rax),%eax
add    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x48(%rbp),%rax
movzbl 0x1(%rax),%eax
add    -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x48(%rbp),%rax
movzbl 0x2(%rax),%eax
add    -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x48(%rbp),%rax
movzbl 0x3(%rax),%eax
add    -0x40(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x48(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x48(%rbp)
jmp    1152 <boxBlur+0x52>
mov    -0x10(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x60(%rbp)
movl   $0x0,-0x68(%rbp)
mov    -0x68(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1306 <boxBlur+0x206>
mov    -0x40(%rbp),%rax
movslq -0x18(%rbp),%rcx
cqto
idiv   %rcx
mov    %al,-0x61(%rbp)
movzbl -0x61(%rbp),%eax
cmp    $0x0,%eax
je     125c <boxBlur+0x15c>
mov    -0x28(%rbp),%rax
movslq -0x18(%rbp),%rcx
cqto
idiv   %rcx
mov    %rax,-0x78(%rbp)
mov    -0x30(%rbp),%rax
movslq -0x18(%rbp),%rcx
cqto
idiv   %rcx
mov    %rax,%rcx
mov    -0x78(%rbp),%rax
shl    $0x8,%rcx
or     %rcx,%rax
mov    %rax,-0x70(%rbp)
mov    -0x38(%rbp),%rax
movslq -0x18(%rbp),%rcx
cqto
idiv   %rcx
mov    %rax,%rcx
mov    -0x70(%rbp),%rax
shl    $0x10,%rcx
or     %rcx,%rax
movzbl -0x61(%rbp),%ecx
shl    $0x18,%ecx
movslq %ecx,%rcx
or     %rcx,%rax
mov    %eax,%ecx
mov    -0x8(%rbp),%rax
mov    %ecx,(%rax)
jmp    1266 <boxBlur+0x166>
mov    -0x8(%rbp),%rax
movl   $0x0,(%rax)
mov    -0x60(%rbp),%rax
movzbl (%rax),%eax
mov    -0x58(%rbp),%rcx
movzbl (%rcx),%ecx
sub    %ecx,%eax
cltq
add    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x60(%rbp),%rax
movzbl 0x1(%rax),%eax
mov    -0x58(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
sub    %ecx,%eax
cltq
add    -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x60(%rbp),%rax
movzbl 0x2(%rax),%eax
mov    -0x58(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
sub    %ecx,%eax
cltq
add    -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x60(%rbp),%rax
movzbl 0x3(%rax),%eax
mov    -0x58(%rbp),%rcx
movzbl 0x3(%rcx),%ecx
sub    %ecx,%eax
cltq
add    -0x40(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x60(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x60(%rbp)
mov    -0x58(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x58(%rbp)
mov    -0x8(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x8(%rbp)
mov    -0x68(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x68(%rbp)
jmp    11ce <boxBlur+0xce>
pop    %rbp
ret

x86 assembly (clang, -O2):
<boxBlur>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rdi,-0x8(%rsp)
lea    0x0(,%rcx,4),%eax
cltq
test   %eax,%eax
jle    115d <boxBlur+0x5d>
lea    (%rsi,%rax,1),%rdi
xor    %r8d,%r8d
mov    %rsi,%rbx
xor    %r11d,%r11d
xor    %r10d,%r10d
xor    %r9d,%r9d
nop
movzbl (%rbx),%ebp
add    %rbp,%r8
movzbl 0x1(%rbx),%ebp
add    %rbp,%r9
movzbl 0x2(%rbx),%ebp
add    %rbp,%r10
movzbl 0x3(%rbx),%ebp
add    %rbp,%r11
add    $0x4,%rbx
cmp    %rdi,%rbx
jb     1130 <boxBlur+0x30>
test   %edx,%edx
jg     1171 <boxBlur+0x71>
jmp    12bb <boxBlur+0x1bb>
xor    %r9d,%r9d
xor    %r10d,%r10d
xor    %r11d,%r11d
xor    %r8d,%r8d
test   %edx,%edx
jle    12bb <boxBlur+0x1bb>
movslq %ecx,%r12
mov    %edx,%edi
lea    (%rax,%rsi,1),%rbp
add    $0x3,%rbp
xor    %r13d,%r13d
jmp    11ef <boxBlur+0xef>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
xor    %ebx,%ebx
mov    -0x8(%rsp),%rax
mov    %ebx,(%rax,%r13,4)
movzbl -0x3(%rbp,%r13,4),%eax
movzbl (%rsi,%r13,4),%edx
add    %rax,%r8
sub    %rdx,%r8
movzbl -0x2(%rbp,%r13,4),%eax
movzbl 0x1(%rsi,%r13,4),%edx
add    %rax,%r9
sub    %rdx,%r9
movzbl -0x1(%rbp,%r13,4),%eax
movzbl 0x2(%rsi,%r13,4),%edx
add    %rax,%r10
sub    %rdx,%r10
movzbl 0x0(%rbp,%r13,4),%eax
movzbl 0x3(%rsi,%r13,4),%edx
add    %rax,%r11
sub    %rdx,%r11
add    $0x1,%r13
cmp    %r13d,%edi
je     12bb <boxBlur+0x1bb>
mov    %r11,%rax
or     %r12,%rax
shr    $0x20,%rax
je     1210 <boxBlur+0x110>
mov    %r11,%rax
cqto
idiv   %r12
mov    %rax,%r15
test   %r15b,%r15b
jne    1223 <boxBlur+0x123>
jmp    1190 <boxBlur+0x90>
nopl   (%rax)
mov    %r11d,%eax
xor    %edx,%edx
div    %ecx
mov    %eax,%r15d
test   %r15b,%r15b
je     1190 <boxBlur+0x90>
mov    %r8,%rax
or     %r12,%rax
shr    $0x20,%rax
je     1240 <boxBlur+0x140>
mov    %r8,%rax
cqto
idiv   %r12
mov    %rax,%r14
jmp    124a <boxBlur+0x14a>
nopl   0x0(%rax)
mov    %r8d,%eax
xor    %edx,%edx
div    %ecx
mov    %eax,%r14d
mov    %r9,%rax
or     %r12,%rax
shr    $0x20,%rax
je     1270 <boxBlur+0x170>
mov    %r9,%rax
cqto
idiv   %r12
mov    %rax,%rbx
jmp    1279 <boxBlur+0x179>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %r9d,%eax
xor    %edx,%edx
div    %ecx
mov    %eax,%ebx
shl    $0x8,%rbx
mov    %r10,%rax
or     %r12,%rax
shr    $0x20,%rax
je     12a0 <boxBlur+0x1a0>
mov    %r10,%rax
cqto
idiv   %r12
jmp    12a7 <boxBlur+0x1a7>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %r10d,%eax
xor    %edx,%edx
div    %ecx
shl    $0x10,%eax
shl    $0x18,%r15d
or     %r15d,%r14d
or     %eax,%ebx
or     %r14d,%ebx
jmp    1192 <boxBlur+0x92>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define void @boxBlur(i32* nocapture writeonly %0, i8* %1, i32 %2, i32 %3) {
%5 = shl i32 %3, 2
%6 = sext i32 %5 to i64
%7 = getelementptr inbounds i8, i8* %1, i64 %6
%8 = icmp sgt i32 %5, 0
br i1 %8, label %17, label %9
9: ; preds = %17, %4
%10 = phi i64 [ 0, %4 ], [ %29, %17 ]
%11 = phi i64 [ 0, %4 ], [ %33, %17 ]
%12 = phi i64 [ 0, %4 ], [ %37, %17 ]
%13 = phi i64 [ 0, %4 ], [ %25, %17 ]
%14 = icmp sgt i32 %2, 0
br i1 %14, label %15, label %40
15: ; preds = %9
%16 = sext i32 %3 to i64
br label %41
17: ; preds = %4, %17
%18 = phi i64 [ %25, %17 ], [ 0, %4 ]
%19 = phi i8* [ %38, %17 ], [ %1, %4 ]
%20 = phi i64 [ %37, %17 ], [ 0, %4 ]
%21 = phi i64 [ %33, %17 ], [ 0, %4 ]
%22 = phi i64 [ %29, %17 ], [ 0, %4 ]
%23 = load i8, i8* %19
%24 = zext i8 %23 to i64
%25 = add nuw nsw i64 %18, %24
%26 = getelementptr inbounds i8, i8* %19, i64 1
%27 = load i8, i8* %26
%28 = zext i8 %27 to i64
%29 = add nuw nsw i64 %22, %28
%30 = getelementptr inbounds i8, i8* %19, i64 2
%31 = load i8, i8* %30
%32 = zext i8 %31 to i64
%33 = add nuw nsw i64 %21, %32
%34 = getelementptr inbounds i8, i8* %19, i64 3
%35 = load i8, i8* %34
%36 = zext i8 %35 to i64
%37 = add nuw nsw i64 %20, %36
%38 = getelementptr inbounds i8, i8* %19, i64 4
%39 = icmp ult i8* %38, %7
br i1 %39, label %17, label %9
40: ; preds = %64, %9
ret void
41: ; preds = %15, %64
%42 = phi i32 [ 0, %15 ], [ %99, %64 ]
%43 = phi i32* [ %0, %15 ], [ %98, %64 ]
%44 = phi i8* [ %7, %15 ], [ %96, %64 ]
%45 = phi i8* [ %1, %15 ], [ %97, %64 ]
%46 = phi i64 [ %13, %15 ], [ %71, %64 ]
%47 = phi i64 [ %12, %15 ], [ %95, %64 ]
%48 = phi i64 [ %11, %15 ], [ %87, %64 ]
%49 = phi i64 [ %10, %15 ], [ %79, %64 ]
%50 = sdiv i64 %47, %16
%51 = and i64 %50, 255
%52 = icmp eq i64 %51, 0
br i1 %52, label %64, label %53
53: ; preds = %41
%54 = sdiv i64 %46, %16
%55 = sdiv i64 %49, %16
%56 = shl i64 %55, 8
%57 = sdiv i64 %48, %16
%58 = shl i64 %57, 16
%59 = shl i64 %50, 24
%60 = or i64 %54, %59
%61 = or i64 %60, %56
%62 = or i64 %61, %58
%63 = trunc i64 %62 to i32
br label %64
64: ; preds = %41, %53
%65 = phi i32 [ %63, %53 ], [ 0, %41 ]
store i32 %65, i32* %43
%66 = load i8, i8* %44
%67 = zext i8 %66 to i64
%68 = load i8, i8* %45
%69 = zext i8 %68 to i64
%70 = add i64 %46, %67
%71 = sub i64 %70, %69
%72 = getelementptr inbounds i8, i8* %44, i64 1
%73 = load i8, i8* %72
%74 = zext i8 %73 to i64
%75 = getelementptr inbounds i8, i8* %45, i64 1
%76 = load i8, i8* %75
%77 = zext i8 %76 to i64
%78 = add i64 %49, %74
%79 = sub i64 %78, %77
%80 = getelementptr inbounds i8, i8* %44, i64 2
%81 = load i8, i8* %80
%82 = zext i8 %81 to i64
%83 = getelementptr inbounds i8, i8* %45, i64 2
%84 = load i8, i8* %83
%85 = zext i8 %84 to i64
%86 = add i64 %48, %82
%87 = sub i64 %86, %85
%88 = getelementptr inbounds i8, i8* %44, i64 3
%89 = load i8, i8* %88
%90 = zext i8 %89 to i64
%91 = getelementptr inbounds i8, i8* %45, i64 3
%92 = load i8, i8* %91
%93 = zext i8 %92 to i64
%94 = add i64 %47, %90
%95 = sub i64 %94, %93
%96 = getelementptr inbounds i8, i8* %44, i64 4
%97 = getelementptr inbounds i8, i8* %45, i64 4
%98 = getelementptr inbounds i32, i32* %43, i64 1
%99 = add nuw nsw i32 %42, 1
%100 = icmp eq i32 %99, %2
br i1 %100, label %40, label %41
}