2015-06-02 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Jun 2015 07:50:19 +0000 (07:50 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Jun 2015 07:50:19 +0000 (07:50 +0000)
PR tree-optimization/65961
* tree-vect-slp.c (vect_get_and_check_slp_defs): Remove bogus
check and clarify dump message.
(vect_build_slp_tree): If all children are built up from scalars
build up the parent from scalars instead.
* tree-vect-stmts.c (vect_is_simple_use): Cleanup.

* gcc.dg/torture/pr65961.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@224013 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr65961.c [new file with mode: 0644]
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c

index b889737..d7597c7 100644 (file)
@@ -1,3 +1,12 @@
+2015-06-02  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/65961
+       * tree-vect-slp.c (vect_get_and_check_slp_defs): Remove bogus
+       check and clarify dump message.
+       (vect_build_slp_tree): If all children are built up from scalars
+       build up the parent from scalars instead.
+       * tree-vect-stmts.c (vect_is_simple_use): Cleanup.
+
 2015-06-02  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        PR other/65366
index 2bd0a31..9dd08e5 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-02  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/65961
+       * gcc.dg/torture/pr65961.c: New testcase.
+
 2015-06-02  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/52563
diff --git a/gcc/testsuite/gcc.dg/torture/pr65961.c b/gcc/testsuite/gcc.dg/torture/pr65961.c
new file mode 100644 (file)
index 0000000..984ad1d
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int *a;
+void
+foo ()
+{
+  do
+    {
+      a[16] = (a[1] ^ a[0]) << 1 | a[1];
+      a[17] = (a[0] ^ a[1]) << 1 | a[0];
+      a[18] = (a[0] ^ a[1]) << 1 | a[0];
+      a[19] = (a[0] ^ a[1]) << 1 | a[0];
+      a[20] = (a[0] ^ a[1]) << 1 | a[0];
+      a[21] = (a[0] ^ a[1]) << 1 | a[0];
+      a[22] = (a[0] ^ a[1]) << 1 | a[0];
+      a[23] = (a[20] ^ a[1]) << 1 | a[9];
+      a += 8;
+    }
+  while (1);
+}
index fb57dd4..9e36d9c 100644 (file)
@@ -301,13 +301,12 @@ again:
       oprnd_info = (*oprnds_info)[i];
 
       if (!vect_is_simple_use (oprnd, NULL, loop_vinfo, bb_vinfo, &def_stmt,
-                              &def, &dt)
-         || (!def_stmt && dt != vect_constant_def))
+                              &def, &dt))
        {
          if (dump_enabled_p ())
            {
              dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                              "Build SLP failed: can't find def for ");
+                              "Build SLP failed: can't analyze def for ");
              dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, oprnd);
               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
            }
@@ -1092,6 +1091,35 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
                               vectorization_factor, matches,
                               npermutes, &this_tree_size, max_tree_size))
        {
+         /* If we have all children of child built up from scalars then just
+            throw that away and build it up this node from scalars.  */
+         if (!SLP_TREE_CHILDREN (child).is_empty ())
+           {
+             unsigned int j;
+             slp_tree grandchild;
+
+             FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (child), j, grandchild)
+               if (grandchild != NULL)
+                 break;
+             if (!grandchild)
+               {
+                 /* Roll back.  */
+                 *max_nunits = old_max_nunits;
+                 loads->truncate (old_nloads);
+                 FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (child), j, grandchild)
+                     vect_free_slp_tree (grandchild);
+                 SLP_TREE_CHILDREN (child).truncate (0);
+
+                 dump_printf_loc (MSG_NOTE, vect_location,
+                                  "Building parent vector operands from "
+                                  "scalars instead\n");
+                 oprnd_info->def_stmts = vNULL;
+                 vect_free_slp_tree (child);
+                 SLP_TREE_CHILDREN (*node).quick_push (NULL);
+                 continue;
+               }
+           }
+
          oprnd_info->def_stmts = vNULL;
          SLP_TREE_CHILDREN (*node).quick_push (child);
          continue;
index 6b018e5..0eeebb0 100644 (file)
@@ -7878,15 +7878,9 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo,
                     bb_vec_info bb_vinfo, gimple *def_stmt,
                    tree *def, enum vect_def_type *dt)
 {
-  basic_block bb;
-  stmt_vec_info stmt_vinfo;
-  struct loop *loop = NULL;
-
-  if (loop_vinfo)
-    loop = LOOP_VINFO_LOOP (loop_vinfo);
-
   *def_stmt = NULL;
   *def = NULL_TREE;
+  *dt = vect_unknown_def_type;
 
   if (dump_enabled_p ())
     {
@@ -7909,13 +7903,6 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo,
       return true;
     }
 
-  if (TREE_CODE (operand) == PAREN_EXPR)
-    {
-      if (dump_enabled_p ())
-        dump_printf_loc (MSG_NOTE, vect_location, "non-associatable copy.\n");
-      operand = TREE_OPERAND (operand, 0);
-    }
-
   if (TREE_CODE (operand) != SSA_NAME)
     {
       if (dump_enabled_p ())
@@ -7924,40 +7911,30 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo,
       return false;
     }
 
-  *def_stmt = SSA_NAME_DEF_STMT (operand);
-  if (*def_stmt == NULL)
+  if (SSA_NAME_IS_DEFAULT_DEF (operand))
     {
-      if (dump_enabled_p ())
-        dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                         "no def_stmt.\n");
-      return false;
+      *def = operand;
+      *dt = vect_external_def;
+      return true;
     }
 
+  *def_stmt = SSA_NAME_DEF_STMT (operand);
   if (dump_enabled_p ())
     {
       dump_printf_loc (MSG_NOTE, vect_location, "def_stmt: ");
       dump_gimple_stmt (MSG_NOTE, TDF_SLIM, *def_stmt, 0);
     }
 
-  /* Empty stmt is expected only in case of a function argument.
-     (Otherwise - we expect a phi_node or a GIMPLE_ASSIGN).  */
-  if (gimple_nop_p (*def_stmt))
-    {
-      *def = operand;
-      *dt = vect_external_def;
-      return true;
-    }
-
-  bb = gimple_bb (*def_stmt);
-
-  if ((loop && !flow_bb_inside_loop_p (loop, bb))
-      || (!loop && bb != BB_VINFO_BB (bb_vinfo))
-      || (!loop && gimple_code (*def_stmt) == GIMPLE_PHI))
+  basic_block bb = gimple_bb (*def_stmt);
+  if ((loop_vinfo && !flow_bb_inside_loop_p (LOOP_VINFO_LOOP (loop_vinfo), bb))
+      || (bb_vinfo
+         && (bb != BB_VINFO_BB (bb_vinfo)
+             || gimple_code (*def_stmt) == GIMPLE_PHI)))
     *dt = vect_external_def;
   else
     {
-      stmt_vinfo = vinfo_for_stmt (*def_stmt);
-      if (!loop && !STMT_VINFO_VECTORIZABLE (stmt_vinfo))
+      stmt_vec_info stmt_vinfo = vinfo_for_stmt (*def_stmt);
+      if (bb_vinfo && !STMT_VINFO_VECTORIZABLE (stmt_vinfo))
        *dt = vect_external_def;
       else
        *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo);