On Wed, Jan 21, 2026 at 3:12 PM Victor Do Nascimento
<[email protected]> wrote:
>
> Given the inability of `expr_invariant_in_loop_p (loop, expr)' to
> handle the `scev_not_known' node as the expression, an unknown loop
> bound in the inner loop in a nested set of loops led to
> `vect_analyze_loop_form' to erroneously consider the outer loop as
> suitable for vectorization.  This introduces the necessary unknown
> loop iteration count check to ensure correct handling of counted loops
> with an embedded uncounted loop.
>
> Bootstrapped on AArch64 and x86_64, no regressions.
>
> gcc/ChangeLog:
>
>         PR tree-optimization/123657
>         * tree-vect-loop.cc (vect_analyze_loop_form): Add
>         chrec_dont_know check.
>         * tree-ssa-loop-ivopts.cc (expr_invariant_in_loop_p):
>         likewise.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/vect/vect-uncounted-run_4.c (main): New.
> ---
>  .../gcc.dg/vect/vect-uncounted-run_4.c          | 17 +++++++++++++++++
>  gcc/tree-ssa-loop-ivopts.cc                     |  4 ++++
>  gcc/tree-vect-loop.cc                           |  3 ++-
>  3 files changed, 23 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/vect/vect-uncounted-run_4.c
>
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-uncounted-run_4.c 
> b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run_4.c
> new file mode 100644
> index 00000000000..f731daf42d9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-uncounted-run_4.c
> @@ -0,0 +1,17 @@
> +/* Ensure we don't vectorize outer loops when the inner loop is uncounted.  
> */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-require-effective-target vect_early_break_hw } */
> +/* { dg-require-effective-target vect_int } */
> +/* { dg-additional-options "-O3" } */
> +
> +int a;
> +int main() {
> +  for (int b = 0; b < 21; b++) {
> +    int c = b;
> +    while (c)
> +      a = c >>= 1;
> +  }
> +  if (a != 0) __builtin_abort();
> +}
> +
> +/* { dg-final { scan-tree-dump "missed:   not vectorized: inner-loop count 
> not invariant." "vect" } } */
> diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
> index 6ecf5bef7b4..62df570003d 100644
> --- a/gcc/tree-ssa-loop-ivopts.cc
> +++ b/gcc/tree-ssa-loop-ivopts.cc
> @@ -1825,6 +1825,10 @@ expr_invariant_in_loop_p (class loop *loop, tree expr)
>
>    gcc_assert (loop_depth (loop) > 0);
>
> +  /* CHREC_DONT_KNOW treated as invariant and thus, if not checked,
> +     misleadingly returns TRUE.  */
> +  gcc_assert (expr != chrec_dont_know);
> +

I don't like this assert much.  Instead ...

>    if (is_gimple_min_invariant (expr))
>      return true;

..
 if (!EXPR_P (expr))
    return false;
...

/* Node used for describing a property that is known at compile
   time.  */
DEFTREECODE (SCEV_KNOWN, "scev_known", tcc_expression, 0)

/* Node used for describing a property that is not known at compile
   time.  */
DEFTREECODE (SCEV_NOT_KNOWN, "scev_not_known", tcc_expression, 0)

these should probably have been tcc_exceptional, but please just
check && !automatically_generated_chrec_p (expr) there.

Or simply drop the hunk.  The other hunk is OK.

Thanks,
Richard.


> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index 03339641750..9d6963a26fe 100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -1555,7 +1555,8 @@ vect_analyze_loop_form (class loop *loop, gimple 
> *loop_vectorized_call,
>         return opt_result::failure_at (vect_location,
>                                        "not vectorized: Bad inner loop.\n");
>
> -      if (!expr_invariant_in_loop_p (loop, inner.number_of_iterations))
> +      if (inner.number_of_iterations ==  chrec_dont_know
> +         || !expr_invariant_in_loop_p (loop, inner.number_of_iterations))
>         return opt_result::failure_at (vect_location,
>                                        "not vectorized: inner-loop count not"
>                                        " invariant.\n");
> --
> 2.43.0
>

Reply via email to