unsigned char ip_verify_checksum(unsigned char header[],
                                 unsigned int header_size_in_bytes) {
  unsigned char number_of_16bit_words, CORRECT = 0, INCORRECT = 1;
  unsigned int count, index, header_16bit_words[30], result;
  long sum = 0, temp = 0;
  number_of_16bit_words = (header_size_in_bytes / 2);
  for (count = 0, index = 0; count < number_of_16bit_words;
       ++count, index += 2) {
    header_16bit_words[count] = header[index];
    header_16bit_words[count] = (header_16bit_words[count] << 8);
    header_16bit_words[count] |= header[index + 1];
  }
  for (count = 0; count < number_of_16bit_words; ++count) {
    sum += header_16bit_words[count];
  }
  temp = (sum >> 16);
  sum &= 0xFFFF;
  result = (sum + temp);
  result = ~result;
  if (result == 0) {
    return CORRECT;
  } else {
    return INCORRECT;
  }
}


x86 assembly (clang, -O0):
<ip_verify_checksum>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
movb   $0x0,-0x16(%rbp)
movb   $0x1,-0x17(%rbp)
movq   $0x0,-0xb0(%rbp)
movq   $0x0,-0xb8(%rbp)
mov    -0x14(%rbp),%eax
shr    $0x1,%eax
mov    %al,-0x15(%rbp)
movl   $0x0,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
mov    -0x1c(%rbp),%eax
movzbl -0x15(%rbp),%ecx
cmp    %ecx,%eax
jae    11b7 <ip_verify_checksum+0xb7>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
movzbl (%rax,%rcx,1),%ecx
mov    -0x1c(%rbp),%eax
mov    %ecx,-0xa0(%rbp,%rax,4)
mov    -0x1c(%rbp),%eax
mov    -0xa0(%rbp,%rax,4),%ecx
shl    $0x8,%ecx
mov    -0x1c(%rbp),%eax
mov    %ecx,-0xa0(%rbp,%rax,4)
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
mov    %ecx,%ecx
movzbl (%rax,%rcx,1),%ecx
mov    -0x1c(%rbp),%eax
or     -0xa0(%rbp,%rax,4),%ecx
mov    %ecx,-0xa0(%rbp,%rax,4)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x20(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x20(%rbp)
jmp    1144 <ip_verify_checksum+0x44>
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
movzbl -0x15(%rbp),%ecx
cmp    %ecx,%eax
jae    11f3 <ip_verify_checksum+0xf3>
mov    -0x1c(%rbp),%eax
mov    -0xa0(%rbp,%rax,4),%eax
add    -0xb0(%rbp),%rax
mov    %rax,-0xb0(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    11be <ip_verify_checksum+0xbe>
mov    -0xb0(%rbp),%rax
sar    $0x10,%rax
mov    %rax,-0xb8(%rbp)
mov    -0xb0(%rbp),%rax
and    $0xffff,%rax
mov    %rax,-0xb0(%rbp)
mov    -0xb0(%rbp),%rax
add    -0xb8(%rbp),%rax
mov    %eax,-0xa4(%rbp)
mov    -0xa4(%rbp),%eax
xor    $0xffffffff,%eax
mov    %eax,-0xa4(%rbp)
cmpl   $0x0,-0xa4(%rbp)
jne    1254 <ip_verify_checksum+0x154>
mov    -0x16(%rbp),%al
mov    %al,-0x1(%rbp)
jmp    125a <ip_verify_checksum+0x15a>
mov    -0x17(%rbp),%al
mov    %al,-0x1(%rbp)
movzbl -0x1(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ip_verify_checksum>:
shr    %esi
and    $0xff,%esi
je     1188 <ip_verify_checksum+0x88>
mov    %esi,%r8d
cmp    $0x1,%esi
jne    111e <ip_verify_checksum+0x1e>
xor    %ecx,%ecx
xor    %edx,%edx
test   $0x1,%r8b
jne    1161 <ip_verify_checksum+0x61>
jmp    1176 <ip_verify_checksum+0x76>
mov    %r8d,%r9d
and    $0xfffffffe,%r9d
neg    %r9
xor    %ecx,%ecx
xor    %edx,%edx
nopl   0x0(%rax)
movzwl (%rdi,%rdx,1),%eax
shl    $0x10,%eax
bswap  %eax
mov    %eax,-0x78(%rsp,%rdx,2)
movzwl 0x2(%rdi,%rdx,1),%eax
shl    $0x10,%eax
bswap  %eax
mov    %eax,-0x74(%rsp,%rdx,2)
add    $0x4,%rdx
add    $0xfffffffffffffffe,%rcx
cmp    %rcx,%r9
jne    1130 <ip_verify_checksum+0x30>
neg    %rcx
test   $0x1,%r8b
je     1176 <ip_verify_checksum+0x76>
movzbl (%rdi,%rdx,1),%eax
shl    $0x8,%eax
or     $0x1,%rdx
movzbl (%rdi,%rdx,1),%edx
or     %eax,%edx
mov    %edx,-0x78(%rsp,%rcx,4)
test   %esi,%esi
je     1188 <ip_verify_checksum+0x88>
cmp    $0x4,%esi
jae    118f <ip_verify_checksum+0x8f>
xor    %ecx,%ecx
xor    %edx,%edx
jmp    1250 <ip_verify_checksum+0x150>
xor    %edx,%edx
jmp    1260 <ip_verify_checksum+0x160>
mov    %r8d,%ecx
and    $0xfc,%ecx
lea    -0x4(%rcx),%rax
mov    %rax,%rdx
shr    $0x2,%rdx
add    $0x1,%rdx
test   %rax,%rax
je     1273 <ip_verify_checksum+0x173>
mov    %rdx,%rdi
and    $0xfffffffffffffffe,%rdi
pxor   %xmm2,%xmm2
xor    %esi,%esi
pxor   %xmm0,%xmm0
pxor   %xmm1,%xmm1
cs nopw 0x0(%rax,%rax,1)
nop
movq   -0x78(%rsp,%rsi,4),%xmm3
movq   -0x70(%rsp,%rsi,4),%xmm4
punpckldq %xmm2,%xmm3
paddq  %xmm0,%xmm3
punpckldq %xmm2,%xmm4
paddq  %xmm1,%xmm4
movq   -0x68(%rsp,%rsi,4),%xmm0
movq   -0x60(%rsp,%rsi,4),%xmm1
punpckldq %xmm2,%xmm0
paddq  %xmm3,%xmm0
punpckldq %xmm2,%xmm1
paddq  %xmm4,%xmm1
add    $0x8,%rsi
add    $0xfffffffffffffffe,%rdi
jne    11d0 <ip_verify_checksum+0xd0>
test   $0x1,%dl
je     1237 <ip_verify_checksum+0x137>
movq   -0x78(%rsp,%rsi,4),%xmm2
movq   -0x70(%rsp,%rsi,4),%xmm3
pxor   %xmm4,%xmm4
punpckldq %xmm4,%xmm2
paddq  %xmm2,%xmm0
punpckldq %xmm4,%xmm3
paddq  %xmm3,%xmm1
paddq  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddq  %xmm0,%xmm1
movq   %xmm1,%rdx
cmp    %r8,%rcx
je     1260 <ip_verify_checksum+0x160>
xchg   %ax,%ax
mov    -0x78(%rsp,%rcx,4),%eax
add    %rax,%rdx
add    $0x1,%rcx
cmp    %rcx,%r8
jne    1250 <ip_verify_checksum+0x150>
mov    %rdx,%rax
shr    $0x10,%rax
movzwl %dx,%ecx
add    %ecx,%eax
cmp    $0xffffffff,%eax
setne  %al
ret
pxor   %xmm0,%xmm0
xor    %esi,%esi
pxor   %xmm1,%xmm1
test   $0x1,%dl
jne    1217 <ip_verify_checksum+0x117>
jmp    1237 <ip_verify_checksum+0x137>

LLVM IR (-O0):
define zeroext i8 @ip_verify_checksum(i8* %0, i32 %1) {
%3 = alloca i8
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i8
%7 = alloca i8
%8 = alloca i8
%9 = alloca i32
%10 = alloca i32
%11 = alloca [30 x i32]
%12 = alloca i32
%13 = alloca i64
%14 = alloca i64
store i8* %0, i8** %4
store i32 %1, i32* %5
store i8 0, i8* %7
store i8 1, i8* %8
store i64 0, i64* %13
store i64 0, i64* %14
%15 = load i32, i32* %5
%16 = udiv i32 %15, 2
%17 = trunc i32 %16 to i8
store i8 %17, i8* %6
store i32 0, i32* %9
store i32 0, i32* %10
br label %18
18: ; preds = %53, %2
%19 = load i32, i32* %9
%20 = load i8, i8* %6
%21 = zext i8 %20 to i32
%22 = icmp ult i32 %19, %21
br i1 %22, label %23, label %58
23: ; preds = %18
%24 = load i8*, i8** %4
%25 = load i32, i32* %10
%26 = zext i32 %25 to i64
%27 = getelementptr inbounds i8, i8* %24, i64 %26
%28 = load i8, i8* %27
%29 = zext i8 %28 to i32
%30 = load i32, i32* %9
%31 = zext i32 %30 to i64
%32 = getelementptr inbounds [30 x i32], [30 x i32]* %11, i64 0, i64 %31
store i32 %29, i32* %32
%33 = load i32, i32* %9
%34 = zext i32 %33 to i64
%35 = getelementptr inbounds [30 x i32], [30 x i32]* %11, i64 0, i64 %34
%36 = load i32, i32* %35
%37 = shl i32 %36, 8
%38 = load i32, i32* %9
%39 = zext i32 %38 to i64
%40 = getelementptr inbounds [30 x i32], [30 x i32]* %11, i64 0, i64 %39
store i32 %37, i32* %40
%41 = load i8*, i8** %4
%42 = load i32, i32* %10
%43 = add i32 %42, 1
%44 = zext i32 %43 to i64
%45 = getelementptr inbounds i8, i8* %41, i64 %44
%46 = load i8, i8* %45
%47 = zext i8 %46 to i32
%48 = load i32, i32* %9
%49 = zext i32 %48 to i64
%50 = getelementptr inbounds [30 x i32], [30 x i32]* %11, i64 0, i64 %49
%51 = load i32, i32* %50
%52 = or i32 %51, %47
store i32 %52, i32* %50
br label %53
53: ; preds = %23
%54 = load i32, i32* %9
%55 = add i32 %54, 1
store i32 %55, i32* %9
%56 = load i32, i32* %10
%57 = add i32 %56, 2
store i32 %57, i32* %10
br label %18
58: ; preds = %18
store i32 0, i32* %9
br label %59
59: ; preds = %72, %58
%60 = load i32, i32* %9
%61 = load i8, i8* %6
%62 = zext i8 %61 to i32
%63 = icmp ult i32 %60, %62
br i1 %63, label %64, label %75
64: ; preds = %59
%65 = load i32, i32* %9
%66 = zext i32 %65 to i64
%67 = getelementptr inbounds [30 x i32], [30 x i32]* %11, i64 0, i64 %66
%68 = load i32, i32* %67
%69 = zext i32 %68 to i64
%70 = load i64, i64* %13
%71 = add nsw i64 %70, %69
store i64 %71, i64* %13
br label %72
72: ; preds = %64
%73 = load i32, i32* %9
%74 = add i32 %73, 1
store i32 %74, i32* %9
br label %59
75: ; preds = %59
%76 = load i64, i64* %13
%77 = ashr i64 %76, 16
store i64 %77, i64* %14
%78 = load i64, i64* %13
%79 = and i64 %78, 65535
store i64 %79, i64* %13
%80 = load i64, i64* %13
%81 = load i64, i64* %14
%82 = add nsw i64 %80, %81
%83 = trunc i64 %82 to i32
store i32 %83, i32* %12
%84 = load i32, i32* %12
%85 = xor i32 %84, -1
store i32 %85, i32* %12
%86 = load i32, i32* %12
%87 = icmp eq i32 %86, 0
br i1 %87, label %88, label %90
88: ; preds = %75
%89 = load i8, i8* %7
store i8 %89, i8* %3
br label %92
90: ; preds = %75
%91 = load i8, i8* %8
store i8 %91, i8* %3
br label %92
92: ; preds = %90, %88
%93 = load i8, i8* %3
ret i8 %93
}

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