This patch adds access helpers for the gather/scatter offset and scale parameters.
gcc/ChangeLog: * internal-fn.cc (expand_scatter_store_optab_fn): Use new function. (expand_gather_load_optab_fn): Ditto. (internal_fn_offset_index): Ditto. (internal_fn_scale_index): Ditto. * internal-fn.h (internal_fn_offset_index): New function. (internal_fn_scale_index): Ditto. * optabs-query.cc (supports_vec_gather_load_p): Adjust index. * tree-vect-data-refs.cc (vect_describe_gather_scatter_call): Use new function. --- gcc/internal-fn.cc | 57 ++++++++++++++++++++++++++++++++++---- gcc/internal-fn.h | 2 ++ gcc/tree-vect-data-refs.cc | 6 ++-- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 044bdc22481..4a9dc26e836 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -3652,8 +3652,8 @@ expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab) internal_fn ifn = gimple_call_internal_fn (stmt); int rhs_index = internal_fn_stored_value_index (ifn); tree base = gimple_call_arg (stmt, 0); - tree offset = gimple_call_arg (stmt, 1); - tree scale = gimple_call_arg (stmt, 2); + tree offset = gimple_call_arg (stmt, internal_fn_offset_index (ifn)); + tree scale = gimple_call_arg (stmt, internal_fn_scale_index (ifn)); tree rhs = gimple_call_arg (stmt, rhs_index); rtx base_rtx = expand_normal (base); @@ -3678,12 +3678,12 @@ expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab) /* Expand {MASK_,}GATHER_LOAD call CALL using optab OPTAB. */ static void -expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab) +expand_gather_load_optab_fn (internal_fn ifn, gcall *stmt, direct_optab optab) { tree lhs = gimple_call_lhs (stmt); tree base = gimple_call_arg (stmt, 0); - tree offset = gimple_call_arg (stmt, 1); - tree scale = gimple_call_arg (stmt, 2); + tree offset = gimple_call_arg (stmt, internal_fn_offset_index (ifn)); + tree scale = gimple_call_arg (stmt, internal_fn_scale_index (ifn)); rtx lhs_rtx = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); rtx base_rtx = expand_normal (base); @@ -5125,6 +5125,53 @@ internal_fn_stored_value_index (internal_fn fn) } } +/* If FN is a gather/scatter return the index of its offset argument, + otherwise return -1. */ + +int +internal_fn_offset_index (internal_fn fn) +{ + if (!internal_gather_scatter_fn_p (fn)) + return -1; + + switch (fn) + { + case IFN_GATHER_LOAD: + case IFN_MASK_GATHER_LOAD: + case IFN_MASK_LEN_GATHER_LOAD: + case IFN_SCATTER_STORE: + case IFN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_SCATTER_STORE: + return 1; + + default: + return -1; + } +} + +/* If FN is a gather/scatter return the index of its scale argument, + otherwise return -1. */ + +int +internal_fn_scale_index (internal_fn fn) +{ + if (!internal_gather_scatter_fn_p (fn)) + return -1; + + switch (fn) + { + case IFN_GATHER_LOAD: + case IFN_MASK_GATHER_LOAD: + case IFN_MASK_LEN_GATHER_LOAD: + case IFN_SCATTER_STORE: + case IFN_MASK_SCATTER_STORE: + case IFN_MASK_LEN_SCATTER_STORE: + return 2; + + default: + return -1; + } +} /* Store all supported else values for the optab referred to by ICODE in ELSE_VALS. The index of the else operand must be specified in diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h index afd4f8e64c7..c5b533c0abd 100644 --- a/gcc/internal-fn.h +++ b/gcc/internal-fn.h @@ -239,6 +239,8 @@ extern int internal_fn_mask_index (internal_fn); extern int internal_fn_len_index (internal_fn); extern int internal_fn_else_index (internal_fn); extern int internal_fn_stored_value_index (internal_fn); +extern int internal_fn_offset_index (internal_fn fn); +extern int internal_fn_scale_index (internal_fn fn); extern bool internal_gather_scatter_fn_supported_p (internal_fn, tree, tree, tree, int, vec<int> * = nullptr); diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index c84cd29116e..5b2cb537438 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -4539,10 +4539,12 @@ vect_describe_gather_scatter_call (stmt_vec_info stmt_info, info->ifn = gimple_call_internal_fn (call); info->decl = NULL_TREE; info->base = gimple_call_arg (call, 0); - info->offset = gimple_call_arg (call, 1); + info->offset = gimple_call_arg + (call, internal_fn_offset_index (info->ifn)); info->offset_dt = vect_unknown_def_type; info->offset_vectype = NULL_TREE; - info->scale = TREE_INT_CST_LOW (gimple_call_arg (call, 2)); + info->scale = TREE_INT_CST_LOW (gimple_call_arg + (call, internal_fn_scale_index (info->ifn))); info->element_type = TREE_TYPE (vectype); info->memory_type = TREE_TYPE (DR_REF (dr)); } -- 2.50.0