On Fri, Jul 11, 2025 at 11:03 AM Robin Dapp <rdapp....@gmail.com> wrote: > > This encapsulates the IFN and the builtin-function way of handling > gather/scatter via three defines: > > GATHER_SCATTER_IFN_P > GATHER_SCATTER_LEGACY_P > GATHER_SCATTER_EMULATED_P > > and introduces a helper define for SLP operand handling as well.
OK. > gcc/ChangeLog: > > * tree-vect-slp.cc (GATHER_SCATTER_OFFSET): New define. > (vect_get_and_check_slp_defs): Use. > * tree-vectorizer.h (GATHER_SCATTER_LEGACY_P): New define. > (GATHER_SCATTER_IFN_P): Ditto. > (GATHER_SCATTER_EMULATED_P): Ditto. > * tree-vect-stmts.cc (vectorizable_store): Use. > (vectorizable_load): Use. > --- > gcc/tree-vect-slp.cc | 12 +++++++----- > gcc/tree-vect-stmts.cc | 19 +++++++++---------- > gcc/tree-vectorizer.h | 8 ++++++++ > 3 files changed, 24 insertions(+), 15 deletions(-) > > diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc > index ad75386926a..0c95ed946bb 100644 > --- a/gcc/tree-vect-slp.cc > +++ b/gcc/tree-vect-slp.cc > @@ -507,6 +507,8 @@ vect_def_types_match (enum vect_def_type dta, enum > vect_def_type dtb) > && (dtb == vect_external_def || dtb == vect_constant_def))); > } > > +#define GATHER_SCATTER_OFFSET (-3) > + > static const int no_arg_map[] = { 0 }; > static const int arg0_map[] = { 1, 0 }; > static const int arg1_map[] = { 1, 1 }; > @@ -516,10 +518,10 @@ static const int arg1_arg4_arg5_map[] = { 3, 1, 4, 5 }; > static const int arg1_arg3_arg4_map[] = { 3, 1, 3, 4 }; > static const int arg3_arg2_map[] = { 2, 3, 2 }; > static const int op1_op0_map[] = { 2, 1, 0 }; > -static const int off_map[] = { 1, -3 }; > -static const int off_op0_map[] = { 2, -3, 0 }; > -static const int off_arg2_arg3_map[] = { 3, -3, 2, 3 }; > -static const int off_arg3_arg2_map[] = { 3, -3, 3, 2 }; > +static const int off_map[] = { 1, GATHER_SCATTER_OFFSET }; > +static const int off_op0_map[] = { 2, GATHER_SCATTER_OFFSET, 0 }; > +static const int off_arg2_arg3_map[] = { 3, GATHER_SCATTER_OFFSET, 2, 3 }; > +static const int off_arg3_arg2_map[] = { 3, GATHER_SCATTER_OFFSET, 3, 2 }; > static const int mask_call_maps[6][7] = { > { 1, 1, }, > { 2, 1, 2, }, > @@ -691,7 +693,7 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned > char swap, > { > oprnd_info = (*oprnds_info)[i]; > int opno = map ? map[i] : int (i); > - if (opno == -3) > + if (opno == GATHER_SCATTER_OFFSET) > { > gcc_assert (STMT_VINFO_GATHER_SCATTER_P (stmt_info)); > if (!is_a <loop_vec_info> (vinfo) > diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc > index 4aa69da2218..57942f43c3b 100644 > --- a/gcc/tree-vect-stmts.cc > +++ b/gcc/tree-vect-stmts.cc > @@ -2455,7 +2455,7 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info > stmt_info, > If that failed for some reason (e.g. because another pattern > took priority), just handle cases in which the offset already > has the right type. */ > - else if (gs_info->ifn != IFN_LAST > + else if (GATHER_SCATTER_IFN_P (*gs_info) > && !is_gimple_call (stmt_info->stmt) > && !tree_nop_conversion_p (TREE_TYPE (gs_info->offset), > TREE_TYPE > (gs_info->offset_vectype))) > @@ -8368,7 +8368,8 @@ vectorizable_store (vec_info *vinfo, > } > else if (memory_access_type != VMAT_LOAD_STORE_LANES > && (memory_access_type != VMAT_GATHER_SCATTER > - || (gs_info.decl && !VECTOR_BOOLEAN_TYPE_P > (mask_vectype)))) > + || (GATHER_SCATTER_LEGACY_P (gs_info) > + && !VECTOR_BOOLEAN_TYPE_P (mask_vectype)))) > { > if (dump_enabled_p ()) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, > @@ -8376,8 +8377,7 @@ vectorizable_store (vec_info *vinfo, > return false; > } > else if (memory_access_type == VMAT_GATHER_SCATTER > - && gs_info.ifn == IFN_LAST > - && !gs_info.decl) > + && GATHER_SCATTER_EMULATED_P (gs_info)) > { > if (dump_enabled_p ()) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, > @@ -9103,7 +9103,7 @@ vectorizable_store (vec_info *vinfo, > final_mask, vec_mask, gsi); > } > > - if (gs_info.ifn != IFN_LAST) > + if (GATHER_SCATTER_IFN_P (gs_info)) > { > if (costing_p) > { > @@ -9166,7 +9166,7 @@ vectorizable_store (vec_info *vinfo, > vect_finish_stmt_generation (vinfo, stmt_info, call, gsi); > new_stmt = call; > } > - else if (gs_info.decl) > + else if (GATHER_SCATTER_LEGACY_P (gs_info)) > { > /* The builtin decls path for scatter is legacy, x86 only. */ > gcc_assert (nunits.is_constant () > @@ -10077,8 +10077,7 @@ vectorizable_load (vec_info *vinfo, > return false; > } > else if (memory_access_type == VMAT_GATHER_SCATTER > - && gs_info.ifn == IFN_LAST > - && !gs_info.decl) > + && GATHER_SCATTER_EMULATED_P (gs_info)) > { > if (dump_enabled_p ()) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, > @@ -11040,7 +11039,7 @@ vectorizable_load (vec_info *vinfo, > > /* 2. Create the vector-load in the loop. */ > unsigned HOST_WIDE_INT align; > - if (gs_info.ifn != IFN_LAST) > + if (GATHER_SCATTER_IFN_P (gs_info)) > { > if (costing_p) > { > @@ -11112,7 +11111,7 @@ vectorizable_load (vec_info *vinfo, > new_stmt = call; > data_ref = NULL_TREE; > } > - else if (gs_info.decl) > + else if (GATHER_SCATTER_LEGACY_P (gs_info)) > { > /* The builtin decls path for gather is legacy, x86 only. */ > gcc_assert (!final_len && nunits.is_constant ()); > diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h > index 799d5fed7a9..7b927491b1c 100644 > --- a/gcc/tree-vectorizer.h > +++ b/gcc/tree-vectorizer.h > @@ -1655,6 +1655,14 @@ struct gather_scatter_info { > #define PURE_SLP_STMT(S) ((S)->slp_type == pure_slp) > #define STMT_SLP_TYPE(S) (S)->slp_type > > +#define GATHER_SCATTER_LEGACY_P(info) ((info).decl != NULL_TREE \ > + && (info).ifn == IFN_LAST) > +#define GATHER_SCATTER_IFN_P(info) ((info).decl == NULL_TREE \ > + && (info).ifn != IFN_LAST) > +#define GATHER_SCATTER_EMULATED_P(info) ((info).decl == NULL_TREE \ > + && (info).ifn == IFN_LAST) > + > + > /* Contains the scalar or vector costs for a vec_info. */ > class vector_costs > { > -- > 2.50.0 >