int fls(num)
long num;
{
  int ret = 1;
  if (!num)
    return 0;
  if (num < 0)
    num = -num;
  if (num & 0xffff0000) {
    ret += 16;
    num = (num >> 16) & 0xffff;
  }
  if (num & 0xff00) {
    ret += 8;
    num >>= 8;
  }
  if (num & 0xf0) {
    ret += 4;
    num >>= 4;
  }
  if (num & 0x0c) {
    ret += 2;
    num >>= 2;
  }
  if (num & 2)
    ret++;
  return ret;
}


x86 assembly (clang, -O0):
<fls>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
movl   $0x1,-0x14(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1126 <fls+0x26>
movl   $0x0,-0x4(%rbp)
jmp    1208 <fls+0x108>
cmpq   $0x0,-0x10(%rbp)
jge    113b <fls+0x3b>
xor    %eax,%eax
sub    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
movabs $0xffff0000,%rax
and    -0x10(%rbp),%rax
cmp    $0x0,%rax
je     116e <fls+0x6e>
mov    -0x14(%rbp),%eax
add    $0x10,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
sar    $0x10,%rax
and    $0xffff,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
and    $0xff00,%rax
cmp    $0x0,%rax
je     1197 <fls+0x97>
mov    -0x14(%rbp),%eax
add    $0x8,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
sar    $0x8,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
and    $0xf0,%rax
cmp    $0x0,%rax
je     11c0 <fls+0xc0>
mov    -0x14(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
sar    $0x4,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
and    $0xc,%rax
cmp    $0x0,%rax
je     11e7 <fls+0xe7>
mov    -0x14(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
sar    $0x2,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
and    $0x2,%rax
cmp    $0x0,%rax
je     1202 <fls+0x102>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<fls>:
test   %rdi,%rdi
je     116e <fls+0x6e>
mov    %rdi,%rcx
neg    %rcx
cmovs  %rdi,%rcx
mov    %ecx,%edx
shr    $0x10,%edx
xor    %eax,%eax
test   $0xffff0000,%ecx
setne  %al
cmove  %rcx,%rdx
shl    $0x4,%eax
lea    0x1(%rax),%ecx
or     $0x9,%eax
mov    %rdx,%rsi
shr    $0x8,%rsi
test   $0xff00,%edx
cmove  %rdx,%rsi
cmove  %ecx,%eax
lea    0x4(%rax),%ecx
mov    %rsi,%rdx
shr    $0x4,%rdx
test   $0xf0,%sil
cmove  %rsi,%rdx
cmove  %eax,%ecx
lea    0x2(%rcx),%esi
mov    %edx,%eax
shr    $0x2,%eax
test   $0xc,%dl
cmove  %ecx,%esi
cmove  %edx,%eax
shr    %eax
and    $0x1,%eax
add    %esi,%eax
ret
xor    %eax,%eax
ret

LLVM IR (-O0):
define i32 @fls(i64 %0) {
%2 = alloca i32
%3 = alloca i64
%4 = alloca i32
store i64 %0, i64* %3
store i32 1, i32* %4
%5 = load i64, i64* %3
%6 = icmp ne i64 %5, 0
br i1 %6, label %8, label %7
7: ; preds = %1
store i32 0, i32* %2
br label %60
8: ; preds = %1
%9 = load i64, i64* %3
%10 = icmp slt i64 %9, 0
br i1 %10, label %11, label %14
11: ; preds = %8
%12 = load i64, i64* %3
%13 = sub nsw i64 0, %12
store i64 %13, i64* %3
br label %14
14: ; preds = %11, %8
%15 = load i64, i64* %3
%16 = and i64 %15, 4294901760
%17 = icmp ne i64 %16, 0
br i1 %17, label %18, label %24
18: ; preds = %14
%19 = load i32, i32* %4
%20 = add nsw i32 %19, 16
store i32 %20, i32* %4
%21 = load i64, i64* %3
%22 = ashr i64 %21, 16
%23 = and i64 %22, 65535
store i64 %23, i64* %3
br label %24
24: ; preds = %18, %14
%25 = load i64, i64* %3
%26 = and i64 %25, 65280
%27 = icmp ne i64 %26, 0
br i1 %27, label %28, label %33
28: ; preds = %24
%29 = load i32, i32* %4
%30 = add nsw i32 %29, 8
store i32 %30, i32* %4
%31 = load i64, i64* %3
%32 = ashr i64 %31, 8
store i64 %32, i64* %3
br label %33
33: ; preds = %28, %24
%34 = load i64, i64* %3
%35 = and i64 %34, 240
%36 = icmp ne i64 %35, 0
br i1 %36, label %37, label %42
37: ; preds = %33
%38 = load i32, i32* %4
%39 = add nsw i32 %38, 4
store i32 %39, i32* %4
%40 = load i64, i64* %3
%41 = ashr i64 %40, 4
store i64 %41, i64* %3
br label %42
42: ; preds = %37, %33
%43 = load i64, i64* %3
%44 = and i64 %43, 12
%45 = icmp ne i64 %44, 0
br i1 %45, label %46, label %51
46: ; preds = %42
%47 = load i32, i32* %4
%48 = add nsw i32 %47, 2
store i32 %48, i32* %4
%49 = load i64, i64* %3
%50 = ashr i64 %49, 2
store i64 %50, i64* %3
br label %51
51: ; preds = %46, %42
%52 = load i64, i64* %3
%53 = and i64 %52, 2
%54 = icmp ne i64 %53, 0
br i1 %54, label %55, label %58
55: ; preds = %51
%56 = load i32, i32* %4
%57 = add nsw i32 %56, 1
store i32 %57, i32* %4
br label %58
58: ; preds = %55, %51
%59 = load i32, i32* %4
store i32 %59, i32* %2
br label %60
60: ; preds = %58, %7
%61 = load i32, i32* %2
ret i32 %61
}

LLVM IR (-O2):
define i32 @fls(i64 %0) {
%2 = icmp eq i64 %0, 0
br i1 %2, label %33, label %3
3: ; preds = %1
%4 = tail call i64 @llvm.abs.i64(i64 %0, i1 true)
%5 = and i64 %4, 4294901760
%6 = icmp eq i64 %5, 0
%7 = lshr i64 %4, 16
%8 = and i64 %7, 65535
%9 = select i1 %6, i64 %4, i64 %8
%10 = select i1 %6, i32 1, i32 17
%11 = and i64 %9, 65280
%12 = icmp eq i64 %11, 0
%13 = or i32 %10, 8
%14 = lshr i64 %9, 8
%15 = select i1 %12, i64 %9, i64 %14
%16 = select i1 %12, i32 %10, i32 %13
%17 = and i64 %15, 240
%18 = icmp eq i64 %17, 0
%19 = or i32 %16, 4
%20 = lshr i64 %15, 4
%21 = select i1 %18, i64 %15, i64 %20
%22 = select i1 %18, i32 %16, i32 %19
%23 = and i64 %21, 12
%24 = icmp eq i64 %23, 0
%25 = or i32 %22, 2
%26 = lshr i64 %21, 2
%27 = select i1 %24, i64 %21, i64 %26
%28 = select i1 %24, i32 %22, i32 %25
%29 = trunc i64 %27 to i32
%30 = lshr i32 %29, 1
%31 = and i32 %30, 1
%32 = add nsw i32 %31, %28
br label %33
33: ; preds = %1, %3
%34 = phi i32 [ %32, %3 ], [ 0, %1 ]
ret i32 %34
}