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 > >> > >
