On Tue, May 19, 2026 at 4:26 AM Andrew Pinski <
[email protected]> wrote:

> On Mon, May 18, 2026 at 10:01 AM Shivam Gupta <[email protected]>
> wrote:
> >
> >
> >
> > On Mon, May 18, 2026 at 12:49 PM Andrew Pinski <
> [email protected]> wrote:
> >>
> >> On Mon, May 18, 2026 at 12:11 AM Shivam Gupta <[email protected]>
> wrote:
> >> >
> >> > This is a follow-up to the -O1 patch for PR112533.
> >> >
> >> > At -O2, GCC lowers (~x & 1) == (~y & 1) via inlining into:
> >> >   _14 = ~x;
> >> >   _12 = (bool) _14;
> >> >   _13 = ~y;
> >> >   _9  = (bool) _13;
> >> >   _8  = _9 == _12;
> >> >
> >> > The NOT cancellation (~x == ~y -> x == y) is handled by existing
> >> > forwprop rules before this rule fires.
> >> >
> >> > Add match.pd rule for eq and ne:
> >> >
> >> >   (T)(x) == (T)(y) -> (T)(x ^ y) == 0
> >> >   (T)(x) != (T)(y) -> (T)(x ^ y) != 0
> >> >
> >> > Bootstrapped and regression tested on aarch64-linux-gnu with
> >> > RUNTESTFLAGS="tree-ssa.exp".
> >> >
> >> > Changes since v1:
> >> > * v2: Generalize the match rule to generic narrowing
> >> >       integral equality comparisons from bool equality.
> >> >
> >> >         PR tree-optimization/112533
> >> >
> >> > gcc/ChangeLog:
> >> >         * match.pd: Add generic narrowing eq/ne to XOR-against-zero
> >> >         rule for (T)(x) == (T)(y) where precision(T) < precision(x).
> >> >
> >> > gcc/testsuite/ChangeLog:
> >> >         * gcc.dg/tree-ssa/narrow-eq-simplify.c: New test covering
> >> >         bool parity and short truncation cases.
> >> >
> >> > Signed-off-by: Shivam Gupta <[email protected]>
> >> > ---
> >> >  gcc/match.pd                                  | 16 +++++++
> >> >  .../gcc.dg/tree-ssa/narrow-eq-simplify.c      | 47
> +++++++++++++++++++
> >> >  2 files changed, 63 insertions(+)
> >> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/narrow-eq-simplify.c
> >> >
> >> > diff --git a/gcc/match.pd b/gcc/match.pd
> >> > index ff13a07ea94..1fcf28044ee 100644
> >> > --- a/gcc/match.pd
> >> > +++ b/gcc/match.pd
> >> > @@ -2033,6 +2033,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >> >        && element_precision (type) <= element_precision (TREE_TYPE
> (@1)))
> >> >    (bit_xor (convert @0) (convert @1))))
> >> >
> >> > +/* For narrowing conversations:
> >> > +   (T)(X) == (T)(Y) -> (T)(X ^ Y) == 0
> >> > +   (T)(X) != (T)(Y) -> (T)(X ^ Y) != 0  */
> >> > +(for cmp (eq ne)
> >> > + (simplify
> >> > +  (cmp (convert@0 @00) (convert@1 @10))
> >> > +  (if (INTEGRAL_TYPE_P (type)
> >> > +      && INTEGRAL_TYPE_P (TREE_TYPE (@00))
> >> > +      && types_match (@00, @10)
> >> > +      && types_match (@0, @1)
> >> > +      && TYPE_PRECISION (TREE_TYPE (@0))
> >> > +          < TYPE_PRECISION (TREE_TYPE (@00)))
> >> > +   (with { tree stype = TREE_TYPE (@0); }
> >> > +    (cmp (convert:stype (bit_xor @00 @10))
> >> > +         { build_zero_cst (stype); })))))
> >>
> >> You need to put this with the other ones that are already doing this
> >> pattern; otherwise this and the other ones won't work.  Also I don't
> >> think you need to match the types of @0 and @1 here.  Also
> >> INTEGRAL_TYPE_P (type) will be true for INTEGRAL_TYPE_P (TREE_TYPE
> >> (@00)).
> >>
> >> Also use itype rather than stype. s here usually stands for signed
> >> while i would stand for inner.
> >>
> >> Thanks,
> >> Andrea
> >>
> >
> > Hello,
> >
> > I browsed the match.pd file but I am not sure where else to put this.
> Rest comments are addressed in v3 of patch.
>
> See line 7738 and after that. It starts with:
> /* From fold_sign_changed_comparison and fold_widened_comparison.
>    FIXME: the lack of symmetry is disturbing.  */
>
> Note simple_comparison expands via
> (define_operator_list simple_comparison         lt   le   eq ne ge   gt)
>
> So with your v2/v3 there are 2 patterns which will match eq/ne and I
> don't think they will work together since they are almost exactly the
> same.
>
>
Thank you for the help.  Yes, It makes sense to move it there.

Thanks,
Shivam

Thanks,
> Andrea
>
>
> >
> > Thanks,
> > Shivam
> >
> >>
> >> > +
> >> >  /* Convert ~X ^ C to X ^ ~C.  */
> >> >  (simplify
> >> >   (bit_xor (convert? (bit_not @0)) INTEGER_CST@1)
> >> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/narrow-eq-simplify.c
> b/gcc/testsuite/gcc.dg/tree-ssa/narrow-eq-simplify.c
> >> > new file mode 100644
> >> > index 00000000000..8b03954719a
> >> > --- /dev/null
> >> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/narrow-eq-simplify.c
> >> > @@ -0,0 +1,47 @@
> >> > +/* { dg-do compile } */
> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> >> > +
> >> > +/* Verify the fix for PR112533 at -O2.
> >> > +   (~a & 1) == (~a & 1) is lowered via inlining to
> >> > +   (bool)(~a) == (bool)(~b), then existing forwprop rules cancel
> >> > +   the NOTs giving (bool)(a) == (bool)(b), which this rule
> >> > +   simplifies to (bool)(a ^ b) == 0.  */
> >> > +
> >> > +typedef unsigned int u32;
> >> > +
> >> > +static _Bool
> >> > +is_even (u32 a)
> >> > +{
> >> > +  return a % 2 == 0;
> >> > +}
> >> > +
> >> > +_Bool
> >> > +same_evenness (u32 a, u32 b)
> >> > +{
> >> > +  return is_even (a) == is_even (b);
> >> > +}
> >> > +
> >> > +_Bool
> >> > +diff_evenness (u32 a, u32 b)
> >> > +{
> >> > +  return is_even (a) != is_even (b);
> >> > +}
> >> > +
> >> > +short
> >> > +eq_short_not (int a, int b)
> >> > +{
> >> > +  short sa = ~a;
> >> > +  short sb = ~b;
> >> > +  return sa == sb;
> >> > +}
> >> > +
> >> > +short
> >> > +ne_short_not (int a, int b)
> >> > +{
> >> > +  short sa = ~a;
> >> > +  short sb = ~b;
> >> > +  return sa != sb;
> >> > +}
> >> > +
> >> > +/* Verify the XOR form is produced.  */
> >> > +/* { dg-final { scan-tree-dump-times "\\\^" 4 "optimized" } } */
> >> > --
> >> > 2.34.1
> >> >
>

Reply via email to