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" } } */
