https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108477
Bug ID: 108477 Summary: fwprop over-optimizes conversion from + to | Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ubizjak at gmail dot com Target Milestone: --- In the unsigned int case (baz) fwprop over-optimizes the addition to a logical or: --cut here-- int lock; int bar (int old) { int val = (old >> 1) & 0x1; int new = (old & ~0x3) + 0x2 + val; lock = new; return val ? 0 : -1; } int ulock; int baz (unsigned int old) { unsigned int val = (old >> 1) & 0x1; unsigned int new = (old & ~0x3) + 0x2 + val; ulock = new; return val ? 0 : -1; } --cut here-- resulting in: bar: movl %edi, %eax andl $-4, %edi sarl %eax andl $1, %eax leal 2(%rax,%rdi), %edx <---- here subl $1, %eax movl %edx, lock(%rip) ret baz: movl %edi, %eax andl $-4, %edi shrl %eax andl $1, %eax orl %eax, %edi <--- here ... subl $1, %eax addl $2, %edi <--- ... and here movl %edi, ulock(%rip) ret Please note the three-operand addition, implemented with LEAL instruction in the signed case, which is not emitted in the unsigned case. The reason is fwprop pass that substitutes addition with the equivalent or operation.