unsigned char msb_pos(unsigned char byte) {
  static const unsigned char mask[] = {0x1, 0x3, 0xf};
  unsigned char r, s;
  r = ((mask[2] & byte) < byte) << 2;
  byte >>= r;
  s = ((mask[1] & byte) < byte) << 1;
  byte >>= s;
  r += s;
  return r + ((mask[0] & byte) < byte);
}


x86 assembly (clang, -O0):
<msb_pos>:
push   %rbp
mov    %rsp,%rbp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movzbl 0xef1(%rip),%eax
movzbl -0x1(%rbp),%ecx
and    %ecx,%eax
movzbl -0x1(%rbp),%ecx
cmp    %ecx,%eax
setl   %al
and    $0x1,%al
movzbl %al,%eax
shl    $0x2,%eax
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%ecx
movzbl -0x1(%rbp),%eax
sar    %cl,%eax
mov    %al,-0x1(%rbp)
movzbl 0xec2(%rip),%eax
movzbl -0x1(%rbp),%ecx
and    %ecx,%eax
movzbl -0x1(%rbp),%ecx
cmp    %ecx,%eax
setl   %al
and    $0x1,%al
movzbl %al,%eax
shl    $0x1,%eax
mov    %al,-0x3(%rbp)
movzbl -0x3(%rbp),%ecx
movzbl -0x1(%rbp),%eax
sar    %cl,%eax
mov    %al,-0x1(%rbp)
movzbl -0x3(%rbp),%ecx
movzbl -0x2(%rbp),%eax
add    %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%eax
movzbl 0xe82(%rip),%ecx
movzbl -0x1(%rbp),%edx
and    %edx,%ecx
movzbl -0x1(%rbp),%edx
cmp    %edx,%ecx
setl   %cl
and    $0x1,%cl
movzbl %cl,%ecx
add    %ecx,%eax
movzbl %al,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<msb_pos>:
xor    %eax,%eax
cmp    $0x10,%dil
setae  %al
shl    $0x2,%eax
mov    %eax,%ecx
shr    %cl,%edi
xor    %edx,%edx
cmp    $0x4,%edi
setae  %dl
lea    (%rdx,%rdx,1),%ecx
shr    %cl,%edi
lea    (%rax,%rdx,2),%ecx
xor    %eax,%eax
cmp    $0x2,%edi
setae  %al
or     %ecx,%eax
ret

LLVM IR (-O0):
@msb_pos.mask = internal constant [3 x i8] c"\01\03\0F"
define zeroext i8 @msb_pos(i8 zeroext %0) {
%2 = alloca i8
%3 = alloca i8
%4 = alloca i8
store i8 %0, i8* %2
%5 = load i8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @msb_pos.mask, i64 0, i64 2)
%6 = zext i8 %5 to i32
%7 = load i8, i8* %2
%8 = zext i8 %7 to i32
%9 = and i32 %6, %8
%10 = load i8, i8* %2
%11 = zext i8 %10 to i32
%12 = icmp slt i32 %9, %11
%13 = zext i1 %12 to i32
%14 = shl i32 %13, 2
%15 = trunc i32 %14 to i8
store i8 %15, i8* %3
%16 = load i8, i8* %3
%17 = zext i8 %16 to i32
%18 = load i8, i8* %2
%19 = zext i8 %18 to i32
%20 = ashr i32 %19, %17
%21 = trunc i32 %20 to i8
store i8 %21, i8* %2
%22 = load i8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @msb_pos.mask, i64 0, i64 1)
%23 = zext i8 %22 to i32
%24 = load i8, i8* %2
%25 = zext i8 %24 to i32
%26 = and i32 %23, %25
%27 = load i8, i8* %2
%28 = zext i8 %27 to i32
%29 = icmp slt i32 %26, %28
%30 = zext i1 %29 to i32
%31 = shl i32 %30, 1
%32 = trunc i32 %31 to i8
store i8 %32, i8* %4
%33 = load i8, i8* %4
%34 = zext i8 %33 to i32
%35 = load i8, i8* %2
%36 = zext i8 %35 to i32
%37 = ashr i32 %36, %34
%38 = trunc i32 %37 to i8
store i8 %38, i8* %2
%39 = load i8, i8* %4
%40 = zext i8 %39 to i32
%41 = load i8, i8* %3
%42 = zext i8 %41 to i32
%43 = add nsw i32 %42, %40
%44 = trunc i32 %43 to i8
store i8 %44, i8* %3
%45 = load i8, i8* %3
%46 = zext i8 %45 to i32
%47 = load i8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @msb_pos.mask, i64 0, i64 0)
%48 = zext i8 %47 to i32
%49 = load i8, i8* %2
%50 = zext i8 %49 to i32
%51 = and i32 %48, %50
%52 = load i8, i8* %2
%53 = zext i8 %52 to i32
%54 = icmp slt i32 %51, %53
%55 = zext i1 %54 to i32
%56 = add nsw i32 %46, %55
%57 = trunc i32 %56 to i8
ret i8 %57
}

LLVM IR (-O2):
define zeroext i8 @msb_pos(i8 zeroext %0) {
%2 = zext i8 %0 to i32
%3 = icmp ugt i8 %0, 15
%4 = select i1 %3, i32 4, i32 0
%5 = lshr i32 %2, %4
%6 = icmp ugt i32 %5, 3
%7 = select i1 %6, i32 2, i32 0
%8 = lshr i32 %5, %7
%9 = or i32 %7, %4
%10 = icmp ugt i32 %8, 1
%11 = zext i1 %10 to i32
%12 = or i32 %9, %11
%13 = trunc i32 %12 to i8
ret i8 %13
}