On Wed, Nov 11, 2026 at 4:23 PM Robin Dapp <[email protected]> wrote:
>
> From: Robin Dapp <[email protected]>
>
> This patch wants to change gather/scatter costing to use
> vect_gather_load and vect_scatter_store instead of n
> scalar_loads/stores. As far as I can tell, we haven't been using
> vector_gather_load/scatter_store in a while because the
>
> if ((kind == vector_load || kind == unaligned_load)
> && (stmt_info && STMT_VINFO_GATHER_SCATTER_P (stmt_info)))
>
> guard wouldn't fire with kind = scalar_load.
>
> Therefore, the patch removes it and passes the appropriate cost kind
> directly, as well as the proper, potentially punned vectype.
>
> Targets need to look at the vectype in order to determine the number of
> gather/scatter elements now where they could rely on "count" before.
>
> I had to adjust one x86 test case that expected vectorization with
> gather. But haswell's gather costs are high at 44 and the "wrong"
> scalar load costs before didn't inhibit vectorization in the same way.
> I tried measuring a comparable test case on my x86 laptop and declining
> to vectorize (i.e. gather is expensive) seems the right call, at least on my
> machine.
Hmm, so the "idea" was that we'd move towards overloading
vector_costs::add_slp_cost (x86 does, handling one specific case)
so as to get all "components" of the overall operation that you could
then classify on. That the components use scalar_load/store would
be of secondary concern.
Would that achieve a similar result and maybe improve handling of
gather/scatter costing for you?
Richard.
> gcc/ChangeLog:
>
> * targhooks.cc (default_builtin_vectorization_cost): Use vector
> subparts as cost estimate.
> * tree-vect-stmts.cc (record_stmt_cost): Don't override cost
> kind.
> (vectorizable_store): Pass vector_scatter_store cost kind.
> (vectorizable_load): Pass vector_gather_load cost kind.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/avx512vl-pr88464-11.c: Use no vect cost model.
> ---
> gcc/targhooks.cc | 4 +++
> .../gcc.target/i386/avx512vl-pr88464-11.c | 2 +-
> gcc/tree-vect-stmts.cc | 27 ++++++-------------
> 3 files changed, 13 insertions(+), 20 deletions(-)
>
> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> index 88582e4fa51..57f9cefd3a1 100644
> --- a/gcc/targhooks.cc
> +++ b/gcc/targhooks.cc
> @@ -779,6 +779,10 @@ default_builtin_vectorization_cost (enum
> vect_cost_for_stmt type_of_cost,
> case vec_deconstruct:
> return estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype)) - 1;
>
> + case vector_gather_load:
> + case vector_scatter_store:
> + return estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype));
> +
> default:
> gcc_unreachable ();
> }
> diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-pr88464-11.c
> b/gcc/testsuite/gcc.target/i386/avx512vl-pr88464-11.c
> index 3a98108279a..7ade00d2a19 100644
> --- a/gcc/testsuite/gcc.target/i386/avx512vl-pr88464-11.c
> +++ b/gcc/testsuite/gcc.target/i386/avx512vl-pr88464-11.c
> @@ -1,6 +1,6 @@
> /* PR tree-optimization/88464 */
> /* { dg-do compile } */
> -/* { dg-options "-O3 -mavx512vl -mprefer-vector-width=128 -mtune=haswell
> -fdump-tree-vect-details" } */
> +/* { dg-options "-O3 -mavx512vl -mprefer-vector-width=128 -mtune=haswell
> -fvect-cost-model=unlimited -fdump-tree-vect-details" } */
> /* { dg-final { scan-tree-dump-times "loop vectorized using 16 byte vectors"
> 4 "vect" } } */
> /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 4
> "vect" } } */
>
> diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
> index 7a4596c337c..0e73b02e356 100644
> --- a/gcc/tree-vect-stmts.cc
> +++ b/gcc/tree-vect-stmts.cc
> @@ -95,13 +95,6 @@ record_stmt_cost (stmt_vector_for_cost *body_cost_vec, int
> count,
> tree vectype, int misalign,
> enum vect_cost_model_location where)
> {
> - if ((kind == vector_load || kind == unaligned_load)
> - && (stmt_info && STMT_VINFO_GATHER_SCATTER_P (stmt_info)))
> - kind = vector_gather_load;
> - if ((kind == vector_store || kind == unaligned_store)
> - && (stmt_info && STMT_VINFO_GATHER_SCATTER_P (stmt_info)))
> - kind = vector_scatter_store;
> -
> stmt_info_for_cost si
> = { count, kind, where, stmt_info, node, vectype, misalign };
> body_cost_vec->safe_push (si);
> @@ -9073,10 +9066,9 @@ vectorizable_store (vec_info *vinfo,
> += record_stmt_cost (cost_vec, 1, vector_stmt,
> slp_node, 0, vect_body);
>
> - unsigned int cnunits = vect_nunits_for_cost (vectype);
> inside_cost
> - += record_stmt_cost (cost_vec, cnunits, scalar_store,
> - slp_node, 0, vect_body);
> + += record_stmt_cost (cost_vec, 1, vector_scatter_store,
> + slp_node, vectype, 0, vect_body);
> continue;
> }
>
> @@ -9189,10 +9181,9 @@ vectorizable_store (vec_info *vinfo,
> (TYPE_MODE (TREE_TYPE (final_mask)))));
> if (costing_p)
> {
> - unsigned int cnunits = vect_nunits_for_cost (vectype);
> inside_cost
> - += record_stmt_cost (cost_vec, cnunits, scalar_store,
> - slp_node, 0, vect_body);
> + += record_stmt_cost (cost_vec, 1, vector_scatter_store,
> + slp_node, vectype, 0, vect_body);
> continue;
> }
>
> @@ -11077,10 +11068,9 @@ vectorizable_load (vec_info *vinfo,
> += record_stmt_cost (cost_vec, 1, vector_stmt,
> slp_node, 0, vect_body);
>
> - unsigned int cnunits = vect_nunits_for_cost (vectype);
> inside_cost
> - = record_stmt_cost (cost_vec, cnunits, scalar_load,
> - slp_node, 0, vect_body);
> + += record_stmt_cost (cost_vec, 1, vector_gather_load,
> + slp_node, vectype, 0, vect_body);
> continue;
> }
> if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
> @@ -11183,10 +11173,9 @@ vectorizable_load (vec_info *vinfo,
> gcc_assert (!final_len && nunits.is_constant ());
> if (costing_p)
> {
> - unsigned int cnunits = vect_nunits_for_cost (vectype);
> inside_cost
> - = record_stmt_cost (cost_vec, cnunits, scalar_load,
> - slp_node, 0, vect_body);
> + += record_stmt_cost (cost_vec, 1, vector_gather_load,
> + slp_node, vectype, 0, vect_body);
> continue;
> }
> tree offset_vectype = TREE_TYPE (vec_offsets[0]);
> --
> 2.56.0
>