[PING][PATCH] match: 1 / X -> X == 1 for positive X [PR125735]
Kael Andrew Franco <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CACAb0qdXjezi+RiiHzeN+y0DLSbBqfz9k7t=rBn-58_C2PxLDg@mail.gmail.com> |
Ping of https://gcc.gnu.org/pipermail/gcc-patches/2026-July/724387.html. Updated patch still works: From a8dad89050597f075c197bba9b0da2703277671e Mon Sep 17 00:00:00 2001 From: Kael Andrew Alonzo Franco <[email protected]> Date: Thu, 30 Jul 2026 21:59:35 -0400 Subject: [PATCH] match: 1 / X -> X == 1 for positive X [PR125735] TYPE_UNSIGNED (type) doesn't cover positive signed types and tree_expr_nonnegative_p () doesn't work so use vr0.nonnegative_p (). Bootstrapped and tested on x86_64-pc-linux-gnu. PR tree-optimization/125735 gcc/ChangeLog: * match.pd: 1 / X -> X == 1 for positive X. [PR125735] gcc/testsuite/ChangeLog: * gcc.dg/pr125735.c: New test. Signed-off-by: Kael Andrew Franco <[email protected]> --- gcc/match.pd | 19 +++++++++++++++---- gcc/testsuite/gcc.dg/pr125735.c | 11 +++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr125735.c diff --git a/gcc/match.pd b/gcc/match.pd index dd223dc4553..9c022224bc5 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -628,8 +628,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && TYPE_UNSIGNED (type)) (trunc_divmod @0 @1)))) -/* 1 / X -> X == 1 for unsigned integer X. - 1 / X -> X >= -1 && X <= 1 ? X : 0 for signed integer X. +/* 1 / X -> X == 1 for positive integer X. + 1 / X -> X >= -1 && X <= 1 ? X : 0 for when X could be negative. But not for 1 / 0 so that we can get proper warnings and errors, and not for 1-bit integers as they are edge cases better handled elsewhere. Delay the conversion of the signed division until late @@ -640,13 +640,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && TYPE_PRECISION (type) > 1 && !integer_zerop (@1) && (!flag_non_call_exceptions || tree_expr_nonzero_p (@1))) - (if (TYPE_UNSIGNED (type)) + (with { + bool positive_p = TYPE_UNSIGNED (type); +#if GIMPLE + int_range_max vr0; + wide_int lower_bnd; + if (!positive_p + && gimple_match_range_of_expr (vr0, @1) + && vr0.nonnegative_p ()) + positive_p = true; +#endif + } + (if (positive_p) (convert (eq:boolean_type_node @1 @0)) (if (fold_before_rtl_expansion_p ()) (with { tree utype = unsigned_type_for (type); } (cond (le (plus (convert:utype @1) { build_one_cst (utype); }) { build_int_cst (utype, 2); }) - @1 { build_zero_cst (type); })))))) + @1 { build_zero_cst (type); }))))))) /* Combine two successive divisions. Note that combining ceil_div and floor_div is trickier and combining round_div even more so. */ diff --git a/gcc/testsuite/gcc.dg/pr125735.c b/gcc/testsuite/gcc.dg/pr125735.c new file mode 100644 index 00000000000..b94d95c0de7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr125735.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +_Bool +one_div_positive (int b) +{ + if (b < 1) return 0; + return (1 / b); +} + +/* { dg-final { scan-tree-dump "b_\[0-9\]+.D. == 1" "optimized" } } */ -- 2.55.0