unsigned long bitmap_ffb(unsigned long word) {
  int b = 0, s;
  if (sizeof(int) == 4) {
    s = 16;
    if (word << 16 != 0)
      s = 0;
    b += s;
    word >>= s;
    s = 8;
    if (word << 24 != 0)
      s = 0;
    b += s;
    word >>= s;
    s = 4;
    if (word << 28 != 0)
      s = 0;
    b += s;
    word >>= s;
    s = 2;
    if (word << 30 != 0)
      s = 0;
    b += s;
    word >>= s;
    s = 1;
    if (word << 31 != 0)
      s = 0;
    b += s;
  }
  return b;
}


x86 assembly (clang, -O0):
<bitmap_ffb>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
movl   $0x10,-0x10(%rbp)
mov    -0x8(%rbp),%rax
shl    $0x10,%rax
cmp    $0x0,%rax
je     112f <bitmap_ffb+0x2f>
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rax
mov    %ecx,%ecx
shr    %cl,%rax
mov    %rax,-0x8(%rbp)
movl   $0x8,-0x10(%rbp)
mov    -0x8(%rbp),%rax
shl    $0x18,%rax
cmp    $0x0,%rax
je     1168 <bitmap_ffb+0x68>
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rax
mov    %ecx,%ecx
shr    %cl,%rax
mov    %rax,-0x8(%rbp)
movl   $0x4,-0x10(%rbp)
mov    -0x8(%rbp),%rax
shl    $0x1c,%rax
cmp    $0x0,%rax
je     11a1 <bitmap_ffb+0xa1>
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rax
mov    %ecx,%ecx
shr    %cl,%rax
mov    %rax,-0x8(%rbp)
movl   $0x2,-0x10(%rbp)
mov    -0x8(%rbp),%rax
shl    $0x1e,%rax
cmp    $0x0,%rax
je     11da <bitmap_ffb+0xda>
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rax
mov    %ecx,%ecx
shr    %cl,%rax
mov    %rax,-0x8(%rbp)
movl   $0x1,-0x10(%rbp)
mov    -0x8(%rbp),%rax
shl    $0x1f,%rax
cmp    $0x0,%rax
je     1213 <bitmap_ffb+0x113>
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0xc(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<bitmap_ffb>:
xor    %ecx,%ecx
mov    %rdi,%rax
shl    $0x10,%rax
sete   %cl
shl    $0x4,%ecx
shr    %cl,%rdi
xor    %eax,%eax
mov    %rdi,%rdx
shl    $0x18,%rdx
sete   %al
lea    (%rcx,%rax,8),%edx
mov    %eax,%ecx
shl    $0x3,%ecx
shr    %cl,%rdi
xor    %eax,%eax
mov    %rdi,%rcx
shl    $0x1c,%rcx
sete   %al
lea    (%rdx,%rax,4),%edx
mov    %eax,%ecx
shl    $0x2,%ecx
shr    %cl,%rdi
xor    %eax,%eax
mov    %rdi,%rcx
shl    $0x1e,%rcx
sete   %al
lea    (%rdx,%rax,2),%edx
mov    %eax,%ecx
add    %eax,%ecx
shr    %cl,%rdi
xor    %eax,%eax
shl    $0x1f,%rdi
sete   %al
or     %edx,%eax
ret

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

LLVM IR (-O2):
define i64 @bitmap_ffb(i64 %0) {
%2 = and i64 %0, 281474976710655
%3 = icmp eq i64 %2, 0
%4 = select i1 %3, i32 16, i32 0
%5 = zext i32 %4 to i64
%6 = lshr i64 %0, %5
%7 = and i64 %6, 1099511627775
%8 = icmp eq i64 %7, 0
%9 = select i1 %8, i32 8, i32 0
%10 = or i32 %9, %4
%11 = zext i32 %9 to i64
%12 = lshr i64 %6, %11
%13 = and i64 %12, 68719476735
%14 = icmp eq i64 %13, 0
%15 = select i1 %14, i32 4, i32 0
%16 = or i32 %10, %15
%17 = zext i32 %15 to i64
%18 = lshr i64 %12, %17
%19 = and i64 %18, 17179869183
%20 = icmp eq i64 %19, 0
%21 = select i1 %20, i32 2, i32 0
%22 = or i32 %16, %21
%23 = zext i32 %21 to i64
%24 = shl nuw nsw i64 8589934591, %23
%25 = and i64 %24, %18
%26 = icmp eq i64 %25, 0
%27 = zext i1 %26 to i32
%28 = or i32 %22, %27
%29 = zext i32 %28 to i64
ret i64 %29
}