#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 */
typedef struct TYPE_4__ TYPE_2__;
typedef struct TYPE_3__ TYPE_1__;

/* Type definitions */
struct udphdr {
  int uh_sum;
};
struct tcphdr {
  int th_sum;
};
struct TYPE_3__ {
  int ip6_un1_nxt;
};
struct TYPE_4__ {
  TYPE_1__ ip6_un1;
};
struct ip6_hdr {
  int /*<<< orphan*/ ip6_src;
  TYPE_2__ ip6_ctlun;
};
struct ip6_frag {
  int ip6f_nxt;
};
struct ip6_dest {
  int ip6d_nxt;
  int ip6d_len;
};
struct ip {
  int ip_hl;
  int ip_sum;
  int /*<<< orphan*/ ip_src;
};
struct icmp6_hdr {
  int icmp6_cksum;
};
struct icmp {
  int icmp_cksum;
};

/* Variables and functions */
#define IPPROTO_DSTOPTS 134
#define IPPROTO_FRAGMENT 133
#define IPPROTO_ICMP 132
#define IPPROTO_ICMPV6 131
#define IPPROTO_IP 130
#define IPPROTO_TCP 129
#define IPPROTO_UDP 128
int in_cksum(unsigned short *, int);
int ntohs(int /*<<< orphan*/);
int do_checksum(char *buf, int protocol, int len) {
  struct ip *iph_p = NULL;
  struct ip6_hdr *ip6h_p = NULL;
  int ip_hl;
  int sum = 0;
  int ip_version = buf[0] >> 4;
  if (ip_version == 6) {
    int next_header;
    ip6h_p = (struct ip6_hdr *)buf;
    next_header = ip6h_p->ip6_ctlun.ip6_un1.ip6_un1_nxt;
    ip_hl = sizeof(struct ip6_hdr);
    while (next_header != protocol) {
      switch (next_header) {
      case IPPROTO_FRAGMENT:
        next_header = ((struct ip6_frag *)(buf + ip_hl))->ip6f_nxt;
        ip_hl += sizeof(struct ip6_frag);
        break;
      case IPPROTO_DSTOPTS:
        next_header = ((struct ip6_dest *)(buf + ip_hl))->ip6d_nxt;
        ip_hl += (((struct ip6_dest *)(buf + ip_hl))->ip6d_len * 8) + 8;
        break;
      default:
        return 0;
      }
    }
  } else if (ip_version == 4) {
    iph_p = (struct ip *)buf;
    ip_hl = iph_p->ip_hl << 2;
  } else {
    return (0);
  }
  if (ip_hl < 0)
    return -2;
  switch (protocol) {
  case IPPROTO_UDP: {
    struct udphdr *udph_p = (struct udphdr *)(buf + ip_hl);
    udph_p->uh_sum = 0;
    if (ip_version == 6) {
      sum = in_cksum((unsigned short *)&ip6h_p->ip6_src, 32);
    } else {
      sum = in_cksum((void *)&iph_p->ip_src, 8);
    }
    sum += ntohs(IPPROTO_UDP + len);
    sum += in_cksum((unsigned short *)udph_p, len);
    udph_p->uh_sum =
        (sum = (sum >> 16) + (sum & 0xffff), (~(sum + (sum >> 16)) & 0xffff));
    break;
  }
  case IPPROTO_TCP: {
    struct tcphdr *tcph_p = (struct tcphdr *)(buf + ip_hl);
    tcph_p->th_sum = 0;
    if (ip_version == 6) {
      sum = in_cksum((unsigned short *)&ip6h_p->ip6_src, 32);
    } else {
      sum = in_cksum((void *)&iph_p->ip_src, 8);
    }
    sum += ntohs(IPPROTO_TCP + len);
    sum += in_cksum((unsigned short *)tcph_p, len);
    tcph_p->th_sum =
        (sum = (sum >> 16) + (sum & 0xffff), (~(sum + (sum >> 16)) & 0xffff));
    break;
  }
  case IPPROTO_ICMP: {
    struct icmp *icmph_p = (struct icmp *)(buf + ip_hl);
    icmph_p->icmp_cksum = 0;
    sum = in_cksum((unsigned short *)icmph_p, len);
    icmph_p->icmp_cksum =
        (sum = (sum >> 16) + (sum & 0xffff), (~(sum + (sum >> 16)) & 0xffff));
    break;
  }
  case IPPROTO_ICMPV6: {
    struct icmp6_hdr *icmp6h_p = (struct icmp6_hdr *)(buf + ip_hl);
    if (ip_version == 6) {
      sum = in_cksum((unsigned short *)&ip6h_p->ip6_src, 32);
    } else {
      return 0;
    }
    sum += ntohs(IPPROTO_ICMPV6 + len);
    icmp6h_p->icmp6_cksum = 0;
    sum += in_cksum((unsigned short *)icmp6h_p, len);
    icmp6h_p->icmp6_cksum =
        (sum = (sum >> 16) + (sum & 0xffff), (~(sum + (sum >> 16)) & 0xffff));
    break;
  }
  case IPPROTO_IP: {
    iph_p->ip_sum = 0;
    sum = in_cksum((unsigned short *)iph_p, len);
    iph_p->ip_sum =
        (sum = (sum >> 16) + (sum & 0xffff), (~(sum + (sum >> 16)) & 0xffff));
    break;
  }
  default: {
    return (-1);
  }
  }
  return (1);
}


x86 assembly (clang, -O0):
<do_checksum>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
sar    $0x4,%eax
mov    %eax,-0x34(%rbp)
cmpl   $0x6,-0x34(%rbp)
jne    120d <do_checksum+0xed>
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
mov    0x4(%rax),%eax
mov    %eax,-0x38(%rbp)
movl   $0x8,-0x2c(%rbp)
mov    -0x38(%rbp),%eax
cmp    -0x14(%rbp),%eax
je     1208 <do_checksum+0xe8>
mov    -0x38(%rbp),%eax
mov    %eax,-0x5c(%rbp)
sub    $0x85,%eax
je     11ae <do_checksum+0x8e>
jmp    119b <do_checksum+0x7b>
mov    -0x5c(%rbp),%eax
sub    $0x86,%eax
je     11cc <do_checksum+0xac>
jmp    11f7 <do_checksum+0xd7>
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    (%rax,%rcx,1),%eax
mov    %eax,-0x38(%rbp)
movslq -0x2c(%rbp),%rax
add    $0x4,%rax
mov    %eax,-0x2c(%rbp)
jmp    1203 <do_checksum+0xe3>
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    (%rax,%rcx,1),%eax
mov    %eax,-0x38(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    0x4(%rax,%rcx,1),%eax
shl    $0x3,%eax
add    $0x8,%eax
add    -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
jmp    1203 <do_checksum+0xe3>
movl   $0x0,-0x4(%rbp)
jmp    1528 <do_checksum+0x408>
jmp    1179 <do_checksum+0x59>
jmp    1241 <do_checksum+0x121>
cmpl   $0x4,-0x34(%rbp)
jne    1230 <do_checksum+0x110>
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
shl    $0x2,%eax
mov    %eax,-0x2c(%rbp)
jmp    123c <do_checksum+0x11c>
movl   $0x0,-0x4(%rbp)
jmp    1528 <do_checksum+0x408>
jmp    1241 <do_checksum+0x121>
cmpl   $0x0,-0x2c(%rbp)
jge    1257 <do_checksum+0x137>
movl   $0xfffffffe,-0x4(%rbp)
jmp    1528 <do_checksum+0x408>
mov    -0x14(%rbp),%eax
add    $0xffffff80,%eax
mov    %eax,%ecx
mov    %rcx,-0x68(%rbp)
sub    $0x4,%eax
ja     1515 <do_checksum+0x3f5>
mov    -0x68(%rbp),%rax
lea    0xd89(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rax
movl   $0x0,(%rax)
cmpl   $0x6,-0x34(%rbp)
jne    12b9 <do_checksum+0x199>
mov    -0x28(%rbp),%rdi
mov    $0x20,%esi
call   1030 <in_cksum@plt>
mov    %eax,-0x30(%rbp)
jmp    12ce <do_checksum+0x1ae>
mov    -0x20(%rbp),%rdi
add    $0x8,%rdi
mov    $0x8,%esi
call   1030 <in_cksum@plt>
mov    %eax,-0x30(%rbp)
mov    -0x18(%rbp),%edi
add    $0x80,%edi
call   1040 <ntohs@plt>
add    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x40(%rbp),%rdi
mov    -0x18(%rbp),%esi
call   1030 <in_cksum@plt>
add    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
mov    -0x30(%rbp),%ecx
and    $0xffff,%ecx
add    %ecx,%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%ecx
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
add    %eax,%ecx
xor    $0xffffffff,%ecx
and    $0xffff,%ecx
mov    -0x40(%rbp),%rax
mov    %ecx,(%rax)
jmp    1521 <do_checksum+0x401>
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
movl   $0x0,(%rax)
cmpl   $0x6,-0x34(%rbp)
jne    1360 <do_checksum+0x240>
mov    -0x28(%rbp),%rdi
mov    $0x20,%esi
call   1030 <in_cksum@plt>
mov    %eax,-0x30(%rbp)
jmp    1375 <do_checksum+0x255>
mov    -0x20(%rbp),%rdi
add    $0x8,%rdi
mov    $0x8,%esi
call   1030 <in_cksum@plt>
mov    %eax,-0x30(%rbp)
mov    -0x18(%rbp),%edi
add    $0x81,%edi
call   1040 <ntohs@plt>
add    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x48(%rbp),%rdi
mov    -0x18(%rbp),%esi
call   1030 <in_cksum@plt>
add    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
mov    -0x30(%rbp),%ecx
and    $0xffff,%ecx
add    %ecx,%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%ecx
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
add    %eax,%ecx
xor    $0xffffffff,%ecx
and    $0xffff,%ecx
mov    -0x48(%rbp),%rax
mov    %ecx,(%rax)
jmp    1521 <do_checksum+0x401>
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rax
movl   $0x0,(%rax)
mov    -0x50(%rbp),%rdi
mov    -0x18(%rbp),%esi
call   1030 <in_cksum@plt>
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
mov    -0x30(%rbp),%ecx
and    $0xffff,%ecx
add    %ecx,%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%ecx
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
add    %eax,%ecx
xor    $0xffffffff,%ecx
and    $0xffff,%ecx
mov    -0x50(%rbp),%rax
mov    %ecx,(%rax)
jmp    1521 <do_checksum+0x401>
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x58(%rbp)
cmpl   $0x6,-0x34(%rbp)
jne    1458 <do_checksum+0x338>
mov    -0x28(%rbp),%rdi
mov    $0x20,%esi
call   1030 <in_cksum@plt>
mov    %eax,-0x30(%rbp)
jmp    1464 <do_checksum+0x344>
movl   $0x0,-0x4(%rbp)
jmp    1528 <do_checksum+0x408>
mov    -0x18(%rbp),%edi
add    $0x83,%edi
call   1040 <ntohs@plt>
add    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x58(%rbp),%rax
movl   $0x0,(%rax)
mov    -0x58(%rbp),%rdi
mov    -0x18(%rbp),%esi
call   1030 <in_cksum@plt>
add    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
mov    -0x30(%rbp),%ecx
and    $0xffff,%ecx
add    %ecx,%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%ecx
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
add    %eax,%ecx
xor    $0xffffffff,%ecx
and    $0xffff,%ecx
mov    -0x58(%rbp),%rax
mov    %ecx,(%rax)
jmp    1521 <do_checksum+0x401>
mov    -0x20(%rbp),%rax
movl   $0x0,0x4(%rax)
mov    -0x20(%rbp),%rdi
mov    -0x18(%rbp),%esi
call   1030 <in_cksum@plt>
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
mov    -0x30(%rbp),%ecx
and    $0xffff,%ecx
add    %ecx,%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%ecx
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
add    %eax,%ecx
xor    $0xffffffff,%ecx
and    $0xffff,%ecx
mov    -0x20(%rbp),%rax
mov    %ecx,0x4(%rax)
jmp    1521 <do_checksum+0x401>
movl   $0xffffffff,-0x4(%rbp)
jmp    1528 <do_checksum+0x408>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<do_checksum>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %edx,%r14d
mov    %rdi,%rbx
mov    (%rdi),%dl
sar    $0x4,%dl
cmp    $0x6,%dl
jne    1185 <do_checksum+0x65>
mov    0x4(%rbx),%eax
mov    $0x8,%ebp
xor    %edi,%edi
cmp    %esi,%eax
jne    116a <do_checksum+0x4a>
mov    %rbx,%rcx
jmp    119e <do_checksum+0x7e>
nopw   0x0(%rax,%rax,1)
movslq %ebp,%rcx
lea    (%rbx,%rcx,1),%rax
mov    0x4(%rbx,%rcx,1),%ecx
lea    0x8(,%rcx,8),%ecx
add    %ecx,%ebp
mov    (%rax),%eax
cmp    %esi,%eax
je     11dd <do_checksum+0xbd>
cmp    $0x86,%eax
je     1150 <do_checksum+0x30>
cmp    $0x85,%eax
jne    11ee <do_checksum+0xce>
movslq %ebp,%rax
add    %rbx,%rax
mov    $0x4,%ecx
jmp    1162 <do_checksum+0x42>
xor    %eax,%eax
cmp    $0x4,%dl
jne    12f2 <do_checksum+0x1d2>
mov    (%rbx),%ebp
shl    $0x2,%ebp
xor    %ecx,%ecx
mov    %rbx,%rdi
test   %ebp,%ebp
js     11e4 <do_checksum+0xc4>
add    $0xffffff80,%esi
cmp    $0x4,%esi
ja     1268 <do_checksum+0x148>
lea    0xe4f(%rip),%rax
movslq (%rax,%rsi,4),%rsi
add    %rax,%rsi
jmp    *%rsi
mov    %ebp,%eax
lea    (%rbx,%rax,1),%r15
movl   $0x0,(%rbx,%rax,1)
cmp    $0x6,%dl
jne    128e <do_checksum+0x16e>
mov    %rcx,%rdi
mov    $0x20,%esi
jmp    1297 <do_checksum+0x177>
mov    %rbx,%rcx
test   %ebp,%ebp
jns    119e <do_checksum+0x7e>
mov    $0xfffffffe,%eax
jmp    12f2 <do_checksum+0x1d2>
xor    %eax,%eax
jmp    12f2 <do_checksum+0x1d2>
lea    0x4(%rdi),%r15
movl   $0x0,0x4(%rdi)
jmp    125e <do_checksum+0x13e>
xor    %eax,%eax
cmp    $0x6,%dl
jne    12f2 <do_checksum+0x1d2>
mov    %ebp,%eax
add    %rax,%rbx
mov    %rcx,%rdi
mov    $0x20,%esi
call   1030 <in_cksum@plt>
mov    %eax,%r15d
lea    0x83(%r14),%edi
call   1040 <ntohs@plt>
mov    %eax,%ebp
add    %r15d,%ebp
movl   $0x0,(%rbx)
mov    %rbx,%rdi
mov    %r14d,%esi
call   1030 <in_cksum@plt>
add    %ebp,%eax
mov    %rbx,%r15
jmp    12d4 <do_checksum+0x1b4>
mov    %ebp,%eax
lea    (%rbx,%rax,1),%r15
movl   $0x0,(%rbx,%rax,1)
mov    %r15,%rdi
mov    %r14d,%esi
call   1030 <in_cksum@plt>
jmp    12d4 <do_checksum+0x1b4>
mov    $0xffffffff,%eax
jmp    12f2 <do_checksum+0x1d2>
mov    %ebp,%eax
lea    (%rbx,%rax,1),%r15
movl   $0x0,(%rbx,%rax,1)
cmp    $0x6,%dl
jne    12a7 <do_checksum+0x187>
mov    %rcx,%rdi
mov    $0x20,%esi
jmp    12b0 <do_checksum+0x190>
add    $0x8,%rdi
mov    $0x8,%esi
call   1030 <in_cksum@plt>
mov    %eax,%ebx
lea    0x80(%r14),%edi
jmp    12be <do_checksum+0x19e>
add    $0x8,%rdi
mov    $0x8,%esi
call   1030 <in_cksum@plt>
mov    %eax,%ebx
lea    0x81(%r14),%edi
call   1040 <ntohs@plt>
mov    %eax,%ebp
add    %ebx,%ebp
mov    %r15,%rdi
mov    %r14d,%esi
call   1030 <in_cksum@plt>
add    %ebp,%eax
mov    %eax,%ecx
sar    $0x10,%ecx
movzwl %ax,%eax
add    %ecx,%eax
mov    %eax,%ecx
shr    $0x10,%ecx
add    %eax,%ecx
not    %ecx
movzwl %cx,%eax
mov    %eax,(%r15)
mov    $0x1,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.ip = type { i32, i32, i32 }
%struct.ip6_hdr = type { i32, %struct.TYPE_4__ }
%struct.TYPE_4__ = type { %struct.TYPE_3__ }
%struct.TYPE_3__ = type { i32 }
%struct.udphdr = type { i32 }
%struct.tcphdr = type { i32 }
%struct.icmp = type { i32 }
%struct.icmp6_hdr = type { i32 }
%struct.ip6_frag = type { i32 }
%struct.ip6_dest = type { i32, i32 }
define i32 @do_checksum(i8* %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca %struct.ip*
%9 = alloca %struct.ip6_hdr*
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca %struct.udphdr*
%15 = alloca %struct.tcphdr*
%16 = alloca %struct.icmp*
%17 = alloca %struct.icmp6_hdr*
store i8* %0, i8** %5
store i32 %1, i32* %6
store i32 %2, i32* %7
store %struct.ip* null, %struct.ip** %8
store %struct.ip6_hdr* null, %struct.ip6_hdr** %9
store i32 0, i32* %11
%18 = load i8*, i8** %5
%19 = getelementptr inbounds i8, i8* %18, i64 0
%20 = load i8, i8* %19
%21 = sext i8 %20 to i32
%22 = ashr i32 %21, 4
store i32 %22, i32* %12
%23 = load i32, i32* %12
%24 = icmp eq i32 %23, 6
br i1 %24, label %25, label %73
25: ; preds = %3
%26 = load i8*, i8** %5
%27 = bitcast i8* %26 to %struct.ip6_hdr*
store %struct.ip6_hdr* %27, %struct.ip6_hdr** %9
%28 = load %struct.ip6_hdr*, %struct.ip6_hdr** %9
%29 = getelementptr inbounds %struct.ip6_hdr, %struct.ip6_hdr* %28, i32 0, i32 1
%30 = getelementptr inbounds %struct.TYPE_4__, %struct.TYPE_4__* %29, i32 0, i32 0
%31 = getelementptr inbounds %struct.TYPE_3__, %struct.TYPE_3__* %30, i32 0, i32 0
%32 = load i32, i32* %31
store i32 %32, i32* %13
store i32 8, i32* %10
br label %33
33: ; preds = %71, %25
%34 = load i32, i32* %13
%35 = load i32, i32* %6
%36 = icmp ne i32 %34, %35
br i1 %36, label %37, label %72
37: ; preds = %33
%38 = load i32, i32* %13
switch i32 %38, label %70 [
i32 133, label %39
i32 134, label %51
]
39: ; preds = %37
%40 = load i8*, i8** %5
%41 = load i32, i32* %10
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds i8, i8* %40, i64 %42
%44 = bitcast i8* %43 to %struct.ip6_frag*
%45 = getelementptr inbounds %struct.ip6_frag, %struct.ip6_frag* %44, i32 0, i32 0
%46 = load i32, i32* %45
store i32 %46, i32* %13
%47 = load i32, i32* %10
%48 = sext i32 %47 to i64
%49 = add i64 %48, 4
%50 = trunc i64 %49 to i32
store i32 %50, i32* %10
br label %71
51: ; preds = %37
%52 = load i8*, i8** %5
%53 = load i32, i32* %10
%54 = sext i32 %53 to i64
%55 = getelementptr inbounds i8, i8* %52, i64 %54
%56 = bitcast i8* %55 to %struct.ip6_dest*
%57 = getelementptr inbounds %struct.ip6_dest, %struct.ip6_dest* %56, i32 0, i32 0
%58 = load i32, i32* %57
store i32 %58, i32* %13
%59 = load i8*, i8** %5
%60 = load i32, i32* %10
%61 = sext i32 %60 to i64
%62 = getelementptr inbounds i8, i8* %59, i64 %61
%63 = bitcast i8* %62 to %struct.ip6_dest*
%64 = getelementptr inbounds %struct.ip6_dest, %struct.ip6_dest* %63, i32 0, i32 1
%65 = load i32, i32* %64
%66 = mul nsw i32 %65, 8
%67 = add nsw i32 %66, 8
%68 = load i32, i32* %10
%69 = add nsw i32 %68, %67
store i32 %69, i32* %10
br label %71
70: ; preds = %37
store i32 0, i32* %4
br label %271
71: ; preds = %51, %39
br label %33
72: ; preds = %33
br label %85
73: ; preds = %3
%74 = load i32, i32* %12
%75 = icmp eq i32 %74, 4
br i1 %75, label %76, label %83
76: ; preds = %73
%77 = load i8*, i8** %5
%78 = bitcast i8* %77 to %struct.ip*
store %struct.ip* %78, %struct.ip** %8
%79 = load %struct.ip*, %struct.ip** %8
%80 = getelementptr inbounds %struct.ip, %struct.ip* %79, i32 0, i32 0
%81 = load i32, i32* %80
%82 = shl i32 %81, 2
store i32 %82, i32* %10
br label %84
83: ; preds = %73
store i32 0, i32* %4
br label %271
84: ; preds = %76
br label %85
85: ; preds = %84, %72
%86 = load i32, i32* %10
%87 = icmp slt i32 %86, 0
br i1 %87, label %88, label %89
88: ; preds = %85
store i32 -2, i32* %4
br label %271
89: ; preds = %85
%90 = load i32, i32* %6
switch i32 %90, label %269 [
i32 128, label %91
i32 129, label %137
i32 132, label %183
i32 131, label %208
i32 130, label %249
]
91: ; preds = %89
%92 = load i8*, i8** %5
%93 = load i32, i32* %10
%94 = sext i32 %93 to i64
%95 = getelementptr inbounds i8, i8* %92, i64 %94
%96 = bitcast i8* %95 to %struct.udphdr*
store %struct.udphdr* %96, %struct.udphdr** %14
%97 = load %struct.udphdr*, %struct.udphdr** %14
%98 = getelementptr inbounds %struct.udphdr, %struct.udphdr* %97, i32 0, i32 0
store i32 0, i32* %98
%99 = load i32, i32* %12
%100 = icmp eq i32 %99, 6
br i1 %100, label %101, label %106
101: ; preds = %91
%102 = load %struct.ip6_hdr*, %struct.ip6_hdr** %9
%103 = getelementptr inbounds %struct.ip6_hdr, %struct.ip6_hdr* %102, i32 0, i32 0
%104 = bitcast i32* %103 to i16*
%105 = call i32 @in_cksum(i16* %104, i32 32)
store i32 %105, i32* %11
br label %112
106: ; preds = %91
%107 = load %struct.ip*, %struct.ip** %8
%108 = getelementptr inbounds %struct.ip, %struct.ip* %107, i32 0, i32 2
%109 = bitcast i32* %108 to i8*
%110 = bitcast i8* %109 to i16*
%111 = call i32 @in_cksum(i16* %110, i32 8)
store i32 %111, i32* %11
br label %112
112: ; preds = %106, %101
%113 = load i32, i32* %7
%114 = add nsw i32 128, %113
%115 = call i32 @ntohs(i32 %114)
%116 = load i32, i32* %11
%117 = add nsw i32 %116, %115
store i32 %117, i32* %11
%118 = load %struct.udphdr*, %struct.udphdr** %14
%119 = bitcast %struct.udphdr* %118 to i16*
%120 = load i32, i32* %7
%121 = call i32 @in_cksum(i16* %119, i32 %120)
%122 = load i32, i32* %11
%123 = add nsw i32 %122, %121
store i32 %123, i32* %11
%124 = load i32, i32* %11
%125 = ashr i32 %124, 16
%126 = load i32, i32* %11
%127 = and i32 %126, 65535
%128 = add nsw i32 %125, %127
store i32 %128, i32* %11
%129 = load i32, i32* %11
%130 = load i32, i32* %11
%131 = ashr i32 %130, 16
%132 = add nsw i32 %129, %131
%133 = xor i32 %132, -1
%134 = and i32 %133, 65535
%135 = load %struct.udphdr*, %struct.udphdr** %14
%136 = getelementptr inbounds %struct.udphdr, %struct.udphdr* %135, i32 0, i32 0
store i32 %134, i32* %136
br label %270
137: ; preds = %89
%138 = load i8*, i8** %5
%139 = load i32, i32* %10
%140 = sext i32 %139 to i64
%141 = getelementptr inbounds i8, i8* %138, i64 %140
%142 = bitcast i8* %141 to %struct.tcphdr*
store %struct.tcphdr* %142, %struct.tcphdr** %15
%143 = load %struct.tcphdr*, %struct.tcphdr** %15
%144 = getelementptr inbounds %struct.tcphdr, %struct.tcphdr* %143, i32 0, i32 0
store i32 0, i32* %144
%145 = load i32, i32* %12
%146 = icmp eq i32 %145, 6
br i1 %146, label %147, label %152
147: ; preds = %137
%148 = load %struct.ip6_hdr*, %struct.ip6_hdr** %9
%149 = getelementptr inbounds %struct.ip6_hdr, %struct.ip6_hdr* %148, i32 0, i32 0
%150 = bitcast i32* %149 to i16*
%151 = call i32 @in_cksum(i16* %150, i32 32)
store i32 %151, i32* %11
br label %158
152: ; preds = %137
%153 = load %struct.ip*, %struct.ip** %8
%154 = getelementptr inbounds %struct.ip, %struct.ip* %153, i32 0, i32 2
%155 = bitcast i32* %154 to i8*
%156 = bitcast i8* %155 to i16*
%157 = call i32 @in_cksum(i16* %156, i32 8)
store i32 %157, i32* %11
br label %158
158: ; preds = %152, %147
%159 = load i32, i32* %7
%160 = add nsw i32 129, %159
%161 = call i32 @ntohs(i32 %160)
%162 = load i32, i32* %11
%163 = add nsw i32 %162, %161
store i32 %163, i32* %11
%164 = load %struct.tcphdr*, %struct.tcphdr** %15
%165 = bitcast %struct.tcphdr* %164 to i16*
%166 = load i32, i32* %7
%167 = call i32 @in_cksum(i16* %165, i32 %166)
%168 = load i32, i32* %11
%169 = add nsw i32 %168, %167
store i32 %169, i32* %11
%170 = load i32, i32* %11
%171 = ashr i32 %170, 16
%172 = load i32, i32* %11
%173 = and i32 %172, 65535
%174 = add nsw i32 %171, %173
store i32 %174, i32* %11
%175 = load i32, i32* %11
%176 = load i32, i32* %11
%177 = ashr i32 %176, 16
%178 = add nsw i32 %175, %177
%179 = xor i32 %178, -1
%180 = and i32 %179, 65535
%181 = load %struct.tcphdr*, %struct.tcphdr** %15
%182 = getelementptr inbounds %struct.tcphdr, %struct.tcphdr* %181, i32 0, i32 0
store i32 %180, i32* %182
br label %270
183: ; preds = %89
%184 = load i8*, i8** %5
%185 = load i32, i32* %10
%186 = sext i32 %185 to i64
%187 = getelementptr inbounds i8, i8* %184, i64 %186
%188 = bitcast i8* %187 to %struct.icmp*
store %struct.icmp* %188, %struct.icmp** %16
%189 = load %struct.icmp*, %struct.icmp** %16
%190 = getelementptr inbounds %struct.icmp, %struct.icmp* %189, i32 0, i32 0
store i32 0, i32* %190
%191 = load %struct.icmp*, %struct.icmp** %16
%192 = bitcast %struct.icmp* %191 to i16*
%193 = load i32, i32* %7
%194 = call i32 @in_cksum(i16* %192, i32 %193)
store i32 %194, i32* %11
%195 = load i32, i32* %11
%196 = ashr i32 %195, 16
%197 = load i32, i32* %11
%198 = and i32 %197, 65535
%199 = add nsw i32 %196, %198
store i32 %199, i32* %11
%200 = load i32, i32* %11
%201 = load i32, i32* %11
%202 = ashr i32 %201, 16
%203 = add nsw i32 %200, %202
%204 = xor i32 %203, -1
%205 = and i32 %204, 65535
%206 = load %struct.icmp*, %struct.icmp** %16
%207 = getelementptr inbounds %struct.icmp, %struct.icmp* %206, i32 0, i32 0
store i32 %205, i32* %207
br label %270
208: ; preds = %89
%209 = load i8*, i8** %5
%210 = load i32, i32* %10
%211 = sext i32 %210 to i64
%212 = getelementptr inbounds i8, i8* %209, i64 %211
%213 = bitcast i8* %212 to %struct.icmp6_hdr*
store %struct.icmp6_hdr* %213, %struct.icmp6_hdr** %17
%214 = load i32, i32* %12
%215 = icmp eq i32 %214, 6
br i1 %215, label %216, label %221
216: ; preds = %208
%217 = load %struct.ip6_hdr*, %struct.ip6_hdr** %9
%218 = getelementptr inbounds %struct.ip6_hdr, %struct.ip6_hdr* %217, i32 0, i32 0
%219 = bitcast i32* %218 to i16*
%220 = call i32 @in_cksum(i16* %219, i32 32)
store i32 %220, i32* %11
br label %222
221: ; preds = %208
store i32 0, i32* %4
br label %271
222: ; preds = %216
%223 = load i32, i32* %7
%224 = add nsw i32 131, %223
%225 = call i32 @ntohs(i32 %224)
%226 = load i32, i32* %11
%227 = add nsw i32 %226, %225
store i32 %227, i32* %11
%228 = load %struct.icmp6_hdr*, %struct.icmp6_hdr** %17
%229 = getelementptr inbounds %struct.icmp6_hdr, %struct.icmp6_hdr* %228, i32 0, i32 0
store i32 0, i32* %229
%230 = load %struct.icmp6_hdr*, %struct.icmp6_hdr** %17
%231 = bitcast %struct.icmp6_hdr* %230 to i16*
%232 = load i32, i32* %7
%233 = call i32 @in_cksum(i16* %231, i32 %232)
%234 = load i32, i32* %11
%235 = add nsw i32 %234, %233
store i32 %235, i32* %11
%236 = load i32, i32* %11
%237 = ashr i32 %236, 16
%238 = load i32, i32* %11
%239 = and i32 %238, 65535
%240 = add nsw i32 %237, %239
store i32 %240, i32* %11
%241 = load i32, i32* %11
%242 = load i32, i32* %11
%243 = ashr i32 %242, 16
%244 = add nsw i32 %241, %243
%245 = xor i32 %244, -1
%246 = and i32 %245, 65535
%247 = load %struct.icmp6_hdr*, %struct.icmp6_hdr** %17
%248 = getelementptr inbounds %struct.icmp6_hdr, %struct.icmp6_hdr* %247, i32 0, i32 0
store i32 %246, i32* %248
br label %270
249: ; preds = %89
%250 = load %struct.ip*, %struct.ip** %8
%251 = getelementptr inbounds %struct.ip, %struct.ip* %250, i32 0, i32 1
store i32 0, i32* %251
%252 = load %struct.ip*, %struct.ip** %8
%253 = bitcast %struct.ip* %252 to i16*
%254 = load i32, i32* %7
%255 = call i32 @in_cksum(i16* %253, i32 %254)
store i32 %255, i32* %11
%256 = load i32, i32* %11
%257 = ashr i32 %256, 16
%258 = load i32, i32* %11
%259 = and i32 %258, 65535
%260 = add nsw i32 %257, %259
store i32 %260, i32* %11
%261 = load i32, i32* %11
%262 = load i32, i32* %11
%263 = ashr i32 %262, 16
%264 = add nsw i32 %261, %263
%265 = xor i32 %264, -1
%266 = and i32 %265, 65535
%267 = load %struct.ip*, %struct.ip** %8
%268 = getelementptr inbounds %struct.ip, %struct.ip* %267, i32 0, i32 1
store i32 %266, i32* %268
br label %270
269: ; preds = %89
store i32 -1, i32* %4
br label %271
270: ; preds = %249, %222, %183, %158, %112
store i32 1, i32* %4
br label %271
271: ; preds = %270, %269, %221, %88, %83, %70
%272 = load i32, i32* %4
ret i32 %272
}

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