#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 int /*<<< orphan*/ uint8_t;
typedef int uint32_t;

/* Variables and functions */
uint32_t crc32(uint8_t *buf, int len) {
  static const uint32_t table[16] = {
      0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
      0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
      0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
  };
  uint32_t crc = 0;
  while (len--) {
    crc ^= *buf++ << 24;
    crc = (crc << 4) ^ table[crc >> 28];
    crc = (crc << 4) ^ table[crc >> 28];
  }
  return crc;
}


x86 assembly (clang, -O0):
<crc32>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0xc(%rbp)
cmp    $0x0,%eax
je     117d <crc32+0x7d>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x8(%rbp)
mov    (%rax),%eax
shl    $0x18,%eax
xor    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
shl    $0x4,%eax
mov    -0x10(%rbp),%ecx
sar    $0x1c,%ecx
movslq %ecx,%rdx
lea    0xeaa(%rip),%rcx
xor    (%rcx,%rdx,4),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
shl    $0x4,%eax
mov    -0x10(%rbp),%ecx
sar    $0x1c,%ecx
movslq %ecx,%rdx
lea    0xe8e(%rip),%rcx
xor    (%rcx,%rdx,4),%eax
mov    %eax,-0x10(%rbp)
jmp    1112 <crc32+0x12>
mov    -0x10(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<crc32>:
test   %esi,%esi
je     1150 <crc32+0x50>
mov    %esi,%r8d
xor    %edx,%edx
lea    0xef0(%rip),%r9
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    (%rdi,%rdx,4),%ecx
shl    $0x18,%ecx
xor    %eax,%ecx
mov    %ecx,%esi
shl    $0x4,%esi
sar    $0x1c,%ecx
movslq %ecx,%rax
xor    (%r9,%rax,4),%esi
mov    %esi,%eax
shl    $0x4,%eax
sar    $0x1c,%esi
movslq %esi,%rcx
xor    (%r9,%rcx,4),%eax
add    $0x1,%rdx
cmp    %edx,%r8d
jne    1120 <crc32+0x20>
ret
xor    %eax,%eax
ret

LLVM IR (-O0):
@crc32.table = internal constant [16 x i32] [i32 0, i32 79764919, i32 159529838, i32 222504665, i32 319059676, i32 398814059, i32 445009330, i32 507990021, i32 638119352, i32 583659535, i32 797628118, i32 726387553, i32 890018660, i32 835552979, i32 1015980042, i32 944750013]
define i32 @crc32(i32* %0, i32 %1) {
%3 = alloca i32*
%4 = alloca i32
%5 = alloca i32
store i32* %0, i32** %3
store i32 %1, i32* %4
store i32 0, i32* %5
br label %6
6: ; preds = %10, %2
%7 = load i32, i32* %4
%8 = add nsw i32 %7, -1
store i32 %8, i32* %4
%9 = icmp ne i32 %7, 0
br i1 %9, label %10, label %33
10: ; preds = %6
%11 = load i32*, i32** %3
%12 = getelementptr inbounds i32, i32* %11, i32 1
store i32* %12, i32** %3
%13 = load i32, i32* %11
%14 = shl i32 %13, 24
%15 = load i32, i32* %5
%16 = xor i32 %15, %14
store i32 %16, i32* %5
%17 = load i32, i32* %5
%18 = shl i32 %17, 4
%19 = load i32, i32* %5
%20 = ashr i32 %19, 28
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds [16 x i32], [16 x i32]* @crc32.table, i64 0, i64 %21
%23 = load i32, i32* %22
%24 = xor i32 %18, %23
store i32 %24, i32* %5
%25 = load i32, i32* %5
%26 = shl i32 %25, 4
%27 = load i32, i32* %5
%28 = ashr i32 %27, 28
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds [16 x i32], [16 x i32]* @crc32.table, i64 0, i64 %29
%31 = load i32, i32* %30
%32 = xor i32 %26, %31
store i32 %32, i32* %5
br label %6
33: ; preds = %6
%34 = load i32, i32* %5
ret i32 %34
}

LLVM IR (-O2):
@crc32.table = internal unnamed_addr constant [16 x i32] [i32 0, i32 79764919, i32 159529838, i32 222504665, i32 319059676, i32 398814059, i32 445009330, i32 507990021, i32 638119352, i32 583659535, i32 797628118, i32 726387553, i32 890018660, i32 835552979, i32 1015980042, i32 944750013]
define i32 @crc32(i32* nocapture %0, i32 %1) {
%3 = icmp eq i32 %1, 0
br i1 %3, label %26, label %4
4: ; preds = %2, %4
%5 = phi i32 [ %24, %4 ], [ 0, %2 ]
%6 = phi i32 [ %8, %4 ], [ %1, %2 ]
%7 = phi i32* [ %9, %4 ], [ %0, %2 ]
%8 = add nsw i32 %6, -1
%9 = getelementptr inbounds i32, i32* %7, i64 1
%10 = load i32, i32* %7
%11 = shl i32 %10, 24
%12 = xor i32 %11, %5
%13 = shl i32 %12, 4
%14 = ashr i32 %12, 28
%15 = sext i32 %14 to i64
%16 = getelementptr inbounds [16 x i32], [16 x i32]* @crc32.table, i64 0, i64 %15
%17 = load i32, i32* %16
%18 = xor i32 %13, %17
%19 = shl i32 %18, 4
%20 = ashr i32 %18, 28
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds [16 x i32], [16 x i32]* @crc32.table, i64 0, i64 %21
%23 = load i32, i32* %22
%24 = xor i32 %19, %23
%25 = icmp eq i32 %8, 0
br i1 %25, label %26, label %4
26: ; preds = %4, %2
%27 = phi i32 [ 0, %2 ], [ %24, %4 ]
ret i32 %27
}