https://gcc.gnu.org/g:61b702d88c8e55affc2bdbd4fee0187a0d72e397

commit r17-1938-g61b702d88c8e55affc2bdbd4fee0187a0d72e397
Author: Kael Andrew Alonzo Franco <[email protected]>
Date:   Sat Jun 27 17:56:29 2026 -0400

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

Diff:
---
 gcc/match.pd                    | 13 ++++++-------
 gcc/testsuite/gcc.dg/pr125749.c | 20 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 62f191cefba0..c8d274388b38 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 000000000000..cf0fc1e86751
--- /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" } } */

Reply via email to