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.

Reply via email to