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.