On Sun, May 31, 2026 at 10:31 AM Andrew Pinski <
[email protected]> wrote:

> On Fri, May 29, 2026 at 10:36 AM Jeffrey Law <[email protected]>
> wrote:
> >
> >
> >
> >
> > On 5/29/2026 10:13 AM, Shivam Gupta wrote:
> > > Recognize XOR patterns involving zero_one_valued operands compared
> > > against zero and simplify them to direct equality or inequality tests.
> > >
> > > Specifically:
> > >
> > > (a == 0) ^ (b != 0)  -> a == b
> > > (a != 0) ^ (b == 0)  -> a == b
> > > (a == 0) ^ (b == 0)  -> a != b
> > > (a != 0) ^ (b != 0)  -> a != b
> > >
> > > Also handle a specific case:
> > > (a == 0) ^ b -> b != (a ^ 1)
> > >
> > > Regression tested on aarch64-linux-gnu.
> > >
> > > gcc/ChangeLog:
> > >       * match.pd: Add simplifications for XORs of zero_one_valued
> > >       comparisons against zero.
> > >
> > > gcc/testsuite/ChangeLog:
> > >       * gcc.dg/tree-ssa/bool-eq-bitxor.c: Update expected number
> > >       of optimized XOR forms.
> > >       * gcc.dg/tree-ssa/bool-xor-zero-one-valued.c: New test.
> > >
> > > Signed-off-by: Shivam Gupta <[email protected]>
> > So for the (a == 0) ^ b case, isn't the simplification for that just a
> > == b rather than b != (a ^ 1)?  If both are 0/1 valued, that works,
> right?
>
> Yes, for 0/1 values, `b != (a^1)` is the same as `a == b` and `a == b`
> is simpler in gimple so that should be used.
>
>
Yes, I agree that is simpler, but on aarch64,  `b != (a ^ 1)` form gives  -
eon w0, w0, w1
and x0, x0, 1
ret

while `a==b` form gives -
eor w0, w0, w1
ubfx x0, x0, 0, 1
eor w0, w0, 1
ret

>
> >
> >
> >
> > > +
> > > +/* For zero_one_valued operands:
> > > +     (a == 0) != (b != 0)  -> a == b
> > > +     (a != 0) != (b == 0)  -> a == b.  */
> > > +(for op1 (eq ne)
> > > +     op2 (ne eq)
> > > + (simplify
> > > +  (ne:c (op1 zero_one_valued_p@0 integer_zerop)
> > > +        (op2 zero_one_valued_p@1 integer_zerop))
> > > +  (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1)))
> > > +   (eq @0 @1))))
> > Do you want to handle an outer EQ here in addition to handling the outer
> > NE?  I think it just inverts the resulting code, right? SImilarly for
> > the other pattern.
>
> Yes I think we should handle an outer ne/eq here too.
>
>
I only kept outer ne since xor is producing that. However we can also add
outer eq for symmetry.

>
> >
> > Do we need conversions on @0 and @1?  In particular a conditional
> > conversion convert?  And if we do that, do we need to adjust the
> > types_match conditional?
>
> I did mention that in my review of the other patch where I suggested
> this one being separate that we should use a convert here.
>
>
Sorry, I missed that in this patch.  However I see with v1 it is -
cmp w0, w1
cset w0, eq
ret

but with v2 by using convert, it is -
and w0, w0, 1
and w1, w1, 1
cmp w0, w1
cset w0, eq
ret

Thanks,
Shivam


> Thanks,
> Andrea
>
>
> >
> > match.pd isn't my area of speciality, so if Andrew or Richard suggest
> > something different, their review matters more than mine.
> >
> > jeff
>

Reply via email to