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

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
#define shift 4

        return ((mask(d) == (0x0 << shift)) ||
                (mask(d) == (0x1 << shift)) ||
                (mask(d) == (0x2 << shift)));

static inline unsigned mask(const struct dentry *dentry)
{
        return dentry->d_flags & (0x7 << shift);
}



ifcombine does:
  _4 = _5 & 112; // this was already there.
  _8 = _4 == 16;
  _7 = _4 == 0;
  _9 = _7 | _8;
  _10 = _4 == 32;
  _11 = _9 | _10;

Which is correct.

reassoc1 does:

  _4 = _5 & 112;
  _8 = _4 == 16;
  _1 = _4 & 4294967279; // -17 or ~16
  _13 = _1 == 0;
  _7 = _4 == 0;
  _10 = _4 == 32;
  _11 = _10 | _13;

and that is where it messes up, it misses reassocation of all three ands
together. And _4 & 4294967279 removes bit 7 from the original and.


Final output:
  _4 = _5 & 112; // 0b1110000
  _1 = _5 & 96;  // 0b1100000
  _13 = _1 == 0; // 0b0000000
  _10 = _4 == 32;// 0b0100000
  _11 = _10 | _13;

So we need have another pattern for something like this:
(bit_ior
 (cmp (bit_and @0 INTEGER_CST@2) INTEGER_CST@3)
 (cmp (bit_and @0 INTEGER_CST@4) INTEGER_CST@5))

And maybe even one like this (which will solve the issue sooner):

(bit_ior
 (cmp (bit_and @0 INTEGER_CST@2) INTEGER_CST@3)
 (cmp @0 INTEGER_CST@5)))

Reply via email to