unsigned char cksum2(unsigned char *buf, unsigned char len) {
  unsigned char s = 0;
  while (len)
    s ^= buf[--len];
  return s;
}


x86 assembly (clang, -O0):
<cksum2>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %rdi,-0x8(%rbp)
mov    %al,-0x9(%rbp)
movb   $0x0,-0xa(%rbp)
cmpb   $0x0,-0x9(%rbp)
je     113e <cksum2+0x3e>
mov    -0x8(%rbp),%rax
mov    -0x9(%rbp),%cl
add    $0xff,%cl
mov    %cl,-0x9(%rbp)
movzbl %cl,%ecx
movzbl (%rax,%rcx,1),%ecx
movzbl -0xa(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0xa(%rbp)
jmp    1112 <cksum2+0x12>
movzbl -0xa(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<cksum2>:
test   %esi,%esi
je     1118 <cksum2+0x18>
movzbl %sil,%r8d
cmp    $0x8,%r8b
jae    111b <cksum2+0x1b>
xor    %eax,%eax
mov    %r8,%rsi
jmp    1390 <cksum2+0x290>
xor    %eax,%eax
ret
cmp    $0x20,%sil
jae    112a <cksum2+0x2a>
xor    %eax,%eax
xor    %edx,%edx
jmp    1300 <cksum2+0x200>
mov    %r8d,%edx
and    $0xffffffe0,%edx
movdqu -0x20(%r8,%rdi,1),%xmm3
movdqu -0x10(%r8,%rdi,1),%xmm0
pxor   %xmm1,%xmm1
cmp    $0x20,%rdx
je     11d4 <cksum2+0xd4>
movdqu -0x40(%r8,%rdi,1),%xmm2
movdqu -0x30(%r8,%rdi,1),%xmm4
pxor   %xmm0,%xmm4
pxor   %xmm3,%xmm2
cmp    $0x40,%edx
je     125d <cksum2+0x15d>
movdqu -0x60(%r8,%rdi,1),%xmm3
movdqu -0x50(%r8,%rdi,1),%xmm0
pxor   %xmm4,%xmm0
pxor   %xmm1,%xmm1
pxor   %xmm2,%xmm3
cmp    $0x60,%edx
je     11d4 <cksum2+0xd4>
movdqu -0x80(%r8,%rdi,1),%xmm2
movdqu -0x70(%r8,%rdi,1),%xmm4
pxor   %xmm0,%xmm4
pxor   %xmm3,%xmm2
cmp    $0x80,%edx
je     125d <cksum2+0x15d>
movdqu -0xa0(%r8,%rdi,1),%xmm3
ff ff ff
movdqu -0x90(%r8,%rdi,1),%xmm0
ff ff ff
pxor   %xmm4,%xmm0
pxor   %xmm1,%xmm1
pxor   %xmm2,%xmm3
cmp    $0xa0,%edx
jne    1235 <cksum2+0x135>
movdqa %xmm0,%xmm2
punpcklbw %xmm1,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
punpckhbw %xmm1,%xmm0
pshufd $0x4e,%xmm0,%xmm0
pshuflw $0x1b,%xmm0,%xmm0
pshufhw $0x1b,%xmm0,%xmm0
packuswb %xmm2,%xmm0
movdqa %xmm3,%xmm2
punpcklbw %xmm1,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
punpckhbw %xmm1,%xmm3
pshufd $0x4e,%xmm3,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm2,%xmm1
jmp    12b9 <cksum2+0x1b9>
movdqu -0xc0(%r8,%rdi,1),%xmm2
ff ff ff
movdqu -0xb0(%r8,%rdi,1),%xmm4
ff ff ff
pxor   %xmm0,%xmm4
pxor   %xmm3,%xmm2
cmp    $0xc0,%edx
jne    13a4 <cksum2+0x2a4>
movdqa %xmm4,%xmm0
punpcklbw %xmm1,%xmm0
pshufd $0x4e,%xmm0,%xmm0
pshuflw $0x1b,%xmm0,%xmm0
pshufhw $0x1b,%xmm0,%xmm3
punpckhbw %xmm1,%xmm4
pshufd $0x4e,%xmm4,%xmm0
pshuflw $0x1b,%xmm0,%xmm0
pshufhw $0x1b,%xmm0,%xmm0
packuswb %xmm3,%xmm0
movdqa %xmm2,%xmm3
punpcklbw %xmm1,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm1,%xmm2
pshufd $0x4e,%xmm2,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm3,%xmm1
pxor   %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
pxor   %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
pxor   %xmm1,%xmm0
movdqa %xmm0,%xmm1
psrld  $0x10,%xmm1
pxor   %xmm0,%xmm1
movdqa %xmm1,%xmm0
psrlw  $0x8,%xmm0
pxor   %xmm1,%xmm0
movd   %xmm0,%eax
cmp    %r8,%rdx
je     139a <cksum2+0x29a>
test   $0x18,%r8b
je     139b <cksum2+0x29b>
mov    %r8d,%r9d
and    $0xfffffff8,%r9d
mov    %r8d,%esi
and    $0x7,%esi
movzbl %al,%eax
movd   %eax,%xmm0
lea    (%r8,%rdi,1),%rax
add    $0xfffffffffffffff8,%rax
neg    %rdx
mov    %r9,%rcx
neg    %rcx
pxor   %xmm1,%xmm1
nopl   0x0(%rax)
movq   (%rax,%rdx,1),%xmm2
punpcklbw %xmm1,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
packuswb %xmm2,%xmm2
pxor   %xmm2,%xmm0
add    $0xfffffffffffffff8,%rdx
cmp    %rdx,%rcx
jne    1330 <cksum2+0x230>
pshufd $0x55,%xmm0,%xmm1
pxor   %xmm0,%xmm1
movdqa %xmm1,%xmm0
psrld  $0x10,%xmm0
pxor   %xmm1,%xmm0
movdqa %xmm0,%xmm1
psrlw  $0x8,%xmm1
pxor   %xmm0,%xmm1
movd   %xmm1,%eax
cmp    %r8,%r9
je     139a <cksum2+0x29a>
cs nopw 0x0(%rax,%rax,1)
nop
xor    -0x1(%rdi,%rsi,1),%al
add    $0xffffffffffffffff,%rsi
jne    1390 <cksum2+0x290>
ret
and    $0x1f,%r8d
jmp    1110 <cksum2+0x10>
movdqu -0xe0(%r8,%rdi,1),%xmm1
ff ff ff
movdqu -0xd0(%r8,%rdi,1),%xmm0
ff ff ff
pxor   %xmm4,%xmm0
pxor   %xmm3,%xmm3
movdqa %xmm0,%xmm4
punpcklbw %xmm3,%xmm4
pshufd $0x4e,%xmm4,%xmm4
pshuflw $0x1b,%xmm4,%xmm4
pshufhw $0x1b,%xmm4,%xmm4
punpckhbw %xmm3,%xmm0
pshufd $0x4e,%xmm0,%xmm0
pshuflw $0x1b,%xmm0,%xmm0
pshufhw $0x1b,%xmm0,%xmm0
packuswb %xmm4,%xmm0
pxor   %xmm2,%xmm1
movdqa %xmm1,%xmm2
punpcklbw %xmm3,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
punpckhbw %xmm3,%xmm1
pshufd $0x4e,%xmm1,%xmm1
jmp    1222 <cksum2+0x122>

LLVM IR (-O0):
define zeroext i8 @cksum2(i8* %0, i8 zeroext %1) {
%3 = alloca i8*
%4 = alloca i8
%5 = alloca i8
store i8* %0, i8** %3
store i8 %1, i8* %4
store i8 0, i8* %5
br label %6
6: ; preds = %9, %2
%7 = load i8, i8* %4
%8 = icmp ne i8 %7, 0
br i1 %8, label %9, label %21
9: ; preds = %6
%10 = load i8*, i8** %3
%11 = load i8, i8* %4
%12 = add i8 %11, -1
store i8 %12, i8* %4
%13 = zext i8 %12 to i64
%14 = getelementptr inbounds i8, i8* %10, i64 %13
%15 = load i8, i8* %14
%16 = zext i8 %15 to i32
%17 = load i8, i8* %5
%18 = zext i8 %17 to i32
%19 = xor i32 %18, %16
%20 = trunc i32 %19 to i8
store i8 %20, i8* %5
br label %6
21: ; preds = %6
%22 = load i8, i8* %5
ret i8 %22
}

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