unsigned int tag_hash(register const char *str, register unsigned int len) {
  static unsigned short asso_values[] = {
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 6,   4,   3,   1,   1,   0,   1,   0,   0,   296, 296,
      296, 296, 296, 296, 296, 22,  73,  151, 4,   13,  59,  65,  2,   69,  0,
      134, 9,   16,  52,  55,  28,  101, 0,   1,   6,   63,  126, 104, 93,  124,
      296, 296, 296, 296, 296, 296, 296, 22,  73,  151, 4,   13,  59,  65,  2,
      69,  0,   134, 9,   16,  52,  55,  28,  101, 0,   1,   6,   63,  126, 104,
      93,  124, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
      296, 296, 296, 296};
  unsigned int hval = len;
  switch (hval) {
  default:
    hval += asso_values[(unsigned char)str[1] + 3];
  case 1:
    hval += asso_values[(unsigned char)str[0]];
    break;
  }
  return hval + asso_values[(unsigned char)str[len - 1]];
}


x86 assembly (clang, -O0):
<tag_hash>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
sub    $0x1,%eax
je     1141 <tag_hash+0x41>
jmp    1122 <tag_hash+0x22>
mov    -0x8(%rbp),%rax
movzbl 0x1(%rax),%eax
add    $0x3,%eax
movslq %eax,%rcx
lea    0x2ef9(%rip),%rax
movzwl (%rax,%rcx,2),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
mov    %eax,%ecx
lea    0x2edf(%rip),%rax
movzwl (%rax,%rcx,2),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
mov    -0x8(%rbp),%rcx
mov    -0xc(%rbp),%edx
sub    $0x1,%edx
mov    %edx,%edx
movzbl (%rcx,%rdx,1),%ecx
mov    %ecx,%edx
lea    0x2eb9(%rip),%rcx
movzwl (%rcx,%rdx,2),%ecx
add    %ecx,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<tag_hash>:
mov    $0x1,%eax
cmp    $0x1,%esi
je     111c <tag_hash+0x1c>
movzbl 0x1(%rdi),%eax
lea    0xeeb(%rip),%rcx
movzwl 0x6(%rcx,%rax,2),%eax
add    %esi,%eax
movzbl (%rdi),%ecx
lea    0xeda(%rip),%rdx
movzwl (%rdx,%rcx,2),%ecx
add    %eax,%ecx
add    $0xffffffff,%esi
movzbl (%rdi,%rsi,1),%eax
movzwl (%rdx,%rax,2),%eax
add    %ecx,%eax
ret

LLVM IR (-O0):
@tag_hash.asso_values = internal global [259 x i16] [i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 6, i16 4, i16 3, i16 1, i16 1, i16 0, i16 1, i16 0, i16 0, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 22, i16 73, i16 151, i16 4, i16 13, i16 59, i16 65, i16 2, i16 69, i16 0, i16 134, i16 9, i16 16, i16 52, i16 55, i16 28, i16 101, i16 0, i16 1, i16 6, i16 63, i16 126, i16 104, i16 93, i16 124, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 22, i16 73, i16 151, i16 4, i16 13, i16 59, i16 65, i16 2, i16 69, i16 0, i16 134, i16 9, i16 16, i16 52, i16 55, i16 28, i16 101, i16 0, i16 1, i16 6, i16 63, i16 126, i16 104, i16 93, i16 124, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296]
define i32 @tag_hash(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 i32, i32* %4
store i32 %6, i32* %5
%7 = load i32, i32* %5
switch i32 %7, label %8 [
i32 1, label %20
]
8: ; preds = %2
%9 = load i8*, i8** %3
%10 = getelementptr inbounds i8, i8* %9, i64 1
%11 = load i8, i8* %10
%12 = zext i8 %11 to i32
%13 = add nsw i32 %12, 3
%14 = sext i32 %13 to i64
%15 = getelementptr inbounds [259 x i16], [259 x i16]* @tag_hash.asso_values, i64 0, i64 %14
%16 = load i16, i16* %15
%17 = zext i16 %16 to i32
%18 = load i32, i32* %5
%19 = add i32 %18, %17
store i32 %19, i32* %5
br label %20
20: ; preds = %2, %8
%21 = load i8*, i8** %3
%22 = getelementptr inbounds i8, i8* %21, i64 0
%23 = load i8, i8* %22
%24 = zext i8 %23 to i64
%25 = getelementptr inbounds [259 x i16], [259 x i16]* @tag_hash.asso_values, i64 0, i64 %24
%26 = load i16, i16* %25
%27 = zext i16 %26 to i32
%28 = load i32, i32* %5
%29 = add i32 %28, %27
store i32 %29, i32* %5
br label %30
30: ; preds = %20
%31 = load i32, i32* %5
%32 = load i8*, i8** %3
%33 = load i32, i32* %4
%34 = sub i32 %33, 1
%35 = zext i32 %34 to i64
%36 = getelementptr inbounds i8, i8* %32, i64 %35
%37 = load i8, i8* %36
%38 = zext i8 %37 to i64
%39 = getelementptr inbounds [259 x i16], [259 x i16]* @tag_hash.asso_values, i64 0, i64 %38
%40 = load i16, i16* %39
%41 = zext i16 %40 to i32
%42 = add i32 %31, %41
ret i32 %42
}

LLVM IR (-O2):
@tag_hash.asso_values = internal unnamed_addr constant [259 x i16] [i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 6, i16 4, i16 3, i16 1, i16 1, i16 0, i16 1, i16 0, i16 0, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 22, i16 73, i16 151, i16 4, i16 13, i16 59, i16 65, i16 2, i16 69, i16 0, i16 134, i16 9, i16 16, i16 52, i16 55, i16 28, i16 101, i16 0, i16 1, i16 6, i16 63, i16 126, i16 104, i16 93, i16 124, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 22, i16 73, i16 151, i16 4, i16 13, i16 59, i16 65, i16 2, i16 69, i16 0, i16 134, i16 9, i16 16, i16 52, i16 55, i16 28, i16 101, i16 0, i16 1, i16 6, i16 63, i16 126, i16 104, i16 93, i16 124, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296, i16 296]
define i32 @tag_hash(i8* nocapture %0, i32 %1) {
%3 = icmp eq i32 %1, 1
br i1 %3, label %13, label %4
4: ; preds = %2
%5 = getelementptr inbounds i8, i8* %0, i64 1
%6 = load i8, i8* %5
%7 = zext i8 %6 to i64
%8 = add nuw nsw i64 %7, 3
%9 = getelementptr inbounds [259 x i16], [259 x i16]* @tag_hash.asso_values, i64 0, i64 %8
%10 = load i16, i16* %9
%11 = zext i16 %10 to i32
%12 = add i32 %11, %1
br label %13
13: ; preds = %2, %4
%14 = phi i32 [ 1, %2 ], [ %12, %4 ]
%15 = load i8, i8* %0
%16 = zext i8 %15 to i64
%17 = getelementptr inbounds [259 x i16], [259 x i16]* @tag_hash.asso_values, i64 0, i64 %16
%18 = load i16, i16* %17
%19 = zext i16 %18 to i32
%20 = add i32 %14, %19
%21 = add i32 %1, -1
%22 = zext i32 %21 to i64
%23 = getelementptr inbounds i8, i8* %0, i64 %22
%24 = load i8, i8* %23
%25 = zext i8 %24 to i64
%26 = getelementptr inbounds [259 x i16], [259 x i16]* @tag_hash.asso_values, i64 0, i64 %25
%27 = load i16, i16* %26
%28 = zext i16 %27 to i32
%29 = add i32 %20, %28
ret i32 %29
}