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

Reply via email to