Commit 81c833b3 by Richard Biener

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.
parent 2473c81c
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> 2020-02-25 Jakub Jelinek <jakub@redhat.com>
PR middle-end/93874 PR middle-end/93874
......
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> 2020-02-25 Jakub Jelinek <jakub@redhat.com>
PR middle-end/93874 PR middle-end/93874
......
/* { 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;
}
...@@ -1749,6 +1749,44 @@ vect_mark_slp_stmts_relevant (slp_tree node) ...@@ -1749,6 +1749,44 @@ vect_mark_slp_stmts_relevant (slp_tree node)
vect_mark_slp_stmts_relevant (node, visited); 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. */ /* Rearrange the statements of NODE according to PERMUTATION. */
...@@ -1840,6 +1878,18 @@ vect_attempt_slp_rearrange_stmts (slp_instance slp_instn) ...@@ -1840,6 +1878,18 @@ vect_attempt_slp_rearrange_stmts (slp_instance slp_instn)
statements in the nodes is not important unless they are memory statements in the nodes is not important unless they are memory
accesses, we can rearrange the statements in all the nodes accesses, we can rearrange the statements in all the nodes
according to the order of the loads. */ 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; hash_set<slp_tree> visited;
vect_slp_rearrange_stmts (SLP_INSTANCE_TREE (slp_instn), group_size, vect_slp_rearrange_stmts (SLP_INSTANCE_TREE (slp_instn), group_size,
node->load_permutation, visited); node->load_permutation, visited);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment