diff options
author | Richard Biener <rguenther@suse.de> | 2020-01-29 09:05:05 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2020-01-29 09:06:08 +0100 |
commit | 148018bc3fe7ce47d005a1c5f7b6dd044024a4af (patch) | |
tree | a30ce10c81aca156f2ee9019eab8b7a6f94e6336 | |
parent | 345ea96111385ecc2a38f1e9b18f4f07cb98140f (diff) | |
download | gcc-148018bc3fe7ce47d005a1c5f7b6dd044024a4af.zip gcc-148018bc3fe7ce47d005a1c5f7b6dd044024a4af.tar.gz gcc-148018bc3fe7ce47d005a1c5f7b6dd044024a4af.tar.bz2 |
tree-optimization/93428 - avoid load permutation vector clobbering
With SLP now being a graph with shared nodes across instances we have
to make sure to compute the load permutation of nodes once, not
overwriting the result of earlier analysis.
2020-01-28 Richard Biener <rguenther@suse.de>
PR tree-optimization/93428
* tree-vect-slp.c (vect_build_slp_tree_2): Compute the load
permutation when the load node is created.
(vect_analyze_slp_instance): Re-use it here.
* gcc.dg/torture/pr93428.c: New testcase.
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr93428.c | 27 | ||||
-rw-r--r-- | gcc/tree-vect-slp.c | 37 |
4 files changed, 64 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd298b9..f6959ef 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-01-29 Richard Biener <rguenther@suse.de> + + PR tree-optimization/93428 + * tree-vect-slp.c (vect_build_slp_tree_2): Compute the load + permutation when the load node is created. + (vect_analyze_slp_instance): Re-use it here. + 2020-01-28 Jan Hubicka <hubicka@ucw.cz> * ipa-prop.c (update_indirect_edges_after_inlining): Fix warning. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 279ab64..a4a775d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-01-29 Richard Biener <rguenther@suse.de> + + PR tree-optimization/93428 + * gcc.dg/torture/pr93428.c: New testcase. + 2020-01-28 Martin Sebor <msebor@redhat.com> PR middle-end/93437 diff --git a/gcc/testsuite/gcc.dg/torture/pr93428.c b/gcc/testsuite/gcc.dg/torture/pr93428.c new file mode 100644 index 0000000..b24f651 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr93428.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-slp-vectorize" } */ + +int ai[2][8]; +void bar (int *); +void +br (void) +{ + int qp[9]; + bar (qp); + ai[0][0] = qp[0] + qp[1] + 1 >> 1; + ai[0][1] = qp[1] + qp[2] + 1 >> 1; + ai[0][2] = qp[2] + qp[3] + 1 >> 1; + ai[0][3] = qp[3] + qp[4] + 1 >> 1; + ai[0][4] = qp[4] + qp[5] + 1 >> 1; + ai[0][5] = qp[5] + qp[6] + 1 >> 1; + ai[0][6] = qp[6] + qp[7] + 1 >> 1; + ai[0][7] = qp[7] + qp[8] + 1 >> 1; + ai[1][0] = qp[0] + qp[1] + 2 * qp[0] + 1 >> 2; + ai[1][1] = qp[0] + qp[2] + 2 * qp[1] + 1 >> 2; + ai[1][2] = qp[1] + qp[3] + 2 * qp[2] + 1 >> 2; + ai[1][3] = qp[2] + qp[4] + 2 * qp[3] + 1 >> 2; + ai[1][4] = qp[3] + qp[5] + 2 * qp[4] + 1 >> 2; + ai[1][5] = qp[4] + qp[6] + 2 * qp[5] + 1 >> 2; + ai[1][6] = qp[5] + qp[7] + 2 * qp[6] + 1 >> 2; + ai[1][7] = qp[6] + qp[8] + 2 * qp[7] + 1 >> 2; +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index b13beeb..71a24b7 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1353,6 +1353,23 @@ vect_build_slp_tree_2 (vec_info *vinfo, *max_nunits = this_max_nunits; (*tree_size)++; node = vect_create_new_slp_node (stmts); + /* And compute the load permutation. Whether it is actually + a permutation depends on the unrolling factor which is + decided later. */ + vec<unsigned> load_permutation; + int j; + stmt_vec_info load_info; + load_permutation.create (group_size); + stmt_vec_info first_stmt_info + = DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (node)[0]); + FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), j, load_info) + { + int load_place = vect_get_place_in_interleaving_chain + (load_info, first_stmt_info); + gcc_assert (load_place != -1); + load_permutation.safe_push (load_place); + } + SLP_TREE_LOAD_PERMUTATION (node) = load_permutation; return node; } } @@ -2254,22 +2271,19 @@ vect_analyze_slp_instance (vec_info *vinfo, bool loads_permuted = false; FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (new_instance), i, load_node) { - vec<unsigned> load_permutation; - int j; + if (!SLP_TREE_LOAD_PERMUTATION (load_node).exists ()) + continue; + unsigned j; stmt_vec_info load_info; bool this_load_permuted = false; - load_permutation.create (group_size); stmt_vec_info first_stmt_info = DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (load_node)[0]); FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (load_node), j, load_info) - { - int load_place = vect_get_place_in_interleaving_chain - (load_info, first_stmt_info); - gcc_assert (load_place != -1); - if (load_place != j) + if (SLP_TREE_LOAD_PERMUTATION (load_node)[j] != j) + { this_load_permuted = true; - load_permutation.safe_push (load_place); - } + break; + } if (!this_load_permuted /* The load requires permutation when unrolling exposes a gap either because the group is larger than the SLP @@ -2278,10 +2292,9 @@ vect_analyze_slp_instance (vec_info *vinfo, || (group_size == DR_GROUP_SIZE (first_stmt_info) && DR_GROUP_GAP (first_stmt_info) == 0))) { - load_permutation.release (); + SLP_TREE_LOAD_PERMUTATION (load_node).release (); continue; } - SLP_TREE_LOAD_PERMUTATION (load_node) = load_permutation; loads_permuted = true; } |