short unflag(unsigned long flag) {
  short i;
  for (i = 0; i < 32; i++) {
    if (flag >> i == 1) {
      return i;
    }
  }
  return -1;
}


x86 assembly (clang, -O0):
<unflag>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
movw   $0x0,-0x12(%rbp)
movswl -0x12(%rbp),%eax
cmp    $0x20,%eax
jge    1155 <unflag+0x55>
mov    -0x10(%rbp),%rax
movswl -0x12(%rbp),%ecx
mov    %ecx,%ecx
shr    %cl,%rax
cmp    $0x1,%rax
jne    113f <unflag+0x3f>
mov    -0x12(%rbp),%ax
mov    %ax,-0x2(%rbp)
jmp    115b <unflag+0x5b>
jmp    1144 <unflag+0x44>
mov    -0x12(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x12(%rbp)
jmp    110e <unflag+0xe>
movw   $0xffff,-0x2(%rbp)
movswl -0x2(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<unflag>:
cmp    $0x1,%rdi
jne    1109 <unflag+0x9>
xor    %eax,%eax
ret
mov    %rdi,%rcx
and    $0xfffffffffffffffe,%rcx
mov    $0x1,%ax
cmp    $0x2,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffffffc,%rcx
mov    $0x2,%ax
cmp    $0x4,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffffff8,%rcx
mov    $0x3,%ax
cmp    $0x8,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffffff0,%rcx
mov    $0x4,%ax
cmp    $0x10,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffffffe0,%rcx
mov    $0x5,%ax
cmp    $0x20,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffffffc0,%rcx
mov    $0x6,%ax
cmp    $0x40,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffffff80,%rcx
mov    $0x7,%ax
cmp    $0x80,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffffff00,%rcx
mov    $0x8,%ax
cmp    $0x100,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffffe00,%rcx
mov    $0x9,%ax
cmp    $0x200,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffffc00,%rcx
mov    $0xa,%ax
cmp    $0x400,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffff800,%rcx
mov    $0xb,%ax
cmp    $0x800,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffff000,%rcx
mov    $0xc,%ax
cmp    $0x1000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffffe000,%rcx
mov    $0xd,%ax
cmp    $0x2000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffffc000,%rcx
mov    $0xe,%ax
cmp    $0x4000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffff8000,%rcx
mov    $0xf,%ax
cmp    $0x8000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffff0000,%rcx
mov    $0x10,%ax
cmp    $0x10000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffe0000,%rcx
mov    $0x11,%ax
cmp    $0x20000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffffc0000,%rcx
mov    $0x12,%ax
cmp    $0x40000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffff80000,%rcx
mov    $0x13,%ax
cmp    $0x80000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffff00000,%rcx
mov    $0x14,%ax
cmp    $0x100000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffe00000,%rcx
mov    $0x15,%ax
cmp    $0x200000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffffc00000,%rcx
mov    $0x16,%ax
cmp    $0x400000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffff800000,%rcx
mov    $0x17,%ax
cmp    $0x800000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffff000000,%rcx
mov    $0x18,%ax
cmp    $0x1000000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffe000000,%rcx
mov    $0x19,%ax
cmp    $0x2000000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffffc000000,%rcx
mov    $0x1a,%ax
cmp    $0x4000000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffff8000000,%rcx
mov    $0x1b,%ax
cmp    $0x8000000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xfffffffff0000000,%rcx
mov    $0x1c,%ax
cmp    $0x10000000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffe0000000,%rcx
mov    $0x1d,%ax
cmp    $0x20000000,%rcx
je     140b <unflag+0x30b>
mov    %rdi,%rcx
and    $0xffffffffc0000000,%rcx
mov    $0x1e,%ax
cmp    $0x40000000,%rcx
je     140b <unflag+0x30b>
shr    $0x1f,%rdi
xor    %eax,%eax
cmp    $0x1,%rdi
sete   %al
shl    $0x5,%eax
add    $0xffffffff,%eax
ret

LLVM IR (-O0):
define signext i16 @unflag(i64 %0) {
%2 = alloca i16
%3 = alloca i64
%4 = alloca i16
store i64 %0, i64* %3
store i16 0, i16* %4
br label %5
5: ; preds = %19, %1
%6 = load i16, i16* %4
%7 = sext i16 %6 to i32
%8 = icmp slt i32 %7, 32
br i1 %8, label %9, label %22
9: ; preds = %5
%10 = load i64, i64* %3
%11 = load i16, i16* %4
%12 = sext i16 %11 to i32
%13 = zext i32 %12 to i64
%14 = lshr i64 %10, %13
%15 = icmp eq i64 %14, 1
br i1 %15, label %16, label %18
16: ; preds = %9
%17 = load i16, i16* %4
store i16 %17, i16* %2
br label %23
18: ; preds = %9
br label %19
19: ; preds = %18
%20 = load i16, i16* %4
%21 = add i16 %20, 1
store i16 %21, i16* %4
br label %5
22: ; preds = %5
store i16 -1, i16* %2
br label %23
23: ; preds = %22, %16
%24 = load i16, i16* %2
ret i16 %24
}

LLVM IR (-O2):
define signext i16 @unflag(i64 %0) {
%2 = icmp eq i64 %0, 1
br i1 %2, label %97, label %3
3: ; preds = %1
%4 = and i64 %0, -2
%5 = icmp eq i64 %4, 2
br i1 %5, label %97, label %6
6: ; preds = %3
%7 = and i64 %0, -4
%8 = icmp eq i64 %7, 4
br i1 %8, label %97, label %9
9: ; preds = %6
%10 = and i64 %0, -8
%11 = icmp eq i64 %10, 8
br i1 %11, label %97, label %12
12: ; preds = %9
%13 = and i64 %0, -16
%14 = icmp eq i64 %13, 16
br i1 %14, label %97, label %15
15: ; preds = %12
%16 = and i64 %0, -32
%17 = icmp eq i64 %16, 32
br i1 %17, label %97, label %18
18: ; preds = %15
%19 = and i64 %0, -64
%20 = icmp eq i64 %19, 64
br i1 %20, label %97, label %21
21: ; preds = %18
%22 = and i64 %0, -128
%23 = icmp eq i64 %22, 128
br i1 %23, label %97, label %24
24: ; preds = %21
%25 = and i64 %0, -256
%26 = icmp eq i64 %25, 256
br i1 %26, label %97, label %27
27: ; preds = %24
%28 = and i64 %0, -512
%29 = icmp eq i64 %28, 512
br i1 %29, label %97, label %30
30: ; preds = %27
%31 = and i64 %0, -1024
%32 = icmp eq i64 %31, 1024
br i1 %32, label %97, label %33
33: ; preds = %30
%34 = and i64 %0, -2048
%35 = icmp eq i64 %34, 2048
br i1 %35, label %97, label %36
36: ; preds = %33
%37 = and i64 %0, -4096
%38 = icmp eq i64 %37, 4096
br i1 %38, label %97, label %39
39: ; preds = %36
%40 = and i64 %0, -8192
%41 = icmp eq i64 %40, 8192
br i1 %41, label %97, label %42
42: ; preds = %39
%43 = and i64 %0, -16384
%44 = icmp eq i64 %43, 16384
br i1 %44, label %97, label %45
45: ; preds = %42
%46 = and i64 %0, -32768
%47 = icmp eq i64 %46, 32768
br i1 %47, label %97, label %48
48: ; preds = %45
%49 = and i64 %0, -65536
%50 = icmp eq i64 %49, 65536
br i1 %50, label %97, label %51
51: ; preds = %48
%52 = and i64 %0, -131072
%53 = icmp eq i64 %52, 131072
br i1 %53, label %97, label %54
54: ; preds = %51
%55 = and i64 %0, -262144
%56 = icmp eq i64 %55, 262144
br i1 %56, label %97, label %57
57: ; preds = %54
%58 = and i64 %0, -524288
%59 = icmp eq i64 %58, 524288
br i1 %59, label %97, label %60
60: ; preds = %57
%61 = and i64 %0, -1048576
%62 = icmp eq i64 %61, 1048576
br i1 %62, label %97, label %63
63: ; preds = %60
%64 = and i64 %0, -2097152
%65 = icmp eq i64 %64, 2097152
br i1 %65, label %97, label %66
66: ; preds = %63
%67 = and i64 %0, -4194304
%68 = icmp eq i64 %67, 4194304
br i1 %68, label %97, label %69
69: ; preds = %66
%70 = and i64 %0, -8388608
%71 = icmp eq i64 %70, 8388608
br i1 %71, label %97, label %72
72: ; preds = %69
%73 = and i64 %0, -16777216
%74 = icmp eq i64 %73, 16777216
br i1 %74, label %97, label %75
75: ; preds = %72
%76 = and i64 %0, -33554432
%77 = icmp eq i64 %76, 33554432
br i1 %77, label %97, label %78
78: ; preds = %75
%79 = and i64 %0, -67108864
%80 = icmp eq i64 %79, 67108864
br i1 %80, label %97, label %81
81: ; preds = %78
%82 = and i64 %0, -134217728
%83 = icmp eq i64 %82, 134217728
br i1 %83, label %97, label %84
84: ; preds = %81
%85 = and i64 %0, -268435456
%86 = icmp eq i64 %85, 268435456
br i1 %86, label %97, label %87
87: ; preds = %84
%88 = and i64 %0, -536870912
%89 = icmp eq i64 %88, 536870912
br i1 %89, label %97, label %90
90: ; preds = %87
%91 = and i64 %0, -1073741824
%92 = icmp eq i64 %91, 1073741824
br i1 %92, label %97, label %93
93: ; preds = %90
%94 = and i64 %0, -2147483648
%95 = icmp eq i64 %94, 2147483648
%96 = select i1 %95, i16 31, i16 -1
br label %97
97: ; preds = %93, %90, %87, %84, %81, %78, %75, %72, %69, %66, %63, %60, %57, %54, %51, %48, %45, %42, %39, %36, %33, %30, %27, %24, %21, %18, %15, %12, %9, %6, %3, %1
%98 = phi i16 [ 0, %1 ], [ 1, %3 ], [ 2, %6 ], [ 3, %9 ], [ 4, %12 ], [ 5, %15 ], [ 6, %18 ], [ 7, %21 ], [ 8, %24 ], [ 9, %27 ], [ 10, %30 ], [ 11, %33 ], [ 12, %36 ], [ 13, %39 ], [ 14, %42 ], [ 15, %45 ], [ 16, %48 ], [ 17, %51 ], [ 18, %54 ], [ 19, %57 ], [ 20, %60 ], [ 21, %63 ], [ 22, %66 ], [ 23, %69 ], [ 24, %72 ], [ 25, %75 ], [ 26, %78 ], [ 27, %81 ], [ 28, %84 ], [ 29, %87 ], [ 30, %90 ], [ %96, %93 ]
ret i16 %98
}