#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 */
size_t Hash(const void *key, size_t len, unsigned int seed) {
  const unsigned int m = 0x5bd1e995;
  const int r = 24;
  size_t h = seed ^ len;
  const unsigned char *data = key;
  while (len >= 4) {
    unsigned int k = *(unsigned int *)data;
    k *= m;
    k ^= k >> r;
    k *= m;
    h *= m;
    h ^= k;
    data += 4;
    len -= 4;
  }
  switch (len) {
  case 3:
    h ^= data[2] << 16;
  case 2:
    h ^= data[1] << 8;
  case 1:
    h ^= data[0];
    h *= m;
  };
  h ^= h >> 13;
  h *= m;
  h ^= h >> 15;
  return h;
}


x86 assembly (clang, -O0):
<Hash>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x5bd1e995,-0x18(%rbp)
movl   $0x18,-0x1c(%rbp)
mov    -0x14(%rbp),%eax
xor    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x30(%rbp)
cmpq   $0x4,-0x10(%rbp)
jb     1198 <Hash+0x98>
mov    -0x30(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x34(%rbp)
imul   $0x5bd1e995,-0x34(%rbp),%eax
mov    %eax,-0x34(%rbp)
mov    -0x34(%rbp),%eax
shr    $0x18,%eax
xor    -0x34(%rbp),%eax
mov    %eax,-0x34(%rbp)
imul   $0x5bd1e995,-0x34(%rbp),%eax
mov    %eax,-0x34(%rbp)
imul   $0x5bd1e995,-0x28(%rbp),%rax
5b
mov    %rax,-0x28(%rbp)
mov    -0x34(%rbp),%eax
xor    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
sub    $0x4,%rax
mov    %rax,-0x10(%rbp)
jmp    1130 <Hash+0x30>
mov    -0x10(%rbp),%rax
mov    %rax,-0x40(%rbp)
sub    $0x1,%rax
je     11ff <Hash+0xff>
jmp    11af <Hash+0xaf>
mov    -0x40(%rbp),%rax
sub    $0x2,%rax
je     11ea <Hash+0xea>
jmp    11c2 <Hash+0xc2>
mov    -0x40(%rbp),%rax
sub    $0x3,%rax
jne    121a <Hash+0x11a>
jmp    11d5 <Hash+0xd5>
mov    -0x30(%rbp),%rax
movzbl 0x2(%rax),%eax
shl    $0x10,%eax
cltq
xor    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
movzbl 0x1(%rax),%eax
shl    $0x8,%eax
cltq
xor    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
movzbl (%rax),%eax
xor    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
imul   $0x5bd1e995,-0x28(%rbp),%rax
5b
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
shr    $0xd,%rax
xor    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
imul   $0x5bd1e995,-0x28(%rbp),%rax
5b
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
shr    $0xf,%rax
xor    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<Hash>:
mov    %edx,%ecx
xor    %rsi,%rcx
cmp    $0x4,%rsi
jb     1199 <Hash+0x99>
lea    -0x4(%rsi),%rdx
test   $0x4,%dl
jne    1147 <Hash+0x47>
imul   $0x5bd1e995,(%rdi),%eax
mov    %eax,%esi
shr    $0x18,%esi
xor    %eax,%esi
imul   $0x5bd1e995,%esi,%eax
imul   $0x5bd1e995,%rcx,%rcx
xor    %rcx,%rax
add    $0x4,%rdi
mov    %rdx,%rsi
mov    %rax,%rcx
cmp    $0x4,%rdx
jae    1150 <Hash+0x50>
jmp    119f <Hash+0x9f>
cmp    $0x4,%rdx
jb     119f <Hash+0x9f>
nopl   (%rax)
imul   $0x5bd1e995,(%rdi),%eax
mov    %eax,%edx
shr    $0x18,%edx
xor    %eax,%edx
imul   $0x5bd1e995,%edx,%eax
imul   $0x5bd1e995,%rcx,%rcx
xor    %rcx,%rax
imul   $0x5bd1e995,0x4(%rdi),%ecx
mov    %ecx,%edx
shr    $0x18,%edx
xor    %ecx,%edx
imul   $0x5bd1e995,%edx,%ecx
imul   $0x5bd1e995,%rax,%rax
xor    %rax,%rcx
add    $0x8,%rdi
add    $0xfffffffffffffff8,%rsi
cmp    $0x3,%rsi
ja     1150 <Hash+0x50>
mov    %rcx,%rax
mov    %rsi,%rdx
cmp    $0x1,%rdx
je     11c7 <Hash+0xc7>
cmp    $0x2,%rdx
je     11bc <Hash+0xbc>
cmp    $0x3,%rdx
jne    11d4 <Hash+0xd4>
movzbl 0x2(%rdi),%ecx
shl    $0x10,%rcx
xor    %rcx,%rax
movzbl 0x1(%rdi),%ecx
shl    $0x8,%rcx
xor    %rcx,%rax
movzbl (%rdi),%ecx
xor    %rax,%rcx
imul   $0x5bd1e995,%rcx,%rax
mov    %rax,%rcx
shr    $0xd,%rcx
xor    %rax,%rcx
imul   $0x5bd1e995,%rcx,%rcx
mov    %rcx,%rax
shr    $0xf,%rax
xor    %rcx,%rax
ret

LLVM IR (-O0):
define i64 @Hash(i8* %0, i64 %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i64
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i64
%10 = alloca i8*
%11 = alloca i32
store i8* %0, i8** %4
store i64 %1, i64* %5
store i32 %2, i32* %6
store i32 1540483477, i32* %7
store i32 24, i32* %8
%12 = load i32, i32* %6
%13 = zext i32 %12 to i64
%14 = load i64, i64* %5
%15 = xor i64 %13, %14
store i64 %15, i64* %9
%16 = load i8*, i8** %4
store i8* %16, i8** %10
br label %17
17: ; preds = %20, %3
%18 = load i64, i64* %5
%19 = icmp uge i64 %18, 4
br i1 %19, label %20, label %42
20: ; preds = %17
%21 = load i8*, i8** %10
%22 = bitcast i8* %21 to i32*
%23 = load i32, i32* %22
store i32 %23, i32* %11
%24 = load i32, i32* %11
%25 = mul i32 %24, 1540483477
store i32 %25, i32* %11
%26 = load i32, i32* %11
%27 = lshr i32 %26, 24
%28 = load i32, i32* %11
%29 = xor i32 %28, %27
store i32 %29, i32* %11
%30 = load i32, i32* %11
%31 = mul i32 %30, 1540483477
store i32 %31, i32* %11
%32 = load i64, i64* %9
%33 = mul i64 %32, 1540483477
store i64 %33, i64* %9
%34 = load i32, i32* %11
%35 = zext i32 %34 to i64
%36 = load i64, i64* %9
%37 = xor i64 %36, %35
store i64 %37, i64* %9
%38 = load i8*, i8** %10
%39 = getelementptr inbounds i8, i8* %38, i64 4
store i8* %39, i8** %10
%40 = load i64, i64* %5
%41 = sub i64 %40, 4
store i64 %41, i64* %5
br label %17
42: ; preds = %17
%43 = load i64, i64* %5
switch i64 %43, label %71 [
i64 3, label %44
i64 2, label %53
i64 1, label %62
]
44: ; preds = %42
%45 = load i8*, i8** %10
%46 = getelementptr inbounds i8, i8* %45, i64 2
%47 = load i8, i8* %46
%48 = zext i8 %47 to i32
%49 = shl i32 %48, 16
%50 = sext i32 %49 to i64
%51 = load i64, i64* %9
%52 = xor i64 %51, %50
store i64 %52, i64* %9
br label %53
53: ; preds = %42, %44
%54 = load i8*, i8** %10
%55 = getelementptr inbounds i8, i8* %54, i64 1
%56 = load i8, i8* %55
%57 = zext i8 %56 to i32
%58 = shl i32 %57, 8
%59 = sext i32 %58 to i64
%60 = load i64, i64* %9
%61 = xor i64 %60, %59
store i64 %61, i64* %9
br label %62
62: ; preds = %42, %53
%63 = load i8*, i8** %10
%64 = getelementptr inbounds i8, i8* %63, i64 0
%65 = load i8, i8* %64
%66 = zext i8 %65 to i64
%67 = load i64, i64* %9
%68 = xor i64 %67, %66
store i64 %68, i64* %9
%69 = load i64, i64* %9
%70 = mul i64 %69, 1540483477
store i64 %70, i64* %9
br label %71
71: ; preds = %62, %42
%72 = load i64, i64* %9
%73 = lshr i64 %72, 13
%74 = load i64, i64* %9
%75 = xor i64 %74, %73
store i64 %75, i64* %9
%76 = load i64, i64* %9
%77 = mul i64 %76, 1540483477
store i64 %77, i64* %9
%78 = load i64, i64* %9
%79 = lshr i64 %78, 15
%80 = load i64, i64* %9
%81 = xor i64 %80, %79
store i64 %81, i64* %9
%82 = load i64, i64* %9
ret i64 %82
}

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