int __ffss(bits)
short int bits;
{
  unsigned short int shift;
  unsigned short int ind = (bits & -bits);
  static const unsigned char lookup[] = {
      0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5,
      5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
      6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  };
  shift = (ind > 0xff) ? 8 : 0;
  return lookup[ind >> shift] + shift;
}


x86 assembly (clang, -O0):
<__ffss>:
push   %rbp
mov    %rsp,%rbp
mov    %di,%ax
mov    %ax,-0x2(%rbp)
movswl -0x2(%rbp),%eax
movswl -0x2(%rbp),%edx
xor    %ecx,%ecx
sub    %edx,%ecx
and    %ecx,%eax
mov    %ax,-0x6(%rbp)
movzwl -0x6(%rbp),%edx
xor    %eax,%eax
mov    $0x8,%ecx
cmp    $0xff,%edx
cmovg  %ecx,%eax
mov    %ax,-0x4(%rbp)
movzwl -0x6(%rbp),%eax
movzwl -0x4(%rbp),%ecx
sar    %cl,%eax
movslq %eax,%rcx
lea    0xeb7(%rip),%rax
movzbl (%rax,%rcx,1),%eax
movzwl -0x4(%rbp),%ecx
add    %ecx,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<__ffss>:
mov    %edi,%eax
neg    %eax
and    %edi,%eax
movzwl %ax,%eax
xor    %edx,%edx
cmp    $0x100,%eax
setae  %dl
lea    0x0(,%rdx,8),%ecx
shr    %cl,%rax
lea    0xedc(%rip),%rcx
movzbl (%rax,%rcx,1),%eax
lea    (%rax,%rdx,8),%eax
ret

LLVM IR (-O0):
@__ffss.lookup = internal constant [128 x i8] c"\00\01\02\02\03\03\03\03\04\04\04\04\04\04\04\04\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07"
define i32 @__ffss(i32 %0) {
%2 = alloca i16
%3 = alloca i16
%4 = alloca i16
%5 = trunc i32 %0 to i16
store i16 %5, i16* %2
%6 = load i16, i16* %2
%7 = sext i16 %6 to i32
%8 = load i16, i16* %2
%9 = sext i16 %8 to i32
%10 = sub nsw i32 0, %9
%11 = and i32 %7, %10
%12 = trunc i32 %11 to i16
store i16 %12, i16* %4
%13 = load i16, i16* %4
%14 = zext i16 %13 to i32
%15 = icmp sgt i32 %14, 255
%16 = zext i1 %15 to i64
%17 = select i1 %15, i32 8, i32 0
%18 = trunc i32 %17 to i16
store i16 %18, i16* %3
%19 = load i16, i16* %4
%20 = zext i16 %19 to i32
%21 = load i16, i16* %3
%22 = zext i16 %21 to i32
%23 = ashr i32 %20, %22
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds [128 x i8], [128 x i8]* @__ffss.lookup, i64 0, i64 %24
%26 = load i8, i8* %25
%27 = zext i8 %26 to i32
%28 = load i16, i16* %3
%29 = zext i16 %28 to i32
%30 = add nsw i32 %27, %29
ret i32 %30
}

LLVM IR (-O2):
@__ffss.lookup = internal unnamed_addr constant [128 x i8] c"\00\01\02\02\03\03\03\03\04\04\04\04\04\04\04\04\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07"
define i32 @__ffss(i32 %0) {
%2 = sub i32 0, %0
%3 = and i32 %0, 65535
%4 = and i32 %3, %2
%5 = icmp ugt i32 %4, 255
%6 = select i1 %5, i32 8, i32 0
%7 = lshr i32 %4, %6
%8 = zext i32 %7 to i64
%9 = getelementptr inbounds [128 x i8], [128 x i8]* @__ffss.lookup, i64 0, i64 %8
%10 = load i8, i8* %9
%11 = zext i8 %10 to i32
%12 = add nuw nsw i32 %6, %11
ret i32 %12
}