char getb2sfac(char *a1, char *a2, int index) {
  int k = index / 8;
  int R = 7 - index % 8;
  if (a1[k] >> R & 1)
    return ('r');
  else if (a2[k] >> R & 1)
    return ('p');
  else
    return ('f');
}


x86 assembly (clang, -O0):
<getb2sfac>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    %eax,-0x20(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    $0x7,%eax
sub    %edx,%eax
mov    %eax,-0x24(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
mov    -0x24(%rbp),%ecx
sar    %cl,%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     1158 <getb2sfac+0x58>
movb   $0x72,-0x1(%rbp)
jmp    1182 <getb2sfac+0x82>
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
mov    -0x24(%rbp),%ecx
sar    %cl,%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     117e <getb2sfac+0x7e>
movb   $0x70,-0x1(%rbp)
jmp    1182 <getb2sfac+0x82>
movb   $0x66,-0x1(%rbp)
movsbl -0x1(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<getb2sfac>:
lea    0x7(%rdx),%eax
test   %edx,%edx
cmovns %edx,%eax
mov    %eax,%ecx
and    $0xfffffff8,%ecx
sub    %ecx,%edx
sar    $0x3,%eax
movslq %eax,%r8
mov    $0x7,%cl
sub    %dl,%cl
mov    $0x1,%edx
shl    %cl,%edx
movsbl (%rdi,%r8,1),%edi
movzbl %cl,%ecx
mov    $0x72,%al
bt     %ecx,%edi
jae    1130 <getb2sfac+0x30>
ret
movsbl (%rsi,%r8,1),%eax
test   %eax,%edx
mov    $0x66,%ecx
mov    $0x70,%eax
cmove  %ecx,%eax
ret

LLVM IR (-O0):
define signext i8 @getb2sfac(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i8* %0, i8** %5
store i8* %1, i8** %6
store i32 %2, i32* %7
%10 = load i32, i32* %7
%11 = sdiv i32 %10, 8
store i32 %11, i32* %8
%12 = load i32, i32* %7
%13 = srem i32 %12, 8
%14 = sub nsw i32 7, %13
store i32 %14, i32* %9
%15 = load i8*, i8** %5
%16 = load i32, i32* %8
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %15, i64 %17
%19 = load i8, i8* %18
%20 = sext i8 %19 to i32
%21 = load i32, i32* %9
%22 = ashr i32 %20, %21
%23 = and i32 %22, 1
%24 = icmp ne i32 %23, 0
br i1 %24, label %25, label %26
25: ; preds = %3
store i8 114, i8* %4
br label %39
26: ; preds = %3
%27 = load i8*, i8** %6
%28 = load i32, i32* %8
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds i8, i8* %27, i64 %29
%31 = load i8, i8* %30
%32 = sext i8 %31 to i32
%33 = load i32, i32* %9
%34 = ashr i32 %32, %33
%35 = and i32 %34, 1
%36 = icmp ne i32 %35, 0
br i1 %36, label %37, label %38
37: ; preds = %26
store i8 112, i8* %4
br label %39
38: ; preds = %26
store i8 102, i8* %4
br label %39
39: ; preds = %38, %37, %25
%40 = load i8, i8* %4
ret i8 %40
}

LLVM IR (-O2):
define signext i8 @getb2sfac(i8* nocapture %0, i8* nocapture %1, i32 %2) {
%4 = sdiv i32 %2, 8
%5 = srem i32 %2, 8
%6 = sub nsw i32 7, %5
%7 = sext i32 %4 to i64
%8 = getelementptr inbounds i8, i8* %0, i64 %7
%9 = load i8, i8* %8
%10 = sext i8 %9 to i32
%11 = shl nuw nsw i32 1, %6
%12 = and i32 %11, %10
%13 = icmp eq i32 %12, 0
br i1 %13, label %14, label %21
14: ; preds = %3
%15 = getelementptr inbounds i8, i8* %1, i64 %7
%16 = load i8, i8* %15
%17 = sext i8 %16 to i32
%18 = and i32 %11, %17
%19 = icmp eq i32 %18, 0
%20 = select i1 %19, i8 102, i8 112
br label %21
21: ; preds = %14, %3
%22 = phi i8 [ 114, %3 ], [ %20, %14 ]
ret i8 %22
}