vect_transform_stmt calls vectorizable_live_operation for
each live statement in an SLP node, but vect_analyze_stmt
only called it the once.  This patch makes vect_analyze_stmt
consistent with vect_transform_stmt, which should be a bit
more robust, and also means that a later patch can use
slp_index when deciding validity.

Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
OK to install?

Richard


2017-09-15  Richard Sandiford  <richard.sandif...@linaro.org>
            Alan Hayward  <alan.hayw...@arm.com>
            David Sherwood  <david.sherw...@arm.com>

gcc/
        * tree-vect-stmts.c (can_vectorize_live_stmts): New function,
        split out from...
        (vect_transform_stmt): ...here.
        (vect_analyze_stmt): Use it instead of calling
        vectorizable_live_operation directly.

Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c       2017-09-14 17:30:48.110211243 +0100
+++ gcc/tree-vect-stmts.c       2017-09-15 11:36:58.331030784 +0100
@@ -8479,6 +8479,35 @@ vectorizable_comparison (gimple *stmt, g
   return true;
 }
 
+/* If SLP_NODE is nonnull, return true if vectorizable_live_operation
+   can handle all live statements in the node.  Otherwise return true
+   if STMT is not live or if vectorizable_live_operation can handle it.
+   GSI and VEC_STMT are as for vectorizable_live_operation.  */
+
+static bool
+can_vectorize_live_stmts (gimple *stmt, gimple_stmt_iterator *gsi,
+                         slp_tree slp_node, gimple **vec_stmt)
+{
+  if (slp_node)
+    {
+      gimple *slp_stmt;
+      unsigned int i;
+      FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (slp_node), i, slp_stmt)
+       {
+         stmt_vec_info slp_stmt_info = vinfo_for_stmt (slp_stmt);
+         if (STMT_VINFO_LIVE_P (slp_stmt_info)
+             && !vectorizable_live_operation (slp_stmt, gsi, slp_node, i,
+                                              vec_stmt))
+           return false;
+       }
+    }
+  else if (STMT_VINFO_LIVE_P (vinfo_for_stmt (stmt))
+          && !vectorizable_live_operation (stmt, gsi, slp_node, -1, vec_stmt))
+    return false;
+
+  return true;
+}
+
 /* Make sure the statement is vectorizable.  */
 
 bool
@@ -8685,17 +8714,13 @@ vect_analyze_stmt (gimple *stmt, bool *n
 
   /* Stmts that are (also) "live" (i.e. - that are used out of the loop)
       need extra handling, except for vectorizable reductions.  */
-  if (STMT_VINFO_LIVE_P (stmt_info)
-      && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
-    ok = vectorizable_live_operation (stmt, NULL, node, -1, NULL);
-
-  if (!ok)
+  if (STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type
+      && !can_vectorize_live_stmts (stmt, NULL, node, NULL))
     {
       if (dump_enabled_p ())
         {
           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                           "not vectorized: live stmt not ");
-          dump_printf (MSG_MISSED_OPTIMIZATION,  "supported: ");
+                           "not vectorized: live stmt not supported: ");
           dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
         }
 
@@ -8861,26 +8886,9 @@ vect_transform_stmt (gimple *stmt, gimpl
 
   /* Handle stmts whose DEF is used outside the loop-nest that is
      being vectorized.  */
-  if (slp_node)
-    {
-      gimple *slp_stmt;
-      int i;
-      if (STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
-       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (slp_node), i, slp_stmt)
-         {
-           stmt_vec_info slp_stmt_info = vinfo_for_stmt (slp_stmt);
-           if (STMT_VINFO_LIVE_P (slp_stmt_info))
-             {
-               done = vectorizable_live_operation (slp_stmt, gsi, slp_node, i,
-                                                   &vec_stmt);
-               gcc_assert (done);
-             }
-         }
-    }
-  else if (STMT_VINFO_LIVE_P (stmt_info)
-          && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
+  if (STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
     {
-      done = vectorizable_live_operation (stmt, gsi, slp_node, -1, &vec_stmt);
+      done = can_vectorize_live_stmts (stmt, gsi, slp_node, &vec_stmt);
       gcc_assert (done);
     }
 

Reply via email to