On Sat, Jun 27, 2026 at 4:41 PM Kael Andrew Franco <[email protected]> wrote: > > From 2d32835deaddd35fc1e35a456f9dc249e797ef83 Mon Sep 17 00:00:00 2001 > From: Kael Andrew Alonzo Franco <[email protected]> > Date: Sat, 27 Jun 2026 17:56:29 -0400 > Subject: [PATCH] match: Use tree_expr_nonnegative_p instead of TYPE_UNSIGNED > for MAX (A, B) (==,!=) 0 -> (A|B) (==,!=) 0 [PR125749] > > tree_expr_nonnegative_p covers non negative signed type variables, unlike > TYPE_UNSIGNED. > > Bootstrapped and tested on x86_64-pc-linux-gnu
Ok and pushed with a small wraparound fix in the changelog. https://gcc.gnu.org/pipermail/gcc-cvs/2026-June/456420.html Thanks, Andrea > > PR tree-optimization/125749 > > gcc/ChangeLog: > > PR tree-optimization/125749 > * match.pd: Use tree_expr_nonnegative_p for MAX (A, B) (==,!=) 0 -> (A|B) > (==,!=) 0. > > gcc/testsuite/ChangeLog: > > PR tree-optimization/125749 > * gcc.dg/pr125749.c: New test. > > Signed-off-by: Kael Franco <[email protected]> > --- > gcc/match.pd | 13 ++++++------- > gcc/testsuite/gcc.dg/pr125749.c | 20 ++++++++++++++++++++ > 2 files changed, 26 insertions(+), 7 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/pr125749.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index 62f191cefba..c8d274388b3 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -4738,15 +4738,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (cmp (minmax @0 INTEGER_CST@1) INTEGER_CST@2) > (comb (cmp @0 @2) (cmp @1 @2)))) > > -/* MAX (A, B) == 0 -> (A|B) == 0 iff unsigned. > - MAX (A, B) != 0 -> (A|B) != 0 iff unsigned. */ > +/* MAX (A, B) == 0 -> (A|B) == 0 iff non-negative. > + MAX (A, B) != 0 -> (A|B) != 0 iff non-negative. */ > (for cmp (eq ne) > (simplify > - (cmp (max @0 @1) integer_zerop) > - (if (TYPE_UNSIGNED (TREE_TYPE (@0))) > - (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); } > - (cmp (bit_ior (convert:utype @0) (convert:utype @1)) > - { build_zero_cst (utype); } ))))) > + (cmp (max tree_expr_nonnegative_p@0 tree_expr_nonnegative_p@1) > integer_zerop) > + (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); } > + (cmp (bit_ior (convert:utype @0) (convert:utype @1)) > + { build_zero_cst (utype); } )))) > > /* Undo fancy ways of writing max/min or other ?: expressions, like > a - ((a - b) & -(a < b)) and a - (a - b) * (a < b) into (a < b) ? b : a. > diff --git a/gcc/testsuite/gcc.dg/pr125749.c b/gcc/testsuite/gcc.dg/pr125749.c > new file mode 100644 > index 00000000000..cf0fc1e8675 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr125749.c > @@ -0,0 +1,20 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > + > +_Bool > +max_eq_zero (unsigned short a, unsigned short b) { > + int aa = a; > + int bb = b; > + int t = aa > bb ? aa : bb; > + return (t == 0) == ((a | b) == 0); > +} > + > +_Bool > +max_ne_zero (unsigned short a, unsigned short b) { > + int aa = a; > + int bb = b; > + int t = aa > bb ? aa : bb; > + return (t != 0) == ((a | b) != 0); > +} > + > +/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */ > -- > 2.54.0 > >
