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. 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