>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