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

Reply via email to