unsigned char smoothing(unsigned char px0, unsigned char px1, unsigned char px2,
                        unsigned char px3, unsigned char px4, unsigned char px5,
                        unsigned char px6, unsigned char px7,
                        unsigned char px8) {
  int px[9] = {px0, px1, px2, px3, px4, px5, px6, px7, px8};
  int px_out = 0;
  for (int i = 0; i < 9; i++) {
    px_out += px[i];
  }
  px_out /= 9;
  return (unsigned char)px_out;
}


x86 assembly (clang, -O0):
<smoothing>:
push   %rbp
mov    %rsp,%rbp
mov    %r8d,-0x48(%rbp)
mov    %ecx,%eax
mov    -0x48(%rbp),%ecx
mov    %eax,-0x44(%rbp)
mov    %edx,%eax
mov    -0x44(%rbp),%edx
mov    %eax,-0x40(%rbp)
mov    %esi,%eax
mov    -0x40(%rbp),%esi
mov    %eax,-0x3c(%rbp)
mov    %edi,%r8d
mov    -0x3c(%rbp),%edi
mov    %r9b,%al
mov    0x20(%rbp),%r9b
mov    0x18(%rbp),%r9b
mov    0x10(%rbp),%r9b
mov    %r8b,-0x1(%rbp)
mov    %dil,-0x2(%rbp)
mov    %sil,-0x3(%rbp)
mov    %dl,-0x4(%rbp)
mov    %cl,-0x5(%rbp)
mov    %al,-0x6(%rbp)
movzbl -0x1(%rbp),%eax
mov    %eax,-0x30(%rbp)
movzbl -0x2(%rbp),%eax
mov    %eax,-0x2c(%rbp)
movzbl -0x3(%rbp),%eax
mov    %eax,-0x28(%rbp)
movzbl -0x4(%rbp),%eax
mov    %eax,-0x24(%rbp)
movzbl -0x5(%rbp),%eax
mov    %eax,-0x20(%rbp)
movzbl -0x6(%rbp),%eax
mov    %eax,-0x1c(%rbp)
movzbl 0x10(%rbp),%eax
mov    %eax,-0x18(%rbp)
movzbl 0x18(%rbp),%eax
mov    %eax,-0x14(%rbp)
movzbl 0x20(%rbp),%eax
mov    %eax,-0x10(%rbp)
movl   $0x0,-0x34(%rbp)
movl   $0x0,-0x38(%rbp)
cmpl   $0x9,-0x38(%rbp)
jge    11bd <smoothing+0xbd>
movslq -0x38(%rbp),%rax
mov    -0x30(%rbp,%rax,4),%eax
add    -0x34(%rbp),%eax
mov    %eax,-0x34(%rbp)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    1197 <smoothing+0x97>
mov    -0x34(%rbp),%eax
mov    $0x9,%ecx
cltd
idiv   %ecx
mov    %eax,-0x34(%rbp)
mov    -0x34(%rbp),%eax
movzbl %al,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<smoothing>:
movzbl 0x18(%rsp),%r10d
movzbl 0x10(%rsp),%r11d
movzbl 0x8(%rsp),%eax
add    %esi,%edi
add    %edx,%edi
add    %ecx,%edi
add    %r8d,%edi
add    %r9d,%edi
add    %eax,%edi
add    %r11d,%edi
add    %r10d,%edi
movzwl %di,%eax
imul   $0xe38f,%eax,%eax
shr    $0x13,%eax
ret

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

LLVM IR (-O2):
define zeroext i8 @smoothing(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3, i8 zeroext %4, i8 zeroext %5, i8 zeroext %6, i8 zeroext %7, i8 zeroext %8) {
%10 = zext i8 %0 to i16
%11 = zext i8 %1 to i16
%12 = zext i8 %2 to i16
%13 = zext i8 %3 to i16
%14 = zext i8 %4 to i16
%15 = zext i8 %5 to i16
%16 = zext i8 %6 to i16
%17 = zext i8 %7 to i16
%18 = zext i8 %8 to i16
%19 = add nuw nsw i16 %11, %10
%20 = add nuw nsw i16 %19, %12
%21 = add nuw nsw i16 %20, %13
%22 = add nuw nsw i16 %21, %14
%23 = add nuw nsw i16 %22, %15
%24 = add nuw nsw i16 %23, %16
%25 = add i16 %24, %17
%26 = add i16 %25, %18
%27 = udiv i16 %26, 9
%28 = trunc i16 %27 to i8
ret i8 %28
}