> Am 09.09.2025 um 12:54 schrieb Juergen Christ <jchr...@linux.ibm.com>:
>
> The length returned by vect_get_loop_len is REALLEN + BIAS, but was
> assumed to be REALLEN - BIAS. If BIAS is -1, this leads to wrong
> code.
>
> Bootstrapped and regtested on s390. Ok for trunk?
Ok. Can you also test on ppc64le which IIRC uses different bias?
Thanks,
Richard
> gcc/ChangeLog:
>
> * tree-vect-loop.cc (vectorizable_live_operation_1): Fix
> load/store bias handling.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/vect/nodump-extractlast-1.c: New test.
>
> Signed-off-by: Juergen Christ <jchr...@linux.ibm.com>
> ---
> .../gcc.dg/vect/nodump-extractlast-1.c | 21 ++++++++++++++++++
> gcc/tree-vect-loop.cc | 22 ++++++++++---------
> 2 files changed, 33 insertions(+), 10 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/vect/nodump-extractlast-1.c
>
> diff --git a/gcc/testsuite/gcc.dg/vect/nodump-extractlast-1.c
> b/gcc/testsuite/gcc.dg/vect/nodump-extractlast-1.c
> new file mode 100644
> index 000000000000..980ac3e42188
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/nodump-extractlast-1.c
> @@ -0,0 +1,21 @@
> +/* Check for a bung in the treatment of LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS
> when
> + using VEC_EXTRACT. */
> +/* { dg-require-effective-target vect_int } */
> +
> +char c = 4;
> +
> +__attribute__((noipa))
> +int
> +foo ()
> +{
> + for ( ; c > 3; c -= 3);
> + return c - 1;
> +}
> +
> +int
> +main ()
> +{
> + if (foo() != 0)
> + __builtin_abort();
> + return 0;
> +}
> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index 3b56f865ec7c..78256904dcea 100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -10155,10 +10155,12 @@ vectorizable_live_operation_1 (loop_vec_info
> loop_vinfo, basic_block exit_bb,
> {
> /* Emit:
>
> - SCALAR_RES = VEC_EXTRACT <VEC_LHS, LEN + BIAS - 1>
> + SCALAR_RES = VEC_EXTRACT <VEC_LHS, LEN - (BIAS + 1)>
>
> - where VEC_LHS is the vectorized live-out result and MASK is
> - the loop mask for the final iteration. */
> + where VEC_LHS is the vectorized live-out result, LEN is the length of
> + the vector, BIAS is the load-store bias. The bias should not be used
> + at all since we are not using load/store operations, but LEN will be
> + REALLEN + BIAS, so subtract it to get to the correct position. */
> gcc_assert (SLP_TREE_LANES (slp_node) == 1);
> gimple_seq tem = NULL;
> gimple_stmt_iterator gsi = gsi_last (tem);
> @@ -10167,18 +10169,18 @@ vectorizable_live_operation_1 (loop_vec_info
> loop_vinfo, basic_block exit_bb,
> 1, vectype, 0, 1);
> gimple_seq_add_seq (&stmts, tem);
>
> - /* BIAS - 1. */
> + /* BIAS + 1. */
> signed char biasval = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo);
> - tree bias_minus_one
> - = int_const_binop (MINUS_EXPR,
> + tree bias_plus_one
> + = int_const_binop (PLUS_EXPR,
> build_int_cst (TREE_TYPE (len), biasval),
> build_one_cst (TREE_TYPE (len)));
>
> - /* LAST_INDEX = LEN + (BIAS - 1). */
> - tree last_index = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (len),
> - len, bias_minus_one);
> + /* LAST_INDEX = LEN - (BIAS + 1). */
> + tree last_index = gimple_build (&stmts, MINUS_EXPR, TREE_TYPE (len),
> + len, bias_plus_one);
>
> - /* SCALAR_RES = VEC_EXTRACT <VEC_LHS, LEN + BIAS - 1>. */
> + /* SCALAR_RES = VEC_EXTRACT <VEC_LHS, LEN - (BIAS + 1)>. */
> tree scalar_res
> = gimple_build (&stmts, CFN_VEC_EXTRACT, TREE_TYPE (vectype),
> vec_lhs_phi, last_index);
> --
> 2.43.7
>