On Mon, Sep 7, 2026 at 3:07 AM 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.
>
>         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 ())

I think you need to fend off r.undefined_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
>

Reply via email to