>From cf6e4302cddd979315a58008e77f0c869280318c Mon Sep 17 00:00:00 2001
From: Kael Andrew Alonzo Franco <[email protected]>
Date: Tue, 7 Jul 2026 13:09:01 -0400
Subject: [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]>
---
 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(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr125738.c

diff --git a/gcc/match.pd b/gcc/match.pd
index a7cec25dbad..81c32b4a5a7 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3095,15 +3095,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 00000000000..4f675c0fc2a
--- /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 b694ec171c1..b9cd65ba8b8 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" } } */

-- 
2.55.0

Reply via email to