[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 || (x & 0x70) == 0x10 || (x & 0x70) == 0x20) on x86_64

2021-06-04 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073

--- Comment #6 from Andrew Pinski  ---
#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; // 0b111
  _1 = _5 & 96;  // 0b110
  _13 = _1 == 0; // 0b000
  _10 = _4 == 32;// 0b010
  _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)))

[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 || (x & 0x70) == 0x10 || (x & 0x70) == 0x20) on x86_64

2016-07-27 Thread dhowells at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073

--- Comment #5 from dhowells at redhat dot com  ---
There's a further potential optimisation.  If shift is large enough that the
bits under test are outside of the LSB, the TESTB changes to a TESTL at the
same address:

Shift 2:

   0:   f6 07 1ctestb  $0x1c,(%rdi)
   3:   0f 94 c0sete   %al
   6:   c3  retq   

Shift 10:

   0:   f7 07 00 1c 00 00   testl  $0x1c00,(%rdi)
   6:   0f 94 c0sete   %al
   9:   c3  retq   

Shift 18:

   0:   f7 07 00 00 1c 00   testl  $0x1c,(%rdi)
   6:   0f 94 c0sete   %al
   9:   c3  retq   

However, one could do a TESTW or a TESTB instead with a smaller immediate value
and a displaced address.

[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 || (x & 0x70) == 0x10 || (x & 0x70) == 0x20) on x86_64

2016-07-27 Thread dhowells at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073

--- Comment #4 from dhowells at redhat dot com  ---
(In reply to Andrew Pinski from comment #2)
> ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20)
> 
> Should be false always.  I suspect you had meant || rather than &&.

Sorry, yes; I got the examples right, but the bz subject wrong.  I've fixed
that.

[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) on x86_64

2016-07-27 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073

Andrew Pinski  changed:

   What|Removed |Added

   Severity|normal  |enhancement

[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) on x86_64

2016-07-27 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073

Andrew Pinski  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2016-07-27
 Ever confirmed|0   |1
   Severity|enhancement |normal

--- Comment #3 from Andrew Pinski  ---
Confirmed with any shift >= 1.  Shift of 0 works :).

[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) on x86_64

2016-07-27 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073

--- Comment #2 from Andrew Pinski  ---
((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20)

Should be false always.  I suspect you had meant || rather than &&.

[Bug tree-optimization/58073] Suboptimal optimisation of ((x & 0x70) == 0x00 && (x & 0x70) == 0x10 && (x & 0x70) == 0x20) on x86_64

2016-07-27 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58073

Andrew Pinski  changed:

   What|Removed |Added

   Severity|normal  |enhancement