int hashString(char *str) {
  static const long long precalculated_table[31] = {
      0,  4,  2,  16, 4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
      16, 19, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
  long long i, ret = 50, sub = 0;
  for (i = 0; str[i] != 0; i++) {
    ret = (190000000000LL + ((ret * 23) ^ ((str[i] - 'A') << i * i))) % 19;
    sub = (290000000000LL + sub * 23 + (str[i] - 'A') * i) % 29;
  }
  return (int)((200000000000LL + (sub != precalculated_table[sub]
                                      ? precalculated_table[sub]
                                      : ret)) %
               20LL);
}


x86 assembly (clang, -O0):
<hashString>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movq   $0x32,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
movq   $0x0,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
je     11c2 <hashString+0xc2>
imul   $0x17,-0x18(%rbp),%rax
mov    -0x8(%rbp),%rcx
mov    -0x10(%rbp),%rdx
movsbl (%rcx,%rdx,1),%edx
sub    $0x41,%edx
mov    -0x10(%rbp),%rcx
imul   -0x10(%rbp),%rcx
shl    %cl,%edx
mov    %edx,%ecx
movslq %ecx,%rcx
xor    %rcx,%rax
movabs $0x2c3ce1ec00,%rcx
add    %rcx,%rax
mov    $0x13,%ecx
cqto
idiv   %rcx
mov    %rdx,-0x18(%rbp)
imul   $0x17,-0x20(%rbp),%rax
movabs $0x438558d400,%rcx
add    %rcx,%rax
mov    -0x8(%rbp),%rcx
mov    -0x10(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
sub    $0x41,%ecx
movslq %ecx,%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rax
mov    $0x1d,%ecx
cqto
idiv   %rcx
mov    %rdx,-0x20(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1120 <hashString+0x20>
mov    -0x20(%rbp),%rax
mov    -0x20(%rbp),%rdx
lea    0xe2f(%rip),%rcx
cmp    (%rcx,%rdx,8),%rax
je     11f3 <hashString+0xf3>
mov    -0x20(%rbp),%rcx
lea    0xe1a(%rip),%rax
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x28(%rbp)
jmp    11fb <hashString+0xfb>
mov    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
movabs $0x2e90edd000,%rcx
add    %rcx,%rax
mov    $0x14,%ecx
cqto
idiv   %rcx
mov    %edx,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<hashString>:
push   %r15
push   %r14
push   %rbx
mov    (%rdi),%al
mov    $0x32,%r8d
xor    %esi,%esi
test   %al,%al
je     11dd <hashString+0xdd>
movabs $0x2c3ce1ec00,%r9
movabs $0xd79435e50d79436,%r10
43 79 0d
movabs $0x438558d400,%r11
movabs $0x469ee58469ee5847,%r14
e5 9e 46
xor    %r15d,%r15d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsbl %al,%edx
lea    (%r8,%r8,2),%rax
add    $0xffffffbf,%edx
mov    %r15d,%ecx
imul   %r15d,%ecx
lea    (%rsi,%rsi,2),%rbx
shl    $0x3,%rbx
sub    %rsi,%rbx
movslq %edx,%rsi
shl    %cl,%edx
shl    $0x3,%rax
sub    %r8,%rax
movslq %edx,%r8
xor    %rax,%r8
add    %r9,%r8
mov    %r8,%rax
imul   %r10
mov    %rdx,%rax
shr    $0x3f,%rax
add    %rdx,%rax
lea    (%rax,%rax,8),%rcx
lea    (%rax,%rcx,2),%rcx
imul   %r15,%rsi
add    %rbx,%rsi
add    %r11,%rsi
mov    %rsi,%rax
imul   %r14
sub    %rcx,%r8
mov    %rdx,%rax
shr    $0x3f,%rax
sar    $0x3,%rdx
add    %rax,%rdx
lea    (%rdx,%rdx,8),%rax
lea    (%rax,%rax,2),%rax
add    %rdx,%rax
add    %rdx,%rax
sub    %rax,%rsi
movzbl 0x1(%rdi,%r15,1),%eax
add    $0x1,%r15
test   %al,%al
jne    1150 <hashString+0x50>
lea    0xe1c(%rip),%rax
mov    (%rax,%rsi,8),%rax
cmp    %rax,%rsi
cmovne %rax,%r8
movabs $0x2e90edd000,%rcx
add    %r8,%rcx
movabs $0x6666666666666667,%rdx
66 66 66
mov    %rcx,%rax
imul   %rdx
mov    %rdx,%rax
shr    $0x3f,%rax
shr    $0x3,%rdx
add    %eax,%edx
shl    $0x2,%edx
lea    (%rdx,%rdx,4),%eax
sub    %eax,%ecx
mov    %ecx,%eax
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@hashString.precalculated_table = internal constant [31 x i64] [i64 0, i64 4, i64 2, i64 16, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15, i64 16, i64 19, i64 18, i64 19, i64 20, i64 21, i64 22, i64 23, i64 24, i64 25, i64 26, i64 27, i64 28, i64 29, i64 30]
define i32 @hashString(i8* %0) {
%2 = alloca i8*
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
store i8* %0, i8** %2
store i64 50, i64* %4
store i64 0, i64* %5
store i64 0, i64* %3
br label %6
6: ; preds = %45, %1
%7 = load i8*, i8** %2
%8 = load i64, i64* %3
%9 = getelementptr inbounds i8, i8* %7, i64 %8
%10 = load i8, i8* %9
%11 = sext i8 %10 to i32
%12 = icmp ne i32 %11, 0
br i1 %12, label %13, label %48
13: ; preds = %6
%14 = load i64, i64* %4
%15 = mul nsw i64 %14, 23
%16 = load i8*, i8** %2
%17 = load i64, i64* %3
%18 = getelementptr inbounds i8, i8* %16, i64 %17
%19 = load i8, i8* %18
%20 = sext i8 %19 to i32
%21 = sub nsw i32 %20, 65
%22 = load i64, i64* %3
%23 = load i64, i64* %3
%24 = mul nsw i64 %22, %23
%25 = trunc i64 %24 to i32
%26 = shl i32 %21, %25
%27 = sext i32 %26 to i64
%28 = xor i64 %15, %27
%29 = add nsw i64 190000000000, %28
%30 = srem i64 %29, 19
store i64 %30, i64* %4
%31 = load i64, i64* %5
%32 = mul nsw i64 %31, 23
%33 = add nsw i64 290000000000, %32
%34 = load i8*, i8** %2
%35 = load i64, i64* %3
%36 = getelementptr inbounds i8, i8* %34, i64 %35
%37 = load i8, i8* %36
%38 = sext i8 %37 to i32
%39 = sub nsw i32 %38, 65
%40 = sext i32 %39 to i64
%41 = load i64, i64* %3
%42 = mul nsw i64 %40, %41
%43 = add nsw i64 %33, %42
%44 = srem i64 %43, 29
store i64 %44, i64* %5
br label %45
45: ; preds = %13
%46 = load i64, i64* %3
%47 = add nsw i64 %46, 1
store i64 %47, i64* %3
br label %6
48: ; preds = %6
%49 = load i64, i64* %5
%50 = load i64, i64* %5
%51 = getelementptr inbounds [31 x i64], [31 x i64]* @hashString.precalculated_table, i64 0, i64 %50
%52 = load i64, i64* %51
%53 = icmp ne i64 %49, %52
br i1 %53, label %54, label %58
54: ; preds = %48
%55 = load i64, i64* %5
%56 = getelementptr inbounds [31 x i64], [31 x i64]* @hashString.precalculated_table, i64 0, i64 %55
%57 = load i64, i64* %56
br label %60
58: ; preds = %48
%59 = load i64, i64* %4
br label %60
60: ; preds = %58, %54
%61 = phi i64 [ %57, %54 ], [ %59, %58 ]
%62 = add nsw i64 200000000000, %61
%63 = srem i64 %62, 20
%64 = trunc i64 %63 to i32
ret i32 %64
}

LLVM IR (-O2):
@hashString.precalculated_table = internal unnamed_addr constant [31 x i64] [i64 0, i64 4, i64 2, i64 16, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15, i64 16, i64 19, i64 18, i64 19, i64 20, i64 21, i64 22, i64 23, i64 24, i64 25, i64 26, i64 27, i64 28, i64 29, i64 30]
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 i64 [ %24, %4 ], [ 0, %1 ]
%7 = phi i64 [ %18, %4 ], [ 50, %1 ]
%8 = phi i64 [ %25, %4 ], [ 0, %1 ]
%9 = sext i8 %5 to i32
%10 = mul nsw i64 %7, 23
%11 = add nsw i32 %9, -65
%12 = mul nsw i64 %8, %8
%13 = trunc i64 %12 to i32
%14 = shl i32 %11, %13
%15 = sext i32 %14 to i64
%16 = xor i64 %10, %15
%17 = add nsw i64 %16, 190000000000
%18 = srem i64 %17, 19
%19 = mul nsw i64 %6, 23
%20 = add nsw i64 %19, 290000000000
%21 = sext i32 %11 to i64
%22 = mul nsw i64 %8, %21
%23 = add nsw i64 %20, %22
%24 = srem i64 %23, 29
%25 = add nuw nsw i64 %8, 1
%26 = getelementptr inbounds i8, i8* %0, i64 %25
%27 = load i8, i8* %26
%28 = icmp eq i8 %27, 0
br i1 %28, label %29, label %4
29: ; preds = %4, %1
%30 = phi i64 [ 50, %1 ], [ %18, %4 ]
%31 = phi i64 [ 0, %1 ], [ %24, %4 ]
%32 = getelementptr inbounds [31 x i64], [31 x i64]* @hashString.precalculated_table, i64 0, i64 %31
%33 = load i64, i64* %32
%34 = icmp eq i64 %31, %33
%35 = select i1 %34, i64 %30, i64 %33
%36 = add nsw i64 %35, 200000000000
%37 = srem i64 %36, 20
%38 = trunc i64 %37 to i32
ret i32 %38
}