[gcc r17-2312] [PATCH] match: Use tree_expr_nonnegative_p for (X / Y) (==, !=) 0 -> X (<, >=) Y [PR125738]

Jeff Law via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:1df48a01e07e30592e0119232b1aaf3d41be03f4

commit r17-2312-g1df48a01e07e30592e0119232b1aaf3d41be03f4
Author: Kael Andrew Franco <[email protected]>
Date:   Fri Jul 10 08:28:13 2026 -0600

    [PATCH] match: Use tree_expr_nonnegative_p for (X / Y) (==, !=) 0 -> X (<,>=) Y [PR125738]
    
    TYPE_UNSIGNED did not cover non-negative X and Y so use tree_expr_nonnegative_p
    to relax condition on optimizations.
    gcc/testsuite/gcc.dg/tree-ssa/pr64130.c fails because match.pd optimize funsigned () before
    evrp pass. Fix this by removing funsigned () and one scan-tree-dump.
    
    Bootstrapped and tested on x86_64-pc-linux-gnu.
    
            PR tree-optimization/125738
            PR tree-optimization/64130
    
    gcc/ChangeLog:
    
            * match.pd: Use tree_expr_nonnegative_p for (X / Y) (==,!=) 0 -> X (<,>=) Y.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/pr125738.c: New test.
            * gcc.dg/tree-ssa/pr64130.c: Remove scan-tree-dump [2, 8589934591].
            (funsigned): Remove.
            (funsigned2): Rename to funsigned.
    
    Signed-off-by: Kael Franco <[email protected]>

Diff:
---
 gcc/match.pd                            |  9 ++++-----
 gcc/testsuite/gcc.dg/pr125738.c         | 22 ++++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr64130.c |  6 ------
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 39328818f0e7..96156fe564f4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3102,15 +3102,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (op @1 { build_zero_cst (TREE_TYPE (@1)); }))))
 
 /* Transform:
-   (X / Y) == 0 -> X < Y if X, Y are unsigned.
-   (X / Y) != 0 -> X >= Y, if X, Y are unsigned.  */
+   (X / Y) == 0 -> X < Y if X, Y are non-negative.
+   (X / Y) != 0 -> X >= Y, if X, Y are non-negative.  */
 (for cmp (eq ne)
      ocmp (lt ge)
  (simplify
-  (cmp (trunc_div @0 @1) integer_zerop)
-  (if (TYPE_UNSIGNED (TREE_TYPE (@0))
+  (cmp (trunc_div tree_expr_nonnegative_p@0 tree_expr_nonnegative_p@1) integer_zerop)
        /* Complex ==/!= is allowed, but not </>=.  */
-       && TREE_CODE (TREE_TYPE (@0)) != COMPLEX_TYPE
+  (if (TREE_CODE (TREE_TYPE (@0)) != COMPLEX_TYPE
        && (VECTOR_TYPE_P (type) || !VECTOR_TYPE_P (TREE_TYPE (@0))))
    (ocmp @0 @1))))
 
diff --git a/gcc/testsuite/gcc.dg/pr125738.c b/gcc/testsuite/gcc.dg/pr125738.c
new file mode 100644
index 000000000000..4f675c0fc2a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr125738.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+aa_div_bb_eq_0 (unsigned short a, unsigned short b)
+{
+  int aa = a;
+  int bb = b;
+  int c = aa / bb;
+  return (c == 0) == (a < b);
+}
+
+int
+aa_div_bb_ne_0 (unsigned short a, unsigned short b)
+{
+  int aa = a;
+  int bb = b;
+  int c = aa / bb;
+  return (c != 0) == (a >= b);
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c b/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c
index b694ec171c15..b9cd65ba8b82 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c
@@ -4,16 +4,10 @@
 __extension__ typedef __UINT32_TYPE__ uint32_t;
 
 int funsigned (uint32_t a)
-{
-  return 0x1ffffffffL / a == 0;
-}
-
-int funsigned2 (uint32_t a)
 {
   if (a < 1) return 1;
   return (-1 * 0x1ffffffffL) / a == 0;
 }
 
-/* { dg-final { scan-tree-dump "int \\\[2, 8589934591\\\]" "evrp" } } */
 /* { dg-final { scan-tree-dump "int \\\[-8589934591, -2\\\]" "evrp" } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.