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.