On Thu, 10 Sep 2026 at 6:55 AM, Andrea Pinski < [email protected]> wrote:
> On Wed, Sep 9, 2026 at 6:07 PM Shivam Gupta <[email protected]> > wrote: > > > > > > > > On Thu, 10 Sep 2026 at 6:32 AM, Andrea Pinski < > [email protected]> wrote: > >> > >> On Sun, Sep 6, 2026 at 6:07 PM Shivam Gupta <[email protected]> > wrote: > >> > > >> > is_rshift_by_1 previously checked TYPE_UNSIGNED on the shift > statement, > >> > preventing signed arithmetic right shifts from being optimized into > CLZ > >> > calls. However, an arithmetic right shift behaves identically to a > logical > >> > right shift when the initial operand entering the loop is > non-negative. > >> > > >> > This patch removes the strict TYPE_UNSIGNED requirement from > is_rshift_by_1 > >> > and adds ranger range_on_edge non-negativity checks in > number_of_iterations_cltz > >> > and number_of_iterations_cltz_complement on the loop preheader edge. > >> > >> > >> Ok. I forgot if you have write after approval access or not. > >> > > > > > > Thank you, I do not have write after approval access but it would be > nice to have someday. I plan to contribute to GCC in long term. > > Pushed as r17-4047-ge90e0f66051d338c1950d2cc9e36967552d75c3a. Will > come back to you on write after approval access though. > Awesome, thanks! > > > > > >> > >> > > >> > PR tree-optimization/125734 > >> > > >> > gcc/ChangeLog: > >> > > >> > * tree-ssa-loop-niter.cc (is_rshift_by_1): Remove > TYPE_UNSIGNED restriction. > >> > (number_of_iterations_cltz): Use range_on_edge to check > non-negativity of > >> > signed preheader input. > >> > (number_of_iterations_cltz_complement): Likewise. > >> > > >> > gcc/testsuite/ChangeLog: > >> > > >> > * gcc.dg/tree-ssa/pr125734.c: New test. > >> > > >> > Regression tested on arch64-unknown-linux-gnu. > >> > > >> > Signed-off-by: Shivam Gupta <[email protected]> > >> > --- > >> > gcc/testsuite/gcc.dg/tree-ssa/pr125734.c | 32 > ++++++++++++++++++++++++ > >> > gcc/tree-ssa-loop-niter.cc | 26 +++++++++++++++++-- > >> > 2 files changed, 56 insertions(+), 2 deletions(-) > >> > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr125734.c > >> > > >> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr125734.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr125734.c > >> > new file mode 100644 > >> > index 000000000..f8d76c459 > >> > --- /dev/null > >> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr125734.c > >> > @@ -0,0 +1,32 @@ > >> > +/* { dg-do compile } */ > >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > >> > + > >> > +int > >> > +nlz32 (int b) > >> > +{ > >> > + int c = sizeof(b) * 8; > >> > + if (b < 0) > >> > + return -1; > >> > + while (b != 0) > >> > + { > >> > + b >>= 1; > >> > + c--; > >> > + } > >> > + return c; > >> > +} > >> > + > >> > +int > >> > +nlz32_negative (int b) > >> > +{ > >> > + int c = sizeof(b) * 8; > >> > + > >> > + while (b != 0) > >> > + { > >> > + b >>= 1; > >> > + c--; > >> > + } > >> > + > >> > + return c; > >> > +} > >> > + > >> > +/* { dg-final { scan-tree-dump-times "\\.CLZ" 1 "optimized" } } */ > >> > diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc > >> > index 0c1ebd1c7..3ce3dccfa 100644 > >> > --- a/gcc/tree-ssa-loop-niter.cc > >> > +++ b/gcc/tree-ssa-loop-niter.cc > >> > @@ -2313,8 +2313,6 @@ is_lshift_by_1 (gassign *stmt) > >> > static bool > >> > is_rshift_by_1 (gassign *stmt) > >> > { > >> > - if (!TYPE_UNSIGNED (TREE_TYPE (gimple_assign_lhs (stmt)))) > >> > - return false; > >> > if (gimple_assign_rhs_code (stmt) == RSHIFT_EXPR > >> > && integer_onep (gimple_assign_rhs2 (stmt))) > >> > return true; > >> > @@ -2482,6 +2480,18 @@ number_of_iterations_cltz (loop_p loop, edge > exit, > >> > > >> > /* We found a match. */ > >> > tree src = gimple_phi_arg_def (phi, loop_preheader_edge > (loop)->dest_idx); > >> > + > >> > + /* If the type is signed, verify via Ranger on the preheader edge > >> > + that the initial value entering the loop is non-negative. */ > >> > + if (!TYPE_UNSIGNED (TREE_TYPE (src))) > >> > + { > >> > + int_range_max r (TREE_TYPE (src)); > >> > + edge e = loop_preheader_edge (loop); > >> > + if (!get_range_query (cfun)->range_on_edge (r, e, src) > >> > + || !r.nonnegative_p ()) > >> > + return false; > >> > + } > >> > + > >> > int src_precision = TYPE_PRECISION (TREE_TYPE (src)); > >> > > >> > /* Save the original SSA name before preprocessing for ranger > queries. */ > >> > @@ -2641,6 +2651,18 @@ number_of_iterations_cltz_complement (loop_p > loop, edge exit, > >> > > >> > /* We found a match. */ > >> > tree src = gimple_phi_arg_def (phi, loop_preheader_edge > (loop)->dest_idx); > >> > + > >> > + /* If the type is signed, verify via Ranger on the preheader edge > >> > + that the initial value entering the loop is non-negative. */ > >> > + if (!TYPE_UNSIGNED (TREE_TYPE (src))) > >> > + { > >> > + int_range_max r (TREE_TYPE (src)); > >> > + edge e = loop_preheader_edge (loop); > >> > + if (!get_range_query (cfun)->range_on_edge (r, e, src) > >> > + || !r.nonnegative_p ()) > >> > + return false; > >> > + } > >> > + > >> > int src_precision = TYPE_PRECISION (TREE_TYPE (src)); > >> > > >> > /* Get the corresponding c[lt]z builtin. */ > >> > -- > >> > 2.43.0 > >> > >
