[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 © = 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