aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2020-01-29 09:05:05 +0100
committerRichard Biener <rguenther@suse.de>2020-01-29 09:06:08 +0100
commit148018bc3fe7ce47d005a1c5f7b6dd044024a4af (patch)
treea30ce10c81aca156f2ee9019eab8b7a6f94e6336
parent345ea96111385ecc2a38f1e9b18f4f07cb98140f (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr93428.c27
-rw-r--r--gcc/tree-vect-slp.c37
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;
}