Even though we define gather_load_cost and scatter_store_cost in the
cost tables, they are never actually used for IFN gather/scatters.
This is because the vectorizer costs them as scalar loads and stores
instead of dedicated vector_gather_load / vector_scatter_store
operations.

This patch makes the cost model recognize VMAT_GATHER_SCATTER_IFN and
use the proper table costs.

gcc/ChangeLog:

        * config/riscv/riscv-vector-costs.cc (costs::adjust_stmt_cost,
        costs::add_stmt_cost): Use gather/scatter costs.

Signed-off-by: Zhongyao Chen <[email protected]>
---
 gcc/config/riscv/riscv-vector-costs.cc | 27 ++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/gcc/config/riscv/riscv-vector-costs.cc 
b/gcc/config/riscv/riscv-vector-costs.cc
index d26a390793c..f430a9907e3 100644
--- a/gcc/config/riscv/riscv-vector-costs.cc
+++ b/gcc/config/riscv/riscv-vector-costs.cc
@@ -1498,6 +1498,21 @@ costs::adjust_stmt_cost (enum vect_cost_for_stmt kind, 
loop_vec_info loop,
          break;
        }
 
+    case scalar_load:
+    case scalar_store:
+      if (node
+         && SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_GATHER_SCATTER_IFN)
+       {
+         const common_vector_cost *common_costs
+           = riscv_vla_mode_p (TYPE_MODE (vectype))
+             ? costs->vla : costs->vls;
+         if (kind == scalar_load)
+           stmt_cost = common_costs->gather_load_cost;
+         else
+           stmt_cost = common_costs->scatter_store_cost;
+       }
+      break;
+
     default:
       break;
     }
@@ -1617,6 +1632,18 @@ costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
   stmt_cost = scale_vector_cost (kind, loop_vinfo, stmt_info, node,
                                 vectype, where, stmt_cost);
 
+  /* Gather loads and scatter stores are costed as a single scalar_load
+     or scalar_store for each element.  We therefore need to divide the
+     full-instruction cost by the number of elements in the vector.  */
+  if (m_cost_type != SCALAR_COST
+      && vectype
+      && (kind == scalar_load || kind == scalar_store)
+      && node
+      && SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_GATHER_SCATTER_IFN)
+    return record_stmt_cost (stmt_info, where,
+                            CEIL (count * stmt_cost,
+                                  vect_nunits_for_cost (vectype)));
+
   return record_stmt_cost (stmt_info, where, count * stmt_cost);
 }
 
-- 
2.43.0


Reply via email to