https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91504

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |easyhack,
                   |                            |missed-optimization
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-08-21
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is likely that we inline deposit32 if it were

static inline unsigned deposit32(unsigned value, int start, int length,
                                 unsigned fieldval)
{
  unsigned mask = (~0U >> (32 - length)) << start;
  return (((fieldval << start) ^ value) & mask) ^ value;
}

changing bar() to the above form results in the same assembly for both.
We end up with (~value & 1024) ^ value:

  _5 = ~value_2(D);
  _3 = _5 & 1024;
  _4 = value_2(D) ^ _3;
  return _4;

on GIMPLE here, compared to

  _1 = value_2(D) & 4294966271;
  _3 = _1 | 1024;
  return _3;

in the good case.  The latter looks more canonical to me but on GIMPLE
is also not optimized fully since it should be simply

  _1 = value_2(D) | 1024;
  return _1;

AFAICS.

Confirmed.  It should be straight-forward to add some match.pd rules
to catch both.

Reply via email to