#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 int abs(unsigned int);
unsigned int HashString(const char *key) {
  static unsigned long randbox[] = {
      0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
      0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU,
      0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU,
      0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
  };
  const char *str = key;
  unsigned int acc = 0;
  while (*str) {
    acc ^= randbox[(*str + acc) & 0xf];
    acc = (acc << 1) | (acc >> 31);
    acc &= 0xffffffffU;
    acc ^= randbox[((*str++ >> 4) + acc) & 0xf];
    acc = (acc << 2) | (acc >> 30);
    acc &= 0xffffffffU;
  }
  return abs(acc);
}


x86 assembly (clang, -O0):
<HashString>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
je     11c9 <HashString+0xb9>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
add    -0x14(%rbp),%eax
and    $0xf,%eax
mov    %eax,%eax
mov    %eax,%ecx
lea    0x2ee0(%rip),%rax
mov    (%rax,%rcx,8),%rcx
mov    -0x14(%rbp),%eax
xor    %rcx,%rax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
shl    $0x1,%eax
mov    -0x14(%rbp),%ecx
shr    $0x1f,%ecx
or     %ecx,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
and    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movsbl (%rax),%eax
sar    $0x4,%eax
add    -0x14(%rbp),%eax
and    $0xf,%eax
mov    %eax,%eax
mov    %eax,%ecx
lea    0x2e93(%rip),%rax
mov    (%rax,%rcx,8),%rcx
mov    -0x14(%rbp),%eax
xor    %rcx,%rax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
shl    $0x2,%eax
mov    -0x14(%rbp),%ecx
shr    $0x1e,%ecx
or     %ecx,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
and    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    112b <HashString+0x1b>
mov    -0x14(%rbp),%edi
call   1030 <abs@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<HashString>:
mov    (%rdi),%dl
test   %dl,%dl
je     1149 <HashString+0x49>
add    $0x1,%rdi
xor    %ecx,%ecx
lea    0xeed(%rip),%rax
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movzbl %dl,%edx
lea    (%rcx,%rdx,1),%esi
and    $0xf,%esi
xor    (%rax,%rsi,8),%ecx
rol    %ecx
shr    $0x4,%edx
add    %ecx,%edx
and    $0xf,%edx
xor    (%rax,%rdx,8),%ecx
rol    $0x2,%ecx
movzbl (%rdi),%edx
add    $0x1,%rdi
test   %dl,%dl
jne    1120 <HashString+0x20>
jmp    114b <HashString+0x4b>
xor    %ecx,%ecx
mov    %ecx,%eax
neg    %eax
cmovs  %ecx,%eax
ret

LLVM IR (-O0):
@HashString.randbox = internal global [16 x i64] [i64 1233424155, i64 3861208506, i64 920280028, i64 1203737833, i64 2361183778, i64 1436532842, i64 3530093878, i64 3775592346, i64 3249491305, i64 489232309, i64 3964416077, i64 2665808236, i64 1763913588, i64 4272782259, i64 3909655222, i64 4027774638]
define i32 @HashString(i8* %0) {
%2 = alloca i8*
%3 = alloca i8*
%4 = alloca i32
store i8* %0, i8** %2
%5 = load i8*, i8** %2
store i8* %5, i8** %3
store i32 0, i32* %4
br label %6
6: ; preds = %10, %1
%7 = load i8*, i8** %3
%8 = load i8, i8* %7
%9 = icmp ne i8 %8, 0
br i1 %9, label %10, label %53
10: ; preds = %6
%11 = load i8*, i8** %3
%12 = load i8, i8* %11
%13 = sext i8 %12 to i32
%14 = load i32, i32* %4
%15 = add i32 %13, %14
%16 = and i32 %15, 15
%17 = zext i32 %16 to i64
%18 = getelementptr inbounds [16 x i64], [16 x i64]* @HashString.randbox, i64 0, i64 %17
%19 = load i64, i64* %18
%20 = load i32, i32* %4
%21 = zext i32 %20 to i64
%22 = xor i64 %21, %19
%23 = trunc i64 %22 to i32
store i32 %23, i32* %4
%24 = load i32, i32* %4
%25 = shl i32 %24, 1
%26 = load i32, i32* %4
%27 = lshr i32 %26, 31
%28 = or i32 %25, %27
store i32 %28, i32* %4
%29 = load i32, i32* %4
%30 = and i32 %29, -1
store i32 %30, i32* %4
%31 = load i8*, i8** %3
%32 = getelementptr inbounds i8, i8* %31, i32 1
store i8* %32, i8** %3
%33 = load i8, i8* %31
%34 = sext i8 %33 to i32
%35 = ashr i32 %34, 4
%36 = load i32, i32* %4
%37 = add i32 %35, %36
%38 = and i32 %37, 15
%39 = zext i32 %38 to i64
%40 = getelementptr inbounds [16 x i64], [16 x i64]* @HashString.randbox, i64 0, i64 %39
%41 = load i64, i64* %40
%42 = load i32, i32* %4
%43 = zext i32 %42 to i64
%44 = xor i64 %43, %41
%45 = trunc i64 %44 to i32
store i32 %45, i32* %4
%46 = load i32, i32* %4
%47 = shl i32 %46, 2
%48 = load i32, i32* %4
%49 = lshr i32 %48, 30
%50 = or i32 %47, %49
store i32 %50, i32* %4
%51 = load i32, i32* %4
%52 = and i32 %51, -1
store i32 %52, i32* %4
br label %6
53: ; preds = %6
%54 = load i32, i32* %4
%55 = call i32 @abs(i32 %54)
ret i32 %55
}

LLVM IR (-O2):
@HashString.randbox = internal unnamed_addr constant [16 x i64] [i64 1233424155, i64 3861208506, i64 920280028, i64 1203737833, i64 2361183778, i64 1436532842, i64 3530093878, i64 3775592346, i64 3249491305, i64 489232309, i64 3964416077, i64 2665808236, i64 1763913588, i64 4272782259, i64 3909655222, i64 4027774638]
define i32 @HashString(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = icmp eq i8 %2, 0
br i1 %3, label %29, label %4
4: ; preds = %1, %4
%5 = phi i8 [ %27, %4 ], [ %2, %1 ]
%6 = phi i32 [ %26, %4 ], [ 0, %1 ]
%7 = phi i8* [ %17, %4 ], [ %0, %1 ]
%8 = zext i8 %5 to i32
%9 = add i32 %6, %8
%10 = and i32 %9, 15
%11 = zext i32 %10 to i64
%12 = getelementptr inbounds [16 x i64], [16 x i64]* @HashString.randbox, i64 0, i64 %11
%13 = load i64, i64* %12
%14 = trunc i64 %13 to i32
%15 = xor i32 %6, %14
%16 = tail call i32 @llvm.fshl.i32(i32 %15, i32 %15, i32 1)
%17 = getelementptr inbounds i8, i8* %7, i64 1
%18 = lshr i32 %8, 4
%19 = add i32 %16, %18
%20 = and i32 %19, 15
%21 = zext i32 %20 to i64
%22 = getelementptr inbounds [16 x i64], [16 x i64]* @HashString.randbox, i64 0, i64 %21
%23 = load i64, i64* %22
%24 = trunc i64 %23 to i32
%25 = xor i32 %16, %24
%26 = tail call i32 @llvm.fshl.i32(i32 %25, i32 %25, i32 2)
%27 = load i8, i8* %17
%28 = icmp eq i8 %27, 0
br i1 %28, label %29, label %4
29: ; preds = %4, %1
%30 = phi i32 [ 0, %1 ], [ %26, %4 ]
%31 = tail call i32 @llvm.abs.i32(i32 %30, i1 true)
ret i32 %31
}