unsigned long count(unsigned long r, unsigned short size) {
  unsigned long sum = 0;
  unsigned short i;
  for (i = 0; i < size; ++i)
    sum += ((r >> i) & 1);
  return sum;
}


x86 assembly (clang, -O0):
<count>:
push   %rbp
mov    %rsp,%rbp
mov    %si,%ax
mov    %rdi,-0x8(%rbp)
mov    %ax,-0xa(%rbp)
movq   $0x0,-0x18(%rbp)
movw   $0x0,-0x1a(%rbp)
movzwl -0x1a(%rbp),%eax
movzwl -0xa(%rbp),%ecx
cmp    %ecx,%eax
jge    1157 <count+0x57>
mov    -0x8(%rbp),%rax
movzwl -0x1a(%rbp),%ecx
mov    %ecx,%ecx
shr    %cl,%rax
and    $0x1,%rax
add    -0x18(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x1a(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x1a(%rbp)
jmp    111d <count+0x1d>
mov    -0x18(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<count>:
test   %esi,%esi
je     1116 <count+0x16>
movzwl %si,%edx
cmp    $0x4,%dx
jae    1119 <count+0x19>
xor    %ecx,%ecx
xor    %eax,%eax
jmp    12c0 <count+0x1c0>
xor    %eax,%eax
ret
mov    %edx,%ecx
and    $0xfffffffc,%ecx
movq   %rdi,%xmm0
pshufd $0x44,%xmm0,%xmm13
lea    -0x4(%rcx),%rsi
mov    %rsi,%rax
shr    $0x2,%rax
add    $0x1,%rax
test   %rsi,%rsi
je     12d6 <count+0x1d6>
mov    %rax,%rsi
and    $0xfffffffffffffffe,%rsi
pxor   %xmm1,%xmm1
movdqa 0xeac(%rip),%xmm4
movdqa 0xeb3(%rip),%xmm8
movapd 0xeba(%rip),%xmm12
movdqa 0xec1(%rip),%xmm9
movdqa 0xec8(%rip),%xmm10
movdqa 0xecf(%rip),%xmm11
pxor   %xmm2,%xmm2
cs nopw 0x0(%rax,%rax,1)
nop
movdqa %xmm13,%xmm6
psrlq  %xmm4,%xmm6
movdqa %xmm4,%xmm3
pshufd $0xee,%xmm4,%xmm5
movdqa %xmm13,%xmm0
psrlq  %xmm5,%xmm0
paddq  %xmm8,%xmm3
movsd  %xmm6,%xmm0
movdqa %xmm13,%xmm5
psrlq  %xmm3,%xmm5
pshufd $0xee,%xmm3,%xmm3
movdqa %xmm13,%xmm6
psrlq  %xmm3,%xmm6
movsd  %xmm5,%xmm6
andpd  %xmm12,%xmm0
paddq  %xmm1,%xmm0
andpd  %xmm12,%xmm6
movdqa %xmm4,%xmm1
paddq  %xmm9,%xmm1
movdqa %xmm4,%xmm3
paddq  %xmm10,%xmm3
movdqa %xmm13,%xmm5
psrlq  %xmm1,%xmm5
pshufd $0xee,%xmm1,%xmm7
movdqa %xmm13,%xmm1
psrlq  %xmm7,%xmm1
movdqa %xmm13,%xmm7
psrlq  %xmm3,%xmm7
paddq  %xmm2,%xmm6
pshufd $0xee,%xmm3,%xmm3
movdqa %xmm13,%xmm2
psrlq  %xmm3,%xmm2
movsd  %xmm5,%xmm1
movsd  %xmm7,%xmm2
andpd  %xmm12,%xmm1
paddq  %xmm0,%xmm1
andpd  %xmm12,%xmm2
paddq  %xmm6,%xmm2
paddq  %xmm11,%xmm4
add    $0xfffffffffffffffe,%rsi
jne    1190 <count+0x90>
test   $0x1,%al
je     12a7 <count+0x1a7>
movdqa 0xdba(%rip),%xmm0
movdqa %xmm13,%xmm3
psrlq  %xmm4,%xmm3
paddq  %xmm4,%xmm0
pshufd $0xee,%xmm4,%xmm4
movdqa %xmm13,%xmm5
psrlq  %xmm4,%xmm5
movsd  %xmm3,%xmm5
movdqa %xmm13,%xmm3
psrlq  %xmm0,%xmm3
pshufd $0xee,%xmm0,%xmm0
psrlq  %xmm0,%xmm13
movsd  %xmm3,%xmm13
movapd 0xd8b(%rip),%xmm0
andpd  %xmm0,%xmm5
paddq  %xmm5,%xmm1
andpd  %xmm0,%xmm13
paddq  %xmm13,%xmm2
paddq  %xmm2,%xmm1
pshufd $0xee,%xmm1,%xmm0
paddq  %xmm1,%xmm0
movq   %xmm0,%rax
cmp    %rdx,%rcx
je     12d5 <count+0x1d5>
xchg   %ax,%ax
mov    %rdi,%rsi
shr    %cl,%rsi
and    $0x1,%esi
add    %rsi,%rax
add    $0x1,%rcx
cmp    %rcx,%rdx
jne    12c0 <count+0x1c0>
ret
pxor   %xmm1,%xmm1
movdqa 0xd1e(%rip),%xmm4
pxor   %xmm2,%xmm2
test   $0x1,%al
jne    124e <count+0x14e>
jmp    12a7 <count+0x1a7>

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

LLVM IR (-O2):
define i64 @count(i64 %0, i16 zeroext %1) {
%3 = icmp eq i16 %1, 0
br i1 %3, label %75, label %4
4: ; preds = %2
%5 = zext i16 %1 to i64
%6 = icmp ult i16 %1, 4
br i1 %6, label %64, label %7
7: ; preds = %4
%8 = and i64 %5, 65532
%9 = insertelement <2 x i64> poison, i64 %0, i64 0
%10 = shufflevector <2 x i64> %9, <2 x i64> poison, <2 x i32> zeroinitializer
%11 = insertelement <2 x i64> poison, i64 %0, i64 0
%12 = shufflevector <2 x i64> %11, <2 x i64> poison, <2 x i32> zeroinitializer
%13 = add nsw i64 %8, -4
%14 = lshr exact i64 %13, 2
%15 = add nuw nsw i64 %14, 1
%16 = and i64 %15, 1
%17 = icmp eq i64 %13, 0
br i1 %17, label %43, label %18
18: ; preds = %7
%19 = and i64 %15, 9223372036854775806
br label %20
20: ; preds = %20, %18
%21 = phi <2 x i64> [ <i64 0, i64 1>, %18 ], [ %40, %20 ]
%22 = phi <2 x i64> [ zeroinitializer, %18 ], [ %38, %20 ]
%23 = phi <2 x i64> [ zeroinitializer, %18 ], [ %39, %20 ]
%24 = phi i64 [ 0, %18 ], [ %41, %20 ]
%25 = add <2 x i64> %21, <i64 2, i64 2>
%26 = lshr <2 x i64> %10, %21
%27 = lshr <2 x i64> %12, %25
%28 = and <2 x i64> %26, <i64 1, i64 1>
%29 = and <2 x i64> %27, <i64 1, i64 1>
%30 = add <2 x i64> %28, %22
%31 = add <2 x i64> %29, %23
%32 = add <2 x i64> %21, <i64 4, i64 4>
%33 = add <2 x i64> %21, <i64 6, i64 6>
%34 = lshr <2 x i64> %10, %32
%35 = lshr <2 x i64> %12, %33
%36 = and <2 x i64> %34, <i64 1, i64 1>
%37 = and <2 x i64> %35, <i64 1, i64 1>
%38 = add <2 x i64> %36, %30
%39 = add <2 x i64> %37, %31
%40 = add <2 x i64> %21, <i64 8, i64 8>
%41 = add i64 %24, 2
%42 = icmp eq i64 %41, %19
br i1 %42, label %43, label %20
43: ; preds = %20, %7
%44 = phi <2 x i64> [ undef, %7 ], [ %38, %20 ]
%45 = phi <2 x i64> [ undef, %7 ], [ %39, %20 ]
%46 = phi <2 x i64> [ <i64 0, i64 1>, %7 ], [ %40, %20 ]
%47 = phi <2 x i64> [ zeroinitializer, %7 ], [ %38, %20 ]
%48 = phi <2 x i64> [ zeroinitializer, %7 ], [ %39, %20 ]
%49 = icmp eq i64 %16, 0
br i1 %49, label %58, label %50
50: ; preds = %43
%51 = add <2 x i64> %46, <i64 2, i64 2>
%52 = lshr <2 x i64> %10, %46
%53 = lshr <2 x i64> %12, %51
%54 = and <2 x i64> %52, <i64 1, i64 1>
%55 = and <2 x i64> %53, <i64 1, i64 1>
%56 = add <2 x i64> %54, %47
%57 = add <2 x i64> %55, %48
br label %58
58: ; preds = %43, %50
%59 = phi <2 x i64> [ %44, %43 ], [ %56, %50 ]
%60 = phi <2 x i64> [ %45, %43 ], [ %57, %50 ]
%61 = add <2 x i64> %60, %59
%62 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %61)
%63 = icmp eq i64 %8, %5
br i1 %63, label %75, label %64
64: ; preds = %4, %58
%65 = phi i64 [ 0, %4 ], [ %8, %58 ]
%66 = phi i64 [ 0, %4 ], [ %62, %58 ]
br label %67
67: ; preds = %64, %67
%68 = phi i64 [ %73, %67 ], [ %65, %64 ]
%69 = phi i64 [ %72, %67 ], [ %66, %64 ]
%70 = lshr i64 %0, %68
%71 = and i64 %70, 1
%72 = add i64 %71, %69
%73 = add nuw nsw i64 %68, 1
%74 = icmp eq i64 %73, %5
br i1 %74, label %75, label %67
75: ; preds = %67, %58, %2
%76 = phi i64 [ 0, %2 ], [ %62, %58 ], [ %72, %67 ]
ret i64 %76
}