char find_category(int n) {
  int powers_of_two[16] = {1 << 5,  1 << 6,  1 << 7,  1 << 8,  1 << 9,  1 << 10,
                           1 << 11, 1 << 12, 1 << 13, 1 << 14, 1 << 15, 1 << 16,
                           1 << 17, 1 << 18, 1 << 19, 1 << 20};
  for (int i = 0; i < 16; ++i) {
    if (n < powers_of_two[i])
      return i;
  }
  return -1;
}


x86 assembly (clang, -O0):
<find_category>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %edi,-0x8(%rbp)
lea    -0x50(%rbp),%rdi
lea    0xeda(%rip),%rsi
mov    $0x40,%edx
call   1030 <memcpy@plt>
movl   $0x0,-0x54(%rbp)
cmpl   $0x10,-0x54(%rbp)
jge    1170 <find_category+0x60>
mov    -0x8(%rbp),%eax
movslq -0x54(%rbp),%rcx
cmp    -0x50(%rbp,%rcx,4),%eax
jge    115d <find_category+0x4d>
mov    -0x54(%rbp),%eax
mov    %al,-0x1(%rbp)
jmp    1174 <find_category+0x64>
jmp    1162 <find_category+0x52>
mov    -0x54(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
jmp    1137 <find_category+0x27>
movb   $0xff,-0x1(%rbp)
movsbl -0x1(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<find_category>:
cmp    $0x20,%edi
jge    1108 <find_category+0x8>
xor    %eax,%eax
ret
mov    $0x1,%al
cmp    $0x40,%edi
jb     11a7 <find_category+0xa7>
mov    $0x2,%al
cmp    $0x80,%edi
jb     11a7 <find_category+0xa7>
mov    $0x3,%al
cmp    $0x100,%edi
jb     11a7 <find_category+0xa7>
mov    $0x4,%al
cmp    $0x200,%edi
jb     11a7 <find_category+0xa7>
mov    $0x5,%al
cmp    $0x400,%edi
jb     11a7 <find_category+0xa7>
mov    $0x6,%al
cmp    $0x800,%edi
jb     11a7 <find_category+0xa7>
mov    $0x7,%al
cmp    $0x1000,%edi
jb     11a7 <find_category+0xa7>
mov    $0x8,%al
cmp    $0x2000,%edi
jb     11a7 <find_category+0xa7>
mov    $0x9,%al
cmp    $0x4000,%edi
jb     11a7 <find_category+0xa7>
mov    $0xa,%al
cmp    $0x8000,%edi
jb     11a7 <find_category+0xa7>
mov    $0xb,%al
cmp    $0x10000,%edi
jb     11a7 <find_category+0xa7>
mov    $0xc,%al
cmp    $0x20000,%edi
jb     11a7 <find_category+0xa7>
mov    $0xd,%al
cmp    $0x40000,%edi
jb     11a7 <find_category+0xa7>
mov    $0xe,%al
cmp    $0x80000,%edi
jb     11a7 <find_category+0xa7>
cmp    $0x100000,%edi
setb   %al
shl    $0x4,%al
add    $0xff,%al
ret

LLVM IR (-O0):
@__const.find_category.powers_of_two = [16 x i32] [i32 32, i32 64, 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]
define signext i8 @find_category(i32 %0) {
%2 = alloca i8
%3 = alloca i32
%4 = alloca [16 x i32]
%5 = alloca i32
store i32 %0, i32* %3
%6 = bitcast [16 x i32]* %4 to i8*
store i32 0, i32* %5
br label %7
7: ; preds = %21, %1
%8 = load i32, i32* %5
%9 = icmp slt i32 %8, 16
br i1 %9, label %10, label %24
10: ; preds = %7
%11 = load i32, i32* %3
%12 = load i32, i32* %5
%13 = sext i32 %12 to i64
%14 = getelementptr inbounds [16 x i32], [16 x i32]* %4, i64 0, i64 %13
%15 = load i32, i32* %14
%16 = icmp slt i32 %11, %15
br i1 %16, label %17, label %20
17: ; preds = %10
%18 = load i32, i32* %5
%19 = trunc i32 %18 to i8
store i8 %19, i8* %2
br label %25
20: ; preds = %10
br label %21
21: ; preds = %20
%22 = load i32, i32* %5
%23 = add nsw i32 %22, 1
store i32 %23, i32* %5
br label %7
24: ; preds = %7
store i8 -1, i8* %2
br label %25
25: ; preds = %24, %17
%26 = load i8, i8* %2
ret i8 %26
}

LLVM IR (-O2):
define signext i8 @find_category(i32 %0) {
%2 = icmp slt i32 %0, 32
br i1 %2, label %34, label %3
3: ; preds = %1
%4 = icmp ult i32 %0, 64
br i1 %4, label %34, label %5
5: ; preds = %3
%6 = icmp ult i32 %0, 128
br i1 %6, label %34, label %7
7: ; preds = %5
%8 = icmp ult i32 %0, 256
br i1 %8, label %34, label %9
9: ; preds = %7
%10 = icmp ult i32 %0, 512
br i1 %10, label %34, label %11
11: ; preds = %9
%12 = icmp ult i32 %0, 1024
br i1 %12, label %34, label %13
13: ; preds = %11
%14 = icmp ult i32 %0, 2048
br i1 %14, label %34, label %15
15: ; preds = %13
%16 = icmp ult i32 %0, 4096
br i1 %16, label %34, label %17
17: ; preds = %15
%18 = icmp ult i32 %0, 8192
br i1 %18, label %34, label %19
19: ; preds = %17
%20 = icmp ult i32 %0, 16384
br i1 %20, label %34, label %21
21: ; preds = %19
%22 = icmp ult i32 %0, 32768
br i1 %22, label %34, label %23
23: ; preds = %21
%24 = icmp ult i32 %0, 65536
br i1 %24, label %34, label %25
25: ; preds = %23
%26 = icmp ult i32 %0, 131072
br i1 %26, label %34, label %27
27: ; preds = %25
%28 = icmp ult i32 %0, 262144
br i1 %28, label %34, label %29
29: ; preds = %27
%30 = icmp ult i32 %0, 524288
br i1 %30, label %34, label %31
31: ; preds = %29
%32 = icmp ult i32 %0, 1048576
%33 = select i1 %32, i8 15, i8 -1
br label %34
34: ; preds = %31, %1, %3, %5, %7, %9, %11, %13, %15, %17, %19, %21, %23, %25, %27, %29
%35 = phi i8 [ 0, %1 ], [ 1, %3 ], [ 2, %5 ], [ 3, %7 ], [ 4, %9 ], [ 5, %11 ], [ 6, %13 ], [ 7, %15 ], [ 8, %17 ], [ 9, %19 ], [ 10, %21 ], [ 11, %23 ], [ 12, %25 ], [ 13, %27 ], [ 14, %29 ], [ %33, %31 ]
ret i8 %35
}