danluu knows much more about the subject matter than me. Meanwhile...
If I take the main.cpp from http://www.strchr.com/media/crc32_popcnt.zip that he comparing and paste it into a new, default, VC2010 project. Then compile it as a Release build, then the mixed disassembly for the inner loop of POPCNT_HardwareSubbuN() looks like
cnt += __popcnt(*(DWORD*)buf) +
__popcnt(*(DWORD*)(buf + sizeof(DWORD) )) +
__popcnt(*(DWORD*)(buf + sizeof(DWORD) * 2 )) +
__popcnt(*(DWORD*)(buf + sizeof(DWORD) * 3 ));
00E71BE0 popcnt ebx,dword ptr [edx+8]
00E71BE5 popcnt esi,dword ptr [edx+0Ch]
00E71BEA add esi,ebx
00E71BEC popcnt ebx,dword ptr [edx+4]
00E71BF1 add esi,ebx
00E71BF3 popcnt ebx,dword ptr [edx]
00E71BF7 add eax,ebx
00E71BF9 add eax,esi
buf += sizeof(DWORD) * 4;
00E71BFB add edx,10h
00E71BFE dec ecx
00E71BFF jne POPCNT_HardwareUnrolled+50h (0E71BE0h)
which looks to me to be as good or better than his inline asm 00000001000013c3 popcntq %r10, %r10
00000001000013c8 addq %r10, %rcx
00000001000013cb popcntq %r11, %r11
00000001000013d0 addq %r11, %r9
00000001000013d3 popcntq %r14, %r14
00000001000013d8 addq %r14, %r8
00000001000013db popcntq %rbx, %rbx
And does not have the odd 000000010000133e movl %ecx, %r10d
0000000100001341 movl %edx, %r11d
0000000100001344 movl %eax, %r14d
0000000100001347 movl %r8d, %ebx
He was complaining about.Maybe there's some compiler issue about arrays that makes using "int cnt[4];" as the accumulator induce the seemingly extraneous movls?