unsigned short in_chksum_ip(unsigned short *w, int blen) {
  unsigned int cksum;
  cksum = w[0];
  cksum += w[1];
  cksum += w[2];
  cksum += w[3];
  cksum += w[4];
  cksum += w[5];
  cksum += w[6];
  cksum += w[7];
  cksum += w[8];
  cksum += w[9];
  blen -= 20;
  w += 10;
  while (blen) {
    cksum += w[0];
    cksum += w[1];
    w += 2;
    blen -= 4;
  }
  cksum = (cksum >> 16) + (cksum & 0x0000ffff);
  cksum += (cksum >> 16);
  return (unsigned short)(~cksum);
}


x86 assembly (clang, -O0):
<in_chksum_ip>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0x8(%rbp),%rax
movzwl (%rax),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0x2(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0x4(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0x6(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0x8(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0xa(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0xc(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0xe(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0x10(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0x12(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x14,%eax
mov    %eax,-0xc(%rbp)
mov    -0x8(%rbp),%rax
add    $0x14,%rax
mov    %rax,-0x8(%rbp)
cmpl   $0x0,-0xc(%rbp)
je     11e7 <in_chksum_ip+0xe7>
mov    -0x8(%rbp),%rax
movzwl (%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzwl 0x2(%rax),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x8(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x4,%eax
mov    %eax,-0xc(%rbp)
jmp    11a8 <in_chksum_ip+0xa8>
mov    -0x10(%rbp),%eax
shr    $0x10,%eax
mov    -0x10(%rbp),%ecx
and    $0xffff,%ecx
add    %ecx,%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
shr    $0x10,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
xor    $0xffffffff,%eax
movzwl %ax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<in_chksum_ip>:
movdqu (%rdi),%xmm0
pxor   %xmm1,%xmm1
movdqa %xmm0,%xmm2
punpckhwd %xmm1,%xmm2
punpcklwd %xmm1,%xmm0
paddd  %xmm2,%xmm0
movzwl 0x10(%rdi),%eax
movzwl 0x12(%rdi),%ecx
pshufd $0xee,%xmm0,%xmm1
paddd  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddd  %xmm1,%xmm0
movd   %xmm0,%edx
add    %eax,%edx
add    %ecx,%edx
mov    %esi,%r8d
add    $0xffffffec,%r8d
je     1215 <in_chksum_ip+0x115>
lea    0x14(%rdi),%rax
add    $0xffffffe8,%esi
cmp    $0x1c,%esi
jb     11f6 <in_chksum_ip+0xf6>
shr    $0x2,%esi
add    $0x1,%esi
mov    %esi,%r9d
and    $0xfffffff8,%r9d
lea    0x0(,%r9,4),%ecx
sub    %ecx,%r8d
lea    (%rax,%r9,4),%rax
movd   %edx,%xmm2
pxor   %xmm0,%xmm0
xor    %edx,%edx
movdqa 0xe7b(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
nop
movdqu 0x14(%rdi,%rdx,4),%xmm3
movdqu 0x24(%rdi,%rdx,4),%xmm4
movdqa %xmm3,%xmm5
pand   %xmm1,%xmm5
paddd  %xmm2,%xmm5
movdqa %xmm4,%xmm6
pand   %xmm1,%xmm6
paddd  %xmm0,%xmm6
psrld  $0x10,%xmm3
movdqa %xmm3,%xmm2
paddd  %xmm5,%xmm2
psrld  $0x10,%xmm4
movdqa %xmm4,%xmm0
paddd  %xmm6,%xmm0
add    $0x8,%rdx
cmp    %rdx,%r9
jne    1190 <in_chksum_ip+0x90>
paddd  %xmm2,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddd  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddd  %xmm1,%xmm0
movd   %xmm0,%edx
cmp    %rsi,%r9
je     1215 <in_chksum_ip+0x115>
mov    %r8d,%ecx
xor    %esi,%esi
nopl   0x0(%rax,%rax,1)
movzwl (%rax,%rsi,1),%edi
add    %edx,%edi
movzwl 0x2(%rax,%rsi,1),%edx
add    %edi,%edx
add    $0x4,%rsi
cmp    %esi,%ecx
jne    1200 <in_chksum_ip+0x100>
mov    %edx,%eax
shr    $0x10,%eax
movzwl %dx,%ecx
add    %eax,%ecx
mov    %ecx,%eax
shr    $0x10,%eax
add    %ecx,%eax
not    %eax
ret

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

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