unsigned long ComputeChecksum32(void *src, int lg) {
  unsigned long *p = src;
  unsigned long chksum = 0;
  unsigned long *end = p + lg / sizeof(unsigned long);
  while (p < end) {
    chksum ^= *p++;
  }
  return (unsigned long)chksum;
}


x86 assembly (clang, -O0):
<ComputeChecksum32>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x18(%rbp),%rax
movslq -0xc(%rbp),%rcx
shr    $0x3,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x28(%rbp),%rax
jae    115f <ComputeChecksum32+0x5f>
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x18(%rbp)
mov    (%rax),%rax
xor    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
jmp    1132 <ComputeChecksum32+0x32>
mov    -0x20(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ComputeChecksum32>:
movslq %esi,%rcx
and    $0xfffffffffffffff8,%rcx
add    %rdi,%rcx
cmp    %rdi,%rcx
jbe    1130 <ComputeChecksum32+0x30>
lea    0x8(%rdi),%rax
cmp    %rax,%rcx
cmova  %rcx,%rax
mov    %rdi,%r9
not    %r9
add    %rax,%r9
cmp    $0x18,%r9
jae    1133 <ComputeChecksum32+0x33>
xor    %eax,%eax
jmp    1230 <ComputeChecksum32+0x130>
xor    %eax,%eax
ret
shr    $0x3,%r9
add    $0x1,%r9
mov    %r9,%r8
and    $0xfffffffffffffffc,%r8
lea    -0x4(%r8),%rsi
mov    %rsi,%rax
shr    $0x2,%rax
add    $0x1,%rax
mov    %eax,%edx
and    $0x3,%edx
cmp    $0xc,%rsi
jae    1168 <ComputeChecksum32+0x68>
pxor   %xmm0,%xmm0
xor    %esi,%esi
pxor   %xmm1,%xmm1
jmp    11d9 <ComputeChecksum32+0xd9>
and    $0xfffffffffffffffc,%rax
pxor   %xmm0,%xmm0
xor    %esi,%esi
pxor   %xmm1,%xmm1
cs nopw 0x0(%rax,%rax,1)
movdqu (%rdi,%rsi,8),%xmm2
pxor   %xmm0,%xmm2
movdqu 0x10(%rdi,%rsi,8),%xmm0
pxor   %xmm1,%xmm0
movdqu 0x20(%rdi,%rsi,8),%xmm1
movdqu 0x30(%rdi,%rsi,8),%xmm3
movdqu 0x40(%rdi,%rsi,8),%xmm4
pxor   %xmm1,%xmm4
pxor   %xmm2,%xmm4
movdqu 0x50(%rdi,%rsi,8),%xmm2
pxor   %xmm3,%xmm2
pxor   %xmm0,%xmm2
movdqu 0x60(%rdi,%rsi,8),%xmm0
pxor   %xmm4,%xmm0
movdqu 0x70(%rdi,%rsi,8),%xmm1
pxor   %xmm2,%xmm1
add    $0x10,%rsi
add    $0xfffffffffffffffc,%rax
jne    1180 <ComputeChecksum32+0x80>
test   %rdx,%rdx
je     120c <ComputeChecksum32+0x10c>
lea    (%rdi,%rsi,8),%rax
add    $0x10,%rax
shl    $0x5,%rdx
xor    %esi,%esi
nopl   0x0(%rax)
movdqu -0x10(%rax,%rsi,1),%xmm2
pxor   %xmm2,%xmm0
movdqu (%rax,%rsi,1),%xmm2
pxor   %xmm2,%xmm1
add    $0x20,%rsi
cmp    %rsi,%rdx
jne    11f0 <ComputeChecksum32+0xf0>
pxor   %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
pxor   %xmm0,%xmm1
movq   %xmm1,%rax
cmp    %r8,%r9
je     123c <ComputeChecksum32+0x13c>
lea    (%rdi,%r8,8),%rdi
nopw   0x0(%rax,%rax,1)
xor    (%rdi),%rax
add    $0x8,%rdi
cmp    %rcx,%rdi
jb     1230 <ComputeChecksum32+0x130>
ret

LLVM IR (-O0):
define i64 @ComputeChecksum32(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i64*
%6 = alloca i64
%7 = alloca i64*
store i8* %0, i8** %3
store i32 %1, i32* %4
%8 = load i8*, i8** %3
%9 = bitcast i8* %8 to i64*
store i64* %9, i64** %5
store i64 0, i64* %6
%10 = load i64*, i64** %5
%11 = load i32, i32* %4
%12 = sext i32 %11 to i64
%13 = udiv i64 %12, 8
%14 = getelementptr inbounds i64, i64* %10, i64 %13
store i64* %14, i64** %7
br label %15
15: ; preds = %19, %2
%16 = load i64*, i64** %5
%17 = load i64*, i64** %7
%18 = icmp ult i64* %16, %17
br i1 %18, label %19, label %25
19: ; preds = %15
%20 = load i64*, i64** %5
%21 = getelementptr inbounds i64, i64* %20, i32 1
store i64* %21, i64** %5
%22 = load i64, i64* %20
%23 = load i64, i64* %6
%24 = xor i64 %23, %22
store i64 %24, i64* %6
br label %15
25: ; preds = %15
%26 = load i64, i64* %6
ret i64 %26
}

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