#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
unsigned long from32to16(unsigned long);
unsigned int do_csum(const unsigned char *buff, int len) {
  int odd, count;
  unsigned long result = 0;
  if (len <= 0) {
    goto out;
  }
  odd = 1 & (unsigned long)buff;
  if (odd) {
    result += (*buff << 8);
    len--;
    buff++;
  }
  count = len >> 1;
  if (count) {
    if (2 & (unsigned long)buff) {
      result += *(unsigned short *)buff;
      count--;
      len -= 2;
      buff += 2;
    }
    count >>= 1;
    if (count) {
      unsigned long carry = 0;
      do {
        unsigned long w = *(unsigned int *)buff;
        count--;
        buff += 4;
        result += carry;
        result += w;
        carry = (w > result);
      } while (count);
      result += carry;
      result = (result & 0xffff) + (result >> 16);
    }
    if (len & 2) {
      result += *(unsigned short *)buff;
      buff += 2;
    }
  }
  if (len & 1) {
    result += (*buff << 8);
  }
  result = from32to16(result);
  if (odd) {
    result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
  }
out:
  return result;
}


x86 assembly (clang, -O0):
<do_csum>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movq   $0x0,-0x20(%rbp)
cmpl   $0x0,-0xc(%rbp)
jg     1136 <do_csum+0x26>
jmp    12ef <do_csum+0x1df>
mov    -0x8(%rbp),%rax
and    $0x1,%rax
mov    %eax,-0x10(%rbp)
cmpl   $0x0,-0x10(%rbp)
je     1174 <do_csum+0x64>
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
shl    $0x8,%eax
cltq
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0xc(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
je     128c <do_csum+0x17c>
mov    -0x8(%rbp),%rax
and    $0x2,%rax
cmp    $0x0,%rax
je     11c6 <do_csum+0xb6>
mov    -0x8(%rbp),%rax
movzwl (%rax),%eax
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x2,%eax
mov    %eax,-0xc(%rbp)
mov    -0x8(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x8(%rbp)
mov    -0x14(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
je     125d <do_csum+0x14d>
movq   $0x0,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%eax
mov    %rax,-0x30(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x8(%rbp)
mov    -0x28(%rbp),%rax
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x30(%rbp),%rax
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x30(%rbp),%rax
cmp    -0x20(%rbp),%rax
seta   %al
and    $0x1,%al
movzbl %al,%eax
cltq
mov    %rax,-0x28(%rbp)
cmpl   $0x0,-0x14(%rbp)
jne    11e1 <do_csum+0xd1>
mov    -0x28(%rbp),%rax
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
and    $0xffff,%rax
mov    -0x20(%rbp),%rcx
shr    $0x10,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
and    $0x2,%eax
cmp    $0x0,%eax
je     1287 <do_csum+0x177>
mov    -0x8(%rbp),%rax
movzwl (%rax),%eax
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x8(%rbp)
jmp    128c <do_csum+0x17c>
mov    -0xc(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     12af <do_csum+0x19f>
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
shl    $0x8,%eax
cltq
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rdi
call   1030 <from32to16@plt>
mov    %rax,-0x20(%rbp)
cmpl   $0x0,-0x10(%rbp)
je     12ea <do_csum+0x1da>
mov    -0x20(%rbp),%rax
shr    $0x8,%rax
and    $0xff,%rax
mov    -0x20(%rbp),%rcx
and    $0xff,%rcx
shl    $0x8,%rcx
or     %rcx,%rax
mov    %rax,-0x20(%rbp)
jmp    12ef <do_csum+0x1df>
mov    -0x20(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<do_csum>:
test   %esi,%esi
jle    112d <do_csum+0x1d>
push   %r14
push   %rbx
push   %rax
mov    %rdi,%r14
test   $0x1,%r14b
jne    1130 <do_csum+0x20>
xor    %edi,%edi
mov    %r14,%rax
cmp    $0x2,%esi
jae    1144 <do_csum+0x34>
jmp    1164 <do_csum+0x54>
xor    %eax,%eax
ret
movzbl (%r14),%edi
shl    $0x8,%rdi
add    $0xffffffff,%esi
lea    0x1(%r14),%rax
cmp    $0x2,%esi
jb     1164 <do_csum+0x54>
mov    %esi,%r9d
shr    %r9d
test   $0x2,%al
jne    118f <do_csum+0x7f>
cmp    $0x2,%r9d
jae    11a6 <do_csum+0x96>
test   $0x2,%sil
je     1164 <do_csum+0x54>
movzwl (%rax),%ecx
add    %rcx,%rdi
add    $0x2,%rax
test   $0x1,%sil
je     1174 <do_csum+0x64>
movzbl (%rax),%eax
shl    $0x8,%rax
add    %rax,%rdi
call   1030 <from32to16@plt>
test   $0x1,%r14b
lea    0x8(%rsp),%rsp
pop    %rbx
pop    %r14
je     118e <do_csum+0x7e>
rol    $0x8,%ax
movzwl %ax,%eax
ret
movzwl (%rax),%ecx
add    %rcx,%rdi
add    $0xffffffff,%r9d
add    $0xfffffffe,%esi
add    $0x2,%rax
cmp    $0x2,%r9d
jb     1154 <do_csum+0x44>
sar    %r9d
lea    -0x1(%r9),%ebx
mov    %r9d,%r8d
and    $0x3,%r8d
cmp    $0x3,%ebx
jae    11bd <do_csum+0xad>
xor    %ebx,%ebx
jmp    1208 <do_csum+0xf8>
and    $0xfffffffc,%r9d
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
add    %rbx,%rdi
mov    (%rax),%ecx
mov    0x4(%rax),%ebx
add    %rdi,%rcx
adc    $0x0,%rcx
add    %rbx,%rcx
mov    0x8(%rax),%edi
adc    $0x0,%rcx
mov    0xc(%rax),%edx
add    $0x10,%rax
add    %rdi,%rcx
adc    $0x0,%rcx
xor    %ebx,%ebx
mov    %rcx,%rdi
add    %rdx,%rdi
setb   %bl
add    $0xfffffffc,%r9d
jne    11d0 <do_csum+0xc0>
test   %r8d,%r8d
je     1227 <do_csum+0x117>
nopl   (%rax)
add    %rbx,%rdi
mov    (%rax),%ecx
add    $0x4,%rax
xor    %ebx,%ebx
add    %rcx,%rdi
setb   %bl
add    $0xffffffff,%r8d
jne    1210 <do_csum+0x100>
add    %rbx,%rdi
movzwl %di,%ecx
shr    $0x10,%rdi
add    %rcx,%rdi
test   $0x2,%sil
jne    115a <do_csum+0x4a>
jmp    1164 <do_csum+0x54>

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

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