https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96176
Bug ID: 96176 Summary: Failure to omit extraneous movzx in atomic compare exchange with unsigned char Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: gabravier at gmail dot com Target Milestone: --- void f(unsigned char *addr, unsigned char old_val, unsigned char new_val) { __atomic_compare_exchange_n(addr, &old_val, new_val, 0, 0, 0); } On x86 with -O3, LLVM generates this : f(unsigned char*, unsigned char, unsigned char): # @f(unsigned char*, unsigned char, unsigned char) mov eax, esi lock cmpxchg byte ptr [rdi], dl ret GCC generates this : f(unsigned char*, unsigned char, unsigned char): mov eax, esi movzx edx, dl lock cmpxchg BYTE PTR [rdi], dl ret