[gcc(refs/vendors/ibm/heads/perf)] tree-optimization/93868 copy SLP tree before re-arranging stmts

Jiu Fu Guo guojiufu@gcc.gnu.org
Thu Mar 19 05:51:12 GMT 2020


https://gcc.gnu.org/g:81c833b311b16cfd87a947374d5ffbbd48facd03

commit 81c833b311b16cfd87a947374d5ffbbd48facd03
Author: Richard Biener <rguenther@suse.de>
Date:   Tue Feb 25 10:31:16 2020 +0100

    tree-optimization/93868 copy SLP tree before re-arranging stmts
    
    This avoids altering possibly shared SLP subtrees when attempting
    to get rid of permutations in SLP reductions by copying the SLP
    subtree before re-arranging stmts in it.
    
    2020-02-25  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/93868
            * tree-vect-slp.c (slp_copy_subtree): New function.
            (vect_attempt_slp_rearrange_stmts): Copy the SLP tree before
            re-arranging stmts in it.
    
            * gcc.dg/torture/pr93868.c: New testcase.

Diff:
---
 gcc/ChangeLog                          |  7 +++++
 gcc/testsuite/ChangeLog                |  5 ++++
 gcc/testsuite/gcc.dg/torture/pr93868.c | 31 +++++++++++++++++++++
 gcc/tree-vect-slp.c                    | 50 ++++++++++++++++++++++++++++++++++
 4 files changed, 93 insertions(+)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9d453f16f07..dba986dfdff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2020-02-25  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/93868
+	* tree-vect-slp.c (slp_copy_subtree): New function.
+	(vect_attempt_slp_rearrange_stmts): Copy the SLP tree before
+	re-arranging stmts in it.
+
 2020-02-25  Jakub Jelinek  <jakub@redhat.com>
 
 	PR middle-end/93874
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 62b000b2314..d25296df65b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-02-25  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/93868
+	* gcc.dg/torture/pr93868.c: New testcase.
+
 2020-02-25  Jakub Jelinek  <jakub@redhat.com>
 
 	PR middle-end/93874
diff --git a/gcc/testsuite/gcc.dg/torture/pr93868.c b/gcc/testsuite/gcc.dg/torture/pr93868.c
new file mode 100644
index 00000000000..850eba1dd49
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr93868.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-vectorize" } */
+
+unsigned a[1024];
+unsigned b[1024];
+
+void __attribute__((noipa))
+foo (unsigned *q, unsigned *r)
+{
+  unsigned sum1 = 0, sum2 = 0;
+  for (int i = 0; i < 512; ++i)
+    {
+      sum1 += a[2*i];
+      sum2 += a[2*i+1];
+      b[2*i] = a[2*i+1];
+      b[2*i+1] = a[2*i];
+    }
+  *q = sum1;
+  *r = sum2;
+}
+
+int main()
+{
+  unsigned sum1, sum2;
+  a[0] = 0;
+  a[1] = 1;
+  foo (&sum1, &sum2);
+  if (b[0] != 1 || b[1] != 0)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 71a24b78cf4..077c7946fee 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1749,6 +1749,44 @@ vect_mark_slp_stmts_relevant (slp_tree node)
   vect_mark_slp_stmts_relevant (node, visited);
 }
 
+/* Copy the SLP subtree rooted at NODE.  */
+
+static slp_tree
+slp_copy_subtree (slp_tree node, hash_map<slp_tree, slp_tree> &map)
+{
+  unsigned i;
+
+  bool existed_p;
+  slp_tree &copy = map.get_or_insert (node, &existed_p);
+  if (existed_p)
+    return copy;
+
+  copy = XNEW (_slp_tree);
+  memcpy (copy, node, sizeof (_slp_tree));
+  if (SLP_TREE_SCALAR_STMTS (node).exists ())
+    {
+      SLP_TREE_SCALAR_STMTS (copy) = SLP_TREE_SCALAR_STMTS (node).copy ();
+      stmt_vec_info stmt_info;
+      FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
+	STMT_VINFO_NUM_SLP_USES (stmt_info)++;
+    }
+  if (SLP_TREE_SCALAR_OPS (node).exists ())
+    SLP_TREE_SCALAR_OPS (copy) = SLP_TREE_SCALAR_OPS (node).copy ();
+  if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
+    SLP_TREE_LOAD_PERMUTATION (copy) = SLP_TREE_LOAD_PERMUTATION (node).copy ();
+  if (SLP_TREE_CHILDREN (node).exists ())
+    SLP_TREE_CHILDREN (copy) = SLP_TREE_CHILDREN (node).copy ();
+  gcc_assert (!SLP_TREE_VEC_STMTS (node).exists ());
+  copy->refcnt = 0;
+
+  slp_tree child;
+  FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (copy), i, child)
+    {
+      SLP_TREE_CHILDREN (copy)[i] = slp_copy_subtree (child, map);
+      SLP_TREE_CHILDREN (copy)[i]->refcnt++;
+    }
+  return copy;
+}
 
 /* Rearrange the statements of NODE according to PERMUTATION.  */
 
@@ -1840,6 +1878,18 @@ vect_attempt_slp_rearrange_stmts (slp_instance slp_instn)
      statements in the nodes is not important unless they are memory
      accesses, we can rearrange the statements in all the nodes
      according to the order of the loads.  */
+
+  /* We have to unshare the SLP tree we modify.  */
+  hash_map<slp_tree, slp_tree> map;
+  slp_tree unshared = slp_copy_subtree (SLP_INSTANCE_TREE (slp_instn), map);
+  vect_free_slp_tree (SLP_INSTANCE_TREE (slp_instn), false);
+  unshared->refcnt++;
+  SLP_INSTANCE_TREE (slp_instn) = unshared;
+  FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (slp_instn), i, node)
+    SLP_INSTANCE_LOADS (slp_instn)[i] = *map.get (node);
+  node = SLP_INSTANCE_LOADS (slp_instn)[0];
+
+  /* Do the actual re-arrangement.  */
   hash_set<slp_tree> visited;
   vect_slp_rearrange_stmts (SLP_INSTANCE_TREE (slp_instn), group_size,
 			    node->load_permutation, visited);


More information about the Gcc-cvs mailing list