https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105429
--- Comment #1 from Uroš Bizjak <ubizjak at gmail dot com> --- The intrinsic is defined as: unsinged __int64 _mm_crc32_u64( unsinged __int64 crc, unsigned __int64 data ) and the unnecessary move is in fact zero-extend: movl %eax, %eax # 16 [c=1 l=2] *zero_extendsidi2/3 You probably want: uint32_t crc(uint64_t current, const uint8_t *buffer, size_t size) { for(size_t i = 0; i < size; i++) current = _mm_crc32_u64(current, buffer[i]); return current; }