__attribute__((always_)) void
imReduceHalfBox4Plant(unsigned char *dst, unsigned char *src, int bytesperpixel,
                      int bytesperline, float *dithersum) {
  int alpha;
  dst[0] = (unsigned char)(((int)src[0] + (int)src[bytesperpixel + 0] +
                            (int)src[bytesperline + 0] +
                            (int)src[bytesperpixel + bytesperline + 0] + 2) >>
                           2);
  dst[1] = (unsigned char)(((int)src[1] + (int)src[bytesperpixel + 1] +
                            (int)src[bytesperline + 1] +
                            (int)src[bytesperpixel + bytesperline + 1] + 2) >>
                           2);
  dst[2] = (unsigned char)(((int)src[2] + (int)src[bytesperpixel + 2] +
                            (int)src[bytesperline + 2] +
                            (int)src[bytesperpixel + bytesperline + 2] + 2) >>
                           2);
  alpha =
      ((int)src[3] + (int)src[bytesperpixel + 3] + (int)src[bytesperline + 3] +
       (int)src[bytesperpixel + bytesperline + 3]);
  alpha += alpha >> 2;
  alpha = (alpha + 2) >> 2;
  if (alpha > 255)
    alpha = 255;
  dst[3] = (unsigned char)alpha;
  return;
}


x86 assembly (clang, -O0):
<imReduceHalfBox4Plant>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    %r8,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movzbl (%rax),%eax
mov    -0x10(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x0,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    -0x10(%rbp),%rcx
mov    -0x18(%rbp),%edx
add    $0x0,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    -0x10(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    -0x18(%rbp),%edx
add    $0x0,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
add    $0x2,%eax
sar    $0x2,%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x1(%rax),%eax
mov    -0x10(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    -0x10(%rbp),%rcx
mov    -0x18(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    -0x10(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    -0x18(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
add    $0x2,%eax
sar    $0x2,%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x1(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x2(%rax),%eax
mov    -0x10(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    -0x10(%rbp),%rcx
mov    -0x18(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    -0x10(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    -0x18(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
add    $0x2,%eax
sar    $0x2,%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x2(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x3(%rax),%eax
mov    -0x10(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x3,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    -0x10(%rbp),%rcx
mov    -0x18(%rbp),%edx
add    $0x3,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    -0x10(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    -0x18(%rbp),%edx
add    $0x3,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
sar    $0x2,%eax
add    -0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
add    $0x2,%eax
sar    $0x2,%eax
mov    %eax,-0x24(%rbp)
cmpl   $0xff,-0x24(%rbp)
jle    1280 <imReduceHalfBox4Plant+0x180>
movl   $0xff,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x3(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<imReduceHalfBox4Plant>:
movzbl (%rsi),%r8d
movslq %edx,%r9
movzbl (%rsi,%r9,1),%edx
add    %r8d,%edx
movslq %ecx,%rcx
movzbl (%rsi,%rcx,1),%eax
add    %edx,%eax
lea    (%rcx,%r9,1),%edx
movslq %edx,%r8
movzbl (%rsi,%r8,1),%edx
add    %edx,%eax
add    $0x2,%eax
shr    $0x2,%eax
mov    %al,(%rdi)
movzbl 0x1(%rsi),%eax
movzbl 0x1(%rsi,%r9,1),%edx
add    %eax,%edx
movzbl 0x1(%rsi,%rcx,1),%eax
add    %edx,%eax
movzbl 0x1(%rsi,%r8,1),%edx
add    %edx,%eax
add    $0x2,%eax
shr    $0x2,%eax
mov    %al,0x1(%rdi)
movzbl 0x2(%rsi),%eax
movzbl 0x2(%rsi,%r9,1),%edx
add    %eax,%edx
movzbl 0x2(%rsi,%rcx,1),%eax
add    %edx,%eax
movzbl 0x2(%rsi,%r8,1),%edx
add    %edx,%eax
add    $0x2,%eax
shr    $0x2,%eax
mov    %al,0x2(%rdi)
movzbl 0x3(%rsi),%eax
movzbl 0x3(%rsi,%r9,1),%edx
add    %eax,%edx
movzbl 0x3(%rsi,%rcx,1),%eax
add    %edx,%eax
movzbl 0x3(%rsi,%r8,1),%ecx
add    %eax,%ecx
mov    %ecx,%eax
shr    $0x2,%eax
add    %ecx,%eax
add    $0x2,%eax
shr    $0x2,%eax
cmp    $0xff,%eax
mov    $0xff,%ecx
cmovb  %eax,%ecx
mov    %cl,0x3(%rdi)
ret

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

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