https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96938
Bug ID: 96938 Summary: Failure to optimize bit-setting pattern when not using temporary Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: gabravier at gmail dot com Target Milestone: --- void g(char *f, int offset, char value) { *f = (int)(*f & ~(1 << (offset & 0x1F))) | (value << (offset & 0x1F)); } This has much worse code generation than this: void g(char *f, int offset, char value) { int tmp = *f & ~(1 << (offset & 0x1F)); *f = tmp | (value << (offset & 0x1F)); } Which should be equivalent to the first example. Example of the worse code generation, on x86 the first example compiles to this: g(char*, int, char): movzx ecx, BYTE PTR [rdi] mov eax, 1 movsx edx, dl shlx eax, eax, esi shlx edx, edx, esi andn eax, eax, ecx or eax, edx mov BYTE PTR [rdi], al ret Whereas the second example compiles to this: g(char*, int, char): movsx eax, BYTE PTR [rdi] movsx edx, dl shlx edx, edx, esi btr eax, esi or eax, edx mov BYTE PTR [rdi], al ret