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. > > >> >> > >> > 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 >> >
