unsigned char dataChecksumLin(unsigned char *message, char nBytes,
                              unsigned short sum) {
  while (nBytes-- > 0)
    sum += *(message++);
  while (sum >> 8)
    sum = (sum & 255) + (sum >> 8);
  return (~sum);
}


x86 assembly (clang, -O0):
<dataChecksumLin>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %sil,%cl
mov    %rdi,-0x8(%rbp)
mov    %cl,-0x9(%rbp)
mov    %ax,-0xc(%rbp)
mov    -0x9(%rbp),%al
mov    %al,%cl
add    $0xff,%cl
mov    %cl,-0x9(%rbp)
movsbl %al,%eax
cmp    $0x0,%eax
jle    114d <dataChecksumLin+0x4d>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movzbl (%rax),%ecx
movzwl -0xc(%rbp),%eax
add    %ecx,%eax
mov    %ax,-0xc(%rbp)
jmp    1115 <dataChecksumLin+0x15>
jmp    1152 <dataChecksumLin+0x52>
movzwl -0xc(%rbp),%eax
sar    $0x8,%eax
cmp    $0x0,%eax
je     117d <dataChecksumLin+0x7d>
movzwl -0xc(%rbp),%eax
and    $0xff,%eax
movzwl -0xc(%rbp),%ecx
sar    $0x8,%ecx
add    %ecx,%eax
mov    %ax,-0xc(%rbp)
jmp    1152 <dataChecksumLin+0x52>
movzwl -0xc(%rbp),%eax
xor    $0xffffffff,%eax
movzbl %al,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<dataChecksumLin>:
mov    %edx,%eax
test   %sil,%sil
jle    1213 <dataChecksumLin+0x113>
lea    -0x1(%rsi),%ecx
cmp    $0xf,%cl
jb     11f7 <dataChecksumLin+0xf7>
movzbl %cl,%r8d
add    $0x1,%r8
mov    %r8d,%r9d
and    $0xfffffff0,%r9d
movzwl %ax,%eax
movd   %eax,%xmm0
lea    -0x10(%r9),%rax
mov    %rax,%rcx
shr    $0x4,%rcx
add    $0x1,%rcx
test   %rax,%rax
je     1235 <dataChecksumLin+0x135>
mov    %rcx,%rax
and    $0xfffffffffffffffe,%rax
pxor   %xmm2,%xmm2
xor    %edx,%edx
pxor   %xmm1,%xmm1
cs nopw 0x0(%rax,%rax,1)
movq   (%rdi,%rdx,1),%xmm3
movq   0x8(%rdi,%rdx,1),%xmm4
punpcklbw %xmm2,%xmm3
paddw  %xmm0,%xmm3
punpcklbw %xmm2,%xmm4
paddw  %xmm1,%xmm4
movq   0x10(%rdi,%rdx,1),%xmm0
movq   0x18(%rdi,%rdx,1),%xmm1
punpcklbw %xmm2,%xmm0
paddw  %xmm3,%xmm0
punpcklbw %xmm2,%xmm1
paddw  %xmm4,%xmm1
add    $0x20,%rdx
add    $0xfffffffffffffffe,%rax
jne    1160 <dataChecksumLin+0x60>
test   $0x1,%cl
je     11c5 <dataChecksumLin+0xc5>
movq   (%rdi,%rdx,1),%xmm2
movq   0x8(%rdi,%rdx,1),%xmm3
pxor   %xmm4,%xmm4
punpcklbw %xmm4,%xmm2
paddw  %xmm2,%xmm0
punpcklbw %xmm4,%xmm3
paddw  %xmm3,%xmm1
paddw  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddw  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddw  %xmm1,%xmm0
movdqa %xmm0,%xmm1
psrld  $0x10,%xmm1
paddw  %xmm0,%xmm1
movd   %xmm1,%eax
cmp    %r9,%r8
je     1213 <dataChecksumLin+0x113>
sub    %r9b,%sil
add    %r9,%rdi
add    $0x1,%sil
nopl   0x0(%rax,%rax,1)
movzbl (%rdi),%ecx
add    $0x1,%rdi
add    %ecx,%eax
add    $0xff,%sil
cmp    $0x1,%sil
ja     1200 <dataChecksumLin+0x100>
movzwl %ax,%ecx
cmp    $0x100,%ecx
jb     1232 <dataChecksumLin+0x132>
xchg   %ax,%ax
movzwl %ax,%ecx
shr    $0x8,%ecx
movzbl %al,%eax
add    %ecx,%eax
cmp    $0xff,%eax
ja     1220 <dataChecksumLin+0x120>
not    %al
ret
pxor   %xmm1,%xmm1
xor    %edx,%edx
test   $0x1,%cl
jne    11a6 <dataChecksumLin+0xa6>
jmp    11c5 <dataChecksumLin+0xc5>

LLVM IR (-O0):
define zeroext i8 @dataChecksumLin(i8* %0, i8 signext %1, i16 zeroext %2) {
%4 = alloca i8*
%5 = alloca i8
%6 = alloca i16
store i8* %0, i8** %4
store i8 %1, i8* %5
store i16 %2, i16* %6
br label %7
7: ; preds = %12, %3
%8 = load i8, i8* %5
%9 = add i8 %8, -1
store i8 %9, i8* %5
%10 = sext i8 %8 to i32
%11 = icmp sgt i32 %10, 0
br i1 %11, label %12, label %21
12: ; preds = %7
%13 = load i8*, i8** %4
%14 = getelementptr inbounds i8, i8* %13, i32 1
store i8* %14, i8** %4
%15 = load i8, i8* %13
%16 = zext i8 %15 to i32
%17 = load i16, i16* %6
%18 = zext i16 %17 to i32
%19 = add nsw i32 %18, %16
%20 = trunc i32 %19 to i16
store i16 %20, i16* %6
br label %7
21: ; preds = %7
br label %22
22: ; preds = %27, %21
%23 = load i16, i16* %6
%24 = zext i16 %23 to i32
%25 = ashr i32 %24, 8
%26 = icmp ne i32 %25, 0
br i1 %26, label %27, label %36
27: ; preds = %22
%28 = load i16, i16* %6
%29 = zext i16 %28 to i32
%30 = and i32 %29, 255
%31 = load i16, i16* %6
%32 = zext i16 %31 to i32
%33 = ashr i32 %32, 8
%34 = add nsw i32 %30, %33
%35 = trunc i32 %34 to i16
store i16 %35, i16* %6
br label %22
36: ; preds = %22
%37 = load i16, i16* %6
%38 = zext i16 %37 to i32
%39 = xor i32 %38, -1
%40 = trunc i32 %39 to i8
ret i8 %40
}

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