int state_to_number(char *str) {
  int x = 0;
  for (int i = 0; i < 23; i++) {
    if (str[i] == 'o')
      x |= (1 << i);
  }
  return x;
}


x86 assembly (clang, -O0):
<state_to_number>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
movl   $0x0,-0x10(%rbp)
cmpl   $0x17,-0x10(%rbp)
jge    1158 <state_to_number+0x58>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x6f,%eax
jne    1145 <state_to_number+0x45>
mov    -0x10(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
or     -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
jmp    114a <state_to_number+0x4a>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    1116 <state_to_number+0x16>
mov    -0xc(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<state_to_number>:
xor    %ecx,%ecx
cmpb   $0x6f,(%rdi)
sete   %cl
xor    %edx,%edx
cmpb   $0x6f,0x1(%rdi)
sete   %dl
add    %edx,%edx
xor    %esi,%esi
cmpb   $0x6f,0x2(%rdi)
movd   0x3(%rdi),%xmm0
pcmpeqb 0xeda(%rip),%xmm0
punpcklbw %xmm0,%xmm0
punpcklwd %xmm0,%xmm0
pand   0xeda(%rip),%xmm0
sete   %sil
movdqu 0x7(%rdi),%xmm1
pcmpeqb 0xed9(%rip),%xmm1
shl    $0x2,%esi
punpcklbw %xmm1,%xmm2
punpckhwd %xmm2,%xmm3
psrad  $0x18,%xmm3
punpckhbw %xmm1,%xmm1
punpckhwd %xmm1,%xmm4
psrad  $0x18,%xmm4
punpcklwd %xmm2,%xmm2
punpcklwd %xmm1,%xmm1
psrad  $0x18,%xmm1
pand   0xeb7(%rip),%xmm1
psrad  $0x18,%xmm2
pand   0xeba(%rip),%xmm2
por    %xmm1,%xmm2
pand   0xebe(%rip),%xmm4
pand   0xec6(%rip),%xmm3
por    %xmm4,%xmm3
por    %xmm2,%xmm3
pshufd $0xee,%xmm3,%xmm1
por    %xmm3,%xmm1
pshufd $0x55,%xmm1,%xmm2
por    %xmm1,%xmm2
movd   %xmm2,%edi
pshufd $0xee,%xmm0,%xmm1
por    %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
por    %xmm1,%xmm0
movd   %xmm0,%eax
or     %esi,%eax
or     %edx,%eax
or     %ecx,%eax
or     %edi,%eax
ret

LLVM IR (-O0):
define i32 @state_to_number(i8* %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca i32
store i8* %0, i8** %2
store i32 0, i32* %3
store i32 0, i32* %4
br label %5
5: ; preds = %22, %1
%6 = load i32, i32* %4
%7 = icmp slt i32 %6, 23
br i1 %7, label %8, label %25
8: ; preds = %5
%9 = load i8*, i8** %2
%10 = load i32, i32* %4
%11 = sext i32 %10 to i64
%12 = getelementptr inbounds i8, i8* %9, i64 %11
%13 = load i8, i8* %12
%14 = sext i8 %13 to i32
%15 = icmp eq i32 %14, 111
br i1 %15, label %16, label %21
16: ; preds = %8
%17 = load i32, i32* %4
%18 = shl i32 1, %17
%19 = load i32, i32* %3
%20 = or i32 %19, %18
store i32 %20, i32* %3
br label %21
21: ; preds = %16, %8
br label %22
22: ; preds = %21
%23 = load i32, i32* %4
%24 = add nsw i32 %23, 1
store i32 %24, i32* %4
br label %5
25: ; preds = %5
%26 = load i32, i32* %3
ret i32 %26
}

LLVM IR (-O2):
define i32 @state_to_number(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = icmp eq i8 %2, 111
%4 = zext i1 %3 to i32
%5 = getelementptr inbounds i8, i8* %0, i64 1
%6 = load i8, i8* %5
%7 = icmp eq i8 %6, 111
%8 = select i1 %7, i32 2, i32 0
%9 = getelementptr inbounds i8, i8* %0, i64 2
%10 = load i8, i8* %9
%11 = icmp eq i8 %10, 111
%12 = select i1 %11, i32 4, i32 0
%13 = getelementptr inbounds i8, i8* %0, i64 3
%14 = bitcast i8* %13 to <4 x i8>*
%15 = load <4 x i8>, <4 x i8>* %14
%16 = icmp eq <4 x i8> %15, <i8 111, i8 111, i8 111, i8 111>
%17 = select <4 x i1> %16, <4 x i32> <i32 8, i32 16, i32 32, i32 64>, <4 x i32> zeroinitializer
%18 = getelementptr inbounds i8, i8* %0, i64 7
%19 = bitcast i8* %18 to <16 x i8>*
%20 = load <16 x i8>, <16 x i8>* %19
%21 = icmp eq <16 x i8> %20, <i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111, i8 111>
%22 = select <16 x i1> %21, <16 x i32> <i32 128, i32 256, i32 512, i32 1024, i32 2048, i32 4096, i32 8192, i32 16384, i32 32768, i32 65536, i32 131072, i32 262144, i32 524288, i32 1048576, i32 2097152, i32 4194304>, <16 x i32> zeroinitializer
%23 = call i32 @llvm.vector.reduce.or.v16i32(<16 x i32> %22)
%24 = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %17)
%25 = or i32 %23, %24
%26 = or i32 %25, %12
%27 = or i32 %26, %8
%28 = or i32 %27, %4
ret i32 %28
}