On Wed, Aug 2, 2023 at 1:25 AM Jakub Jelinek via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On Wed, Aug 02, 2023 at 10:04:26AM +0200, Richard Biener via Gcc-patches > wrote: > > > --- a/gcc/match.pd > > > +++ b/gcc/match.pd > > > @@ -1157,8 +1157,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > > > > > /* Simplify ~X & X as zero. */ > > > (simplify > > > - (bit_and:c (convert? @0) (convert? (bit_not @0))) > > > - { build_zero_cst (type); }) > > > + (bit_and (convert? @0) (convert? @1)) > > > + (if (bitwise_inverted_equal_p (@0, @1)) > > > + { build_zero_cst (type); })) > > I wonder if the above isn't incorrect. > Without the possibility of widening converts it would be ok, > but for widening conversions it is significant not just that > the bits of @0 and @1 are inverted, but also that they are either > both signed or both unsigned and so the MS bit (which is guaranteed > to be different) extends to 0s in one case and to all 1s in the other > one, so that even the upper bits are inverted. > But that isn't the case here. Something like (untested): > long long > foo (unsigned int x) > { > int y = x; > y = ~y; > return ((long long) x) & y; > } > Actually maybe for this pattern it happens to be ok, because while > the upper bits in this case might not be inverted between the extended > operands (if x has msb set), it will be 0 & 0 in the upper bits. > > > > > > > /* PR71636: Transform x & ((1U << b) - 1) -> x & ~(~0U << b); */ > > > (simplify > > > @@ -1395,8 +1396,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > > /* ~x ^ x -> -1 */ > > > (for op (bit_ior bit_xor) > > > (simplify > > > - (op:c (convert? @0) (convert? (bit_not @0))) > > > - (convert { build_all_ones_cst (TREE_TYPE (@0)); }))) > > > + (op (convert? @0) (convert? @1)) > > > + (if (bitwise_inverted_equal_p (@0, @1)) > > > + (convert { build_all_ones_cst (TREE_TYPE (@0)); })))) > > But not here. > long long > bar (unsigned int x) > { > int y = x; > y = ~y; > return ((long long) x) ^ y; > } > > long long > baz (unsigned int x) > { > int y = x; > y = ~y; > return y ^ ((long long) x); > } > You pick TREE_TYPE (@0), but that is a random signedness if the two > operands have different signedness.
Oh you are correct, I am testing a patch which adds the test to make sure the types of @0 and @1 match which brings us back to basically was done beforehand and still provides the benefit of using bitwise_inverted_equal_p for the comparisons. Thanks, Andrew > > Jakub >