tree-optimization/93397 delay converted reduction chain adjustment
authorRichard Biener <rguenther@suse.de>
Mon, 27 Jan 2020 09:30:29 +0000 (10:30 +0100)
committerRichard Biener <rguenther@suse.de>
Mon, 27 Jan 2020 09:31:53 +0000 (10:31 +0100)
The following delays adjusting the SLP graph for converted reduction
chains to a point where the SLP build no longer can fail since we
otherwise fail to undo marking the conversion as a group.

2020-01-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/93397
* tree-vect-slp.c (vect_analyze_slp_instance): Delay
converted reduction chain SLP graph adjustment.

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

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

index 88e4c2d65c8e0ecff212ba60f6c920ee7994f69f..45075840824cd3632e598d1c72f7509fa6e04b62 100644 (file)
@@ -1,3 +1,9 @@
+2020-01-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/93397
+       * tree-vect-slp.c (vect_analyze_slp_instance): Delay
+       converted reduction chain SLP graph adjustment.
+
 2020-01-26  Marek Polacek  <polacek@redhat.com>
 
        PR sanitizer/93436
index bcaca253aafe8a9b6121de30da07425a45b749bd..2de060843d9c8034322f7cc799505f0aaec4b36b 100644 (file)
@@ -1,3 +1,8 @@
+2020-01-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/93397
+       * gcc.dg/torture/pr93397.c: New testcase.
+
 2020-01-27  Tobias Burnus  <tobias@codesourcery.com>
 
        PR fortran/85781
diff --git a/gcc/testsuite/gcc.dg/torture/pr93397.c b/gcc/testsuite/gcc.dg/torture/pr93397.c
new file mode 100644 (file)
index 0000000..c19b798
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize" } */
+
+char
+bn (char *vu)
+{
+  int b6;
+  char wv = 0;
+
+  for (b6 = 0; b6 <= 64; b6 += 4)
+    wv += vu[b6] + vu[b6 + 1];
+
+  return wv;
+}
index cebaa811dd21d9a32d5052b57dbddd5ac4a05862..b13beeb3689ffe811349b81f3269eeeec094c96d 100644 (file)
@@ -2210,34 +2210,6 @@ vect_analyze_slp_instance (vec_info *vinfo,
                              &tree_size, bst_map);
   if (node != NULL)
     {
-      /* If this is a reduction chain with a conversion in front
-         amend the SLP tree with a node for that.  */
-      if (!dr
-         && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
-         && STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def)
-       {
-         /* Get at the conversion stmt - we know it's the single use
-            of the last stmt of the reduction chain.  */
-         gimple *tem = vect_orig_stmt (scalar_stmts[group_size - 1])->stmt;
-         use_operand_p use_p;
-         gimple *use_stmt;
-         bool r = single_imm_use (gimple_assign_lhs (tem), &use_p, &use_stmt);
-         gcc_assert (r);
-         next_info = vinfo->lookup_stmt (use_stmt);
-         next_info = vect_stmt_to_vectorize (next_info);
-         scalar_stmts = vNULL;
-         scalar_stmts.create (group_size);
-         for (unsigned i = 0; i < group_size; ++i)
-           scalar_stmts.quick_push (next_info);
-         slp_tree conv = vect_create_new_slp_node (scalar_stmts);
-         SLP_TREE_CHILDREN (conv).quick_push (node);
-         node = conv;
-         /* We also have to fake this conversion stmt as SLP reduction group
-            so we don't have to mess with too much code elsewhere.  */
-         REDUC_GROUP_FIRST_ELEMENT (next_info) = next_info;
-         REDUC_GROUP_NEXT_ELEMENT (next_info) = NULL;
-       }
-
       /* Calculate the unrolling factor based on the smallest type.  */
       poly_uint64 unrolling_factor
        = calculate_unrolling_factor (max_nunits, group_size);
@@ -2355,6 +2327,36 @@ vect_analyze_slp_instance (vec_info *vinfo,
                }
            }
 
+         /* If this is a reduction chain with a conversion in front
+            amend the SLP tree with a node for that.  */
+         if (!dr
+             && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
+             && STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def)
+           {
+             /* Get at the conversion stmt - we know it's the single use
+                of the last stmt of the reduction chain.  */
+             gimple *tem = vect_orig_stmt (scalar_stmts[group_size - 1])->stmt;
+             use_operand_p use_p;
+             gimple *use_stmt;
+             bool r = single_imm_use (gimple_assign_lhs (tem),
+                                      &use_p, &use_stmt);
+             gcc_assert (r);
+             next_info = vinfo->lookup_stmt (use_stmt);
+             next_info = vect_stmt_to_vectorize (next_info);
+             scalar_stmts = vNULL;
+             scalar_stmts.create (group_size);
+             for (unsigned i = 0; i < group_size; ++i)
+               scalar_stmts.quick_push (next_info);
+             slp_tree conv = vect_create_new_slp_node (scalar_stmts);
+             SLP_TREE_CHILDREN (conv).quick_push (node);
+             SLP_INSTANCE_TREE (new_instance) = conv;
+             /* We also have to fake this conversion stmt as SLP reduction
+                group so we don't have to mess with too much code
+                elsewhere.  */
+             REDUC_GROUP_FIRST_ELEMENT (next_info) = next_info;
+             REDUC_GROUP_NEXT_ELEMENT (next_info) = NULL;
+           }
+
          vinfo->slp_instances.safe_push (new_instance);
 
          if (dump_enabled_p ())