#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 */
typedef char *__sum16;

/* Variables and functions */
__sum16 ip_fast_csum(const void *iph, unsigned int ihl) {
  unsigned int sum;
  asm("  movl (%1), %0\n"
      "  subl $4, %2\n"
      "  jbe 2f\n"
      "  addl 4(%1), %0\n"
      "  adcl 8(%1), %0\n"
      "  adcl 12(%1), %0\n"
      "1: adcl 16(%1), %0\n"
      "  lea 4(%1), %1\n"
      "  decl %2\n"
      "  jne      1b\n"
      "  adcl $0, %0\n"
      "  movl %0, %2\n"
      "  shrl $16, %0\n"
      "  addw %w2, %w0\n"
      "  adcl $0, %0\n"
      "  notl %0\n"
      "2:"
      : "=r"(sum), "=r"(iph), "=r"(ihl)
      : "1"(iph), "2"(ihl)
      : "memory");
  return (__sum16)sum;
}


x86 assembly (clang, -O0):
<ip_fast_csum>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0x8(%rbp),%rcx
mov    -0xc(%rbp),%eax
mov    (%rcx),%edx
sub    $0x4,%eax
jbe    1145 <ip_fast_csum+0x45>
add    0x4(%rcx),%edx
adc    0x8(%rcx),%edx
adc    0xc(%rcx),%edx
adc    0x10(%rcx),%edx
lea    0x4(%rcx),%rcx
dec    %eax
jne    1126 <ip_fast_csum+0x26>
adc    $0x0,%edx
mov    %edx,%eax
shr    $0x10,%edx
add    %ax,%dx
adc    $0x0,%edx
not    %edx
mov    %edx,-0x10(%rbp)
mov    %rcx,-0x8(%rbp)
mov    %eax,-0xc(%rbp)
mov    -0x10(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ip_fast_csum>:
mov    (%rdi),%eax
sub    $0x4,%esi
jbe    112b <ip_fast_csum+0x2b>
add    0x4(%rdi),%eax
adc    0x8(%rdi),%eax
adc    0xc(%rdi),%eax
adc    0x10(%rdi),%eax
lea    0x4(%rdi),%rdi
dec    %esi
jne    1110 <ip_fast_csum+0x10>
adc    $0x0,%eax
mov    %eax,%esi
shr    $0x10,%eax
add    %si,%ax
adc    $0x0,%eax
not    %eax
mov    %eax,%eax
ret

LLVM IR (-O0):
define i8* @ip_fast_csum(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i32
store i8* %0, i8** %3
store i32 %1, i32* %4
%6 = load i8*, i8** %3
%7 = load i32, i32* %4
%8 = call { i32, i8*, i32 } asm " movl ($1), $0\0A subl $$4, $2\0A jbe 2f\0A addl 4($1), $0\0A adcl 8($1), $0\0A adcl 12($1), $0\0A1: adcl 16($1), $0\0A lea 4($1), $1\0A decl $2\0A jne 1b\0A adcl $$0, $0\0A movl $0, $2\0A shrl $$16, $0\0A addw ${2:w}, ${0:w}\0A adcl $$0, $0\0A notl $0\0A2:", "=r,=r,=r,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %6, i32 %7)
%9 = extractvalue { i32, i8*, i32 } %8, 0
%10 = extractvalue { i32, i8*, i32 } %8, 1
%11 = extractvalue { i32, i8*, i32 } %8, 2
store i32 %9, i32* %5
store i8* %10, i8** %3
store i32 %11, i32* %4
%12 = load i32, i32* %5
%13 = zext i32 %12 to i64
%14 = inttoptr i64 %13 to i8*
ret i8* %14
}

LLVM IR (-O2):
define i8* @ip_fast_csum(i8* %0, i32 %1) {
%3 = tail call { i32, i8*, i32 } asm " movl ($1), $0\0A subl $$4, $2\0A jbe 2f\0A addl 4($1), $0\0A adcl 8($1), $0\0A adcl 12($1), $0\0A1: adcl 16($1), $0\0A lea 4($1), $1\0A decl $2\0A jne 1b\0A adcl $$0, $0\0A movl $0, $2\0A shrl $$16, $0\0A addw ${2:w}, ${0:w}\0A adcl $$0, $0\0A notl $0\0A2:", "=r,=r,=r,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %0, i32 %1)
%4 = extractvalue { i32, i8*, i32 } %3, 0
%5 = zext i32 %4 to i64
%6 = inttoptr i64 %5 to i8*
ret i8* %6
}