unsigned char calc_checksum(unsigned int value, int nbytes) {
  int i;
  unsigned char sum = 0;
  unsigned char bytes[4];
  for (i = 0; i < nbytes; i++) {
    bytes[i] = value & 0x000000ff;
    value >>= 8;
  }
  for (i = 0; i < nbytes; i++) {
    sum += bytes[i];
  }
  return sum;
}


x86 assembly (clang, -O0):
<calc_checksum>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movb   $0x0,-0xd(%rbp)
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    114a <calc_checksum+0x4a>
mov    -0x4(%rbp),%eax
and    $0xff,%eax
mov    %al,%cl
movslq -0xc(%rbp),%rax
mov    %cl,-0x11(%rbp,%rax,1)
mov    -0x4(%rbp),%eax
shr    $0x8,%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1115 <calc_checksum+0x15>
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    117d <calc_checksum+0x7d>
movslq -0xc(%rbp),%rax
movzbl -0x11(%rbp,%rax,1),%ecx
movzbl -0xd(%rbp),%eax
add    %ecx,%eax
mov    %al,-0xd(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1151 <calc_checksum+0x51>
movzbl -0xd(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<calc_checksum>:
test   %esi,%esi
jle    1182 <calc_checksum+0x82>
mov    %esi,%r8d
lea    -0x1(%r8),%rcx
mov    %r8d,%eax
and    $0x3,%eax
cmp    $0x3,%rcx
jae    1120 <calc_checksum+0x20>
xor    %edx,%edx
test   %rax,%rax
jne    1149 <calc_checksum+0x49>
jmp    1170 <calc_checksum+0x70>
mov    %r8d,%ecx
and    $0xfffffffc,%ecx
xor    %edx,%edx
nopl   0x0(%rax,%rax,1)
mov    %edi,-0x4(%rsp,%rdx,1)
add    $0x4,%rdx
mov    $0x0,%edi
cmp    %rdx,%rcx
jne    1130 <calc_checksum+0x30>
xor    %edi,%edi
test   %rax,%rax
je     1170 <calc_checksum+0x70>
add    %rsp,%rdx
add    $0xfffffffffffffffc,%rdx
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    %dil,(%rdx,%rcx,1)
shr    $0x8,%edi
add    $0x1,%rcx
cmp    %rcx,%rax
jne    1160 <calc_checksum+0x60>
test   %esi,%esi
jle    1182 <calc_checksum+0x82>
cmp    $0x8,%esi
jae    1185 <calc_checksum+0x85>
xor    %edx,%edx
xor    %eax,%eax
jmp    12c0 <calc_checksum+0x1c0>
xor    %eax,%eax
ret
cmp    $0x20,%esi
jae    1193 <calc_checksum+0x93>
xor    %eax,%eax
xor    %edx,%edx
jmp    1280 <calc_checksum+0x180>
mov    %r8d,%edx
and    $0xffffffe0,%edx
lea    -0x20(%rdx),%rcx
mov    %rcx,%rdi
shr    $0x5,%rdi
add    $0x1,%rdi
mov    %edi,%eax
and    $0x3,%eax
cmp    $0x60,%rcx
jae    11bf <calc_checksum+0xbf>
pxor   %xmm0,%xmm0
xor    %esi,%esi
pxor   %xmm1,%xmm1
jmp    122a <calc_checksum+0x12a>
and    $0xfffffffffffffffc,%rdi
pxor   %xmm0,%xmm0
xor    %esi,%esi
pxor   %xmm1,%xmm1
nopl   (%rax)
movdqu -0x4(%rsp,%rsi,1),%xmm2
paddb  %xmm0,%xmm2
movdqu 0xc(%rsp,%rsi,1),%xmm0
paddb  %xmm1,%xmm0
movdqu 0x1c(%rsp,%rsi,1),%xmm1
movdqu 0x2c(%rsp,%rsi,1),%xmm3
movdqu 0x3c(%rsp,%rsi,1),%xmm4
paddb  %xmm1,%xmm4
paddb  %xmm2,%xmm4
movdqu 0x4c(%rsp,%rsi,1),%xmm2
paddb  %xmm3,%xmm2
paddb  %xmm0,%xmm2
movdqu 0x5c(%rsp,%rsi,1),%xmm0
paddb  %xmm4,%xmm0
movdqu 0x6c(%rsp,%rsi,1),%xmm1
paddb  %xmm2,%xmm1
sub    $0xffffffffffffff80,%rsi
add    $0xfffffffffffffffc,%rdi
jne    11d0 <calc_checksum+0xd0>
test   %rax,%rax
je     125c <calc_checksum+0x15c>
add    %rsp,%rsi
add    $0xc,%rsi
shl    $0x5,%rax
xor    %edi,%edi
nopl   0x0(%rax)
movdqu -0x10(%rsi,%rdi,1),%xmm2
paddb  %xmm2,%xmm0
movdqu (%rsi,%rdi,1),%xmm2
paddb  %xmm2,%xmm1
add    $0x20,%rdi
cmp    %rdi,%rax
jne    1240 <calc_checksum+0x140>
paddb  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddb  %xmm0,%xmm1
pxor   %xmm0,%xmm0
psadbw %xmm1,%xmm0
movd   %xmm0,%eax
cmp    %r8,%rdx
je     12cd <calc_checksum+0x1cd>
test   $0x18,%r8b
je     12c0 <calc_checksum+0x1c0>
mov    %rdx,%rsi
mov    %r8d,%edx
and    $0xfffffff8,%edx
movzbl %al,%eax
movd   %eax,%xmm0
movq   -0x4(%rsp,%rsi,1),%xmm1
paddb  %xmm1,%xmm0
add    $0x8,%rsi
cmp    %rsi,%rdx
jne    1290 <calc_checksum+0x190>
pxor   %xmm1,%xmm1
psadbw %xmm1,%xmm0
movd   %xmm0,%eax
cmp    %r8,%rdx
je     12cd <calc_checksum+0x1cd>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
add    -0x4(%rsp,%rdx,1),%al
add    $0x1,%rdx
cmp    %rdx,%r8
jne    12c0 <calc_checksum+0x1c0>
ret

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

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