int create_sign_bitwise_len(char *str, unsigned int *sign1, unsigned int *sign2,
                            unsigned int slen) {
  unsigned int h1 = 1159241;
  unsigned int h2 = 2000011;
  while (slen) {
    h1 ^= (h1 << 5) + (h1 >> 2) + *str;
    h2 ^= (h2 << 5) + (h2 >> 2) + *str++;
    slen--;
  }
  *sign1 = h1 & 0x7fffffff;
  *sign2 = h2 & 0x7fffffff;
  return 0;
}


x86 assembly (clang, -O0):
<create_sign_bitwise_len>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
movl   $0x11b049,-0x20(%rbp)
movl   $0x1e848b,-0x24(%rbp)
cmpl   $0x0,-0x1c(%rbp)
je     117e <create_sign_bitwise_len+0x7e>
mov    -0x20(%rbp),%eax
shl    $0x5,%eax
mov    -0x20(%rbp),%ecx
shr    $0x2,%ecx
add    %ecx,%eax
mov    -0x8(%rbp),%rcx
movsbl (%rcx),%ecx
add    %ecx,%eax
xor    -0x20(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x24(%rbp),%eax
shl    $0x5,%eax
mov    -0x24(%rbp),%ecx
shr    $0x2,%ecx
add    %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
movsbl (%rcx),%ecx
add    %ecx,%eax
xor    -0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    1121 <create_sign_bitwise_len+0x21>
mov    -0x20(%rbp),%ecx
and    $0x7fffffff,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x24(%rbp),%ecx
and    $0x7fffffff,%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
xor    %eax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<create_sign_bitwise_len>:
test   %ecx,%ecx
je     111d <create_sign_bitwise_len+0x1d>
test   $0x1,%cl
jne    112a <create_sign_bitwise_len+0x2a>
movdqa 0xeef(%rip),%xmm0
mov    %ecx,%eax
cmp    $0x1,%ecx
jne    1152 <create_sign_bitwise_len+0x52>
jmp    11c0 <create_sign_bitwise_len+0xc0>
movdqa 0xedb(%rip),%xmm0
jmp    11c8 <create_sign_bitwise_len+0xc8>
movsbl (%rdi),%eax
movd   %eax,%xmm0
pshufd $0x50,%xmm0,%xmm0
paddd  0xed2(%rip),%xmm0
add    $0x1,%rdi
pxor   0xeb6(%rip),%xmm0
lea    -0x1(%rcx),%eax
cmp    $0x1,%ecx
je     11c0 <create_sign_bitwise_len+0xc0>
mov    %eax,%r8d
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
movsbl (%rdi,%rcx,1),%eax
movdqa %xmm0,%xmm1
pslld  $0x5,%xmm1
movdqa %xmm0,%xmm2
psrld  $0x2,%xmm2
paddd  %xmm1,%xmm2
movd   %eax,%xmm1
pshufd $0x50,%xmm1,%xmm1
paddd  %xmm2,%xmm1
pxor   %xmm0,%xmm1
movsbl 0x1(%rdi,%rcx,1),%eax
movdqa %xmm1,%xmm0
pslld  $0x5,%xmm0
movdqa %xmm1,%xmm2
psrld  $0x2,%xmm2
paddd  %xmm0,%xmm2
movd   %eax,%xmm0
pshufd $0x50,%xmm0,%xmm0
paddd  %xmm2,%xmm0
pxor   %xmm1,%xmm0
add    $0x2,%rcx
cmp    %ecx,%r8d
jne    1160 <create_sign_bitwise_len+0x60>
pand   0xe58(%rip),%xmm0
movd   %xmm0,(%rsi)
pshufd $0x55,%xmm0,%xmm0
movd   %xmm0,(%rdx)
xor    %eax,%eax
ret

LLVM IR (-O0):
define i32 @create_sign_bitwise_len(i8* %0, i32* %1, i32* %2, i32 %3) {
%5 = alloca i8*
%6 = alloca i32*
%7 = alloca i32*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
store i8* %0, i8** %5
store i32* %1, i32** %6
store i32* %2, i32** %7
store i32 %3, i32* %8
store i32 1159241, i32* %9
store i32 2000011, i32* %10
br label %11
11: ; preds = %14, %4
%12 = load i32, i32* %8
%13 = icmp ne i32 %12, 0
br i1 %13, label %14, label %40
14: ; preds = %11
%15 = load i32, i32* %9
%16 = shl i32 %15, 5
%17 = load i32, i32* %9
%18 = lshr i32 %17, 2
%19 = add i32 %16, %18
%20 = load i8*, i8** %5
%21 = load i8, i8* %20
%22 = sext i8 %21 to i32
%23 = add i32 %19, %22
%24 = load i32, i32* %9
%25 = xor i32 %24, %23
store i32 %25, i32* %9
%26 = load i32, i32* %10
%27 = shl i32 %26, 5
%28 = load i32, i32* %10
%29 = lshr i32 %28, 2
%30 = add i32 %27, %29
%31 = load i8*, i8** %5
%32 = getelementptr inbounds i8, i8* %31, i32 1
store i8* %32, i8** %5
%33 = load i8, i8* %31
%34 = sext i8 %33 to i32
%35 = add i32 %30, %34
%36 = load i32, i32* %10
%37 = xor i32 %36, %35
store i32 %37, i32* %10
%38 = load i32, i32* %8
%39 = add i32 %38, -1
store i32 %39, i32* %8
br label %11
40: ; preds = %11
%41 = load i32, i32* %9
%42 = and i32 %41, 2147483647
%43 = load i32*, i32** %6
store i32 %42, i32* %43
%44 = load i32, i32* %10
%45 = and i32 %44, 2147483647
%46 = load i32*, i32** %7
store i32 %45, i32* %46
ret i32 0
}

LLVM IR (-O2):
define i32 @create_sign_bitwise_len(i8* nocapture %0, i32* nocapture writeonly %1, i32* nocapture writeonly %2, i32 %3) {
%5 = icmp eq i32 %3, 0
br i1 %5, label %53, label %6
6: ; preds = %4
%7 = and i32 %3, 1
%8 = icmp eq i32 %7, 0
br i1 %8, label %18, label %9
9: ; preds = %6
%10 = load i8, i8* %0
%11 = sext i8 %10 to i32
%12 = getelementptr inbounds i8, i8* %0, i64 1
%13 = insertelement <2 x i32> poison, i32 %11, i64 0
%14 = shufflevector <2 x i32> %13, <2 x i32> poison, <2 x i32> zeroinitializer
%15 = add <2 x i32> %14, <i32 37385522, i32 64500354>
%16 = xor <2 x i32> %15, <i32 1159241, i32 2000011>
%17 = add i32 %3, -1
br label %18
18: ; preds = %9, %6
%19 = phi <2 x i32> [ undef, %6 ], [ %16, %9 ]
%20 = phi i32 [ %3, %6 ], [ %17, %9 ]
%21 = phi i8* [ %0, %6 ], [ %12, %9 ]
%22 = phi <2 x i32> [ <i32 1159241, i32 2000011>, %6 ], [ %16, %9 ]
%23 = icmp eq i32 %3, 1
br i1 %23, label %50, label %24
24: ; preds = %18, %24
%25 = phi i32 [ %48, %24 ], [ %20, %18 ]
%26 = phi i8* [ %43, %24 ], [ %21, %18 ]
%27 = phi <2 x i32> [ %47, %24 ], [ %22, %18 ]
%28 = load i8, i8* %26
%29 = sext i8 %28 to i32
%30 = shl <2 x i32> %27, <i32 5, i32 5>
%31 = lshr <2 x i32> %27, <i32 2, i32 2>
%32 = add <2 x i32> %30, %31
%33 = getelementptr inbounds i8, i8* %26, i64 1
%34 = insertelement <2 x i32> poison, i32 %29, i64 0
%35 = shufflevector <2 x i32> %34, <2 x i32> poison, <2 x i32> zeroinitializer
%36 = add <2 x i32> %32, %35
%37 = xor <2 x i32> %36, %27
%38 = load i8, i8* %33
%39 = sext i8 %38 to i32
%40 = shl <2 x i32> %37, <i32 5, i32 5>
%41 = lshr <2 x i32> %37, <i32 2, i32 2>
%42 = add <2 x i32> %40, %41
%43 = getelementptr inbounds i8, i8* %26, i64 2
%44 = insertelement <2 x i32> poison, i32 %39, i64 0
%45 = shufflevector <2 x i32> %44, <2 x i32> poison, <2 x i32> zeroinitializer
%46 = add <2 x i32> %42, %45
%47 = xor <2 x i32> %46, %37
%48 = add i32 %25, -2
%49 = icmp eq i32 %48, 0
br i1 %49, label %50, label %24
50: ; preds = %24, %18
%51 = phi <2 x i32> [ %19, %18 ], [ %47, %24 ]
%52 = and <2 x i32> %51, <i32 2147483647, i32 2147483647>
br label %53
53: ; preds = %50, %4
%54 = phi <2 x i32> [ <i32 1159241, i32 2000011>, %4 ], [ %52, %50 ]
%55 = extractelement <2 x i32> %54, i64 0
store i32 %55, i32* %1
%56 = extractelement <2 x i32> %54, i64 1
store i32 %56, i32* %2
ret i32 0
}