From: Ezra Sitorus <[email protected]>

Teach GCC that IFN_COMPLEX_DOT_PROD_ROT0 is lane reducing. This involves
modifying helper functions to support internal-function calls.

Are there any tests that can/need to be added for this?

gcc/ChangeLog:
        * tree-vect-loop.cc (vectorizable_lane_reducing): Handle internal-fn
          calls.
        * tree-vectorizer.h (lane_reducing_op_p): Make
          IFN_COMPLEX_DOT_PROD_ROT0 return true.
          (lane_reducing_stmt_p): Add support for gcall/internal_fn.
---
 gcc/tree-vect-loop.cc | 10 ++++++----
 gcc/tree-vectorizer.h | 18 +++++++++++++++++-
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 19e7a6fa884f..6237ae7802dd 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -6787,7 +6787,10 @@ vectorizable_lane_reducing (loop_vec_info loop_vinfo, 
stmt_vec_info stmt_info,
   if (!lane_reducing_stmt_p (stmt))
     return false;
 
-  tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+  gimple_match_op op;
+  if (!gimple_extract_op (stmt, &op))
+    return false;
+  tree type = op.type;
 
   if (!INTEGRAL_TYPE_P (type))
     return false;
@@ -6808,7 +6811,7 @@ vectorizable_lane_reducing (loop_vec_info loop_vinfo, 
stmt_vec_info stmt_info,
   gcc_assert (!nested_in_vect_loop_p (LOOP_VINFO_LOOP (loop_vinfo), 
stmt_info));
   gcc_assert (VECT_REDUC_INFO_TYPE (reduc_info) == TREE_CODE_REDUCTION);
 
-  for (int i = 0; i < (int) gimple_num_ops (stmt) - 1; i++)
+  for (int i = 0; i < (int) op.num_ops; i++)
     {
       slp_tree slp_op;
       tree op;
@@ -6887,9 +6890,8 @@ vectorizable_lane_reducing (loop_vec_info loop_vinfo, 
stmt_vec_info stmt_info,
 
   if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo))
     {
-      enum tree_code code = gimple_assign_rhs_code (stmt);
       if (vect_reduction_update_partial_vector_usage (loop_vinfo, reduc_info,
-                                                     code, type, vectype_in))
+                                                     op.code, type, 
vectype_in))
        {
          internal_fn reduc_fn = VECT_REDUC_INFO_FN (reduc_info);
          internal_fn mask_reduc_fn
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 7ce13828c0a2..e9f611e25a67 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -2422,7 +2422,18 @@ vect_apply_runtime_profitability_check_p (loop_vec_info 
loop_vinfo)
 inline bool
 lane_reducing_op_p (code_helper code)
 {
-  return code == DOT_PROD_EXPR || code == WIDEN_SUM_EXPR || code == SAD_EXPR;
+  if (code == DOT_PROD_EXPR || code == WIDEN_SUM_EXPR || code == SAD_EXPR)
+    return true;
+
+  if (code.is_internal_fn ())
+    switch (internal_fn (code))
+      {
+       case IFN_COMPLEX_DOT_PROD_ROT0:
+         return true;
+       default:
+         break;
+      }
+  return false;
 }
 
 /* Return true if STMT is a lane-reducing statement.  */
@@ -2432,6 +2443,11 @@ lane_reducing_stmt_p (gimple *stmt)
 {
   if (auto *assign = dyn_cast <gassign *> (stmt))
     return lane_reducing_op_p (gimple_assign_rhs_code (assign));
+
+  if (auto *call = dyn_cast <gcall *> (stmt))
+    return (gimple_call_internal_p (call)
+           && lane_reducing_op_p (gimple_call_internal_fn (call)));
+
   return false;
 }
 
-- 
2.53.0

Reply via email to