aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2020-10-28 12:56:16 +0100
committerRichard Biener <rguenther@suse.de>2020-10-28 14:15:37 +0100
commit2acb33103c4cbc6766d8707ad58aa5cc9a804719 (patch)
tree2ae9a8c3f1965c9c023d7cda958797c0027e62e9 /gcc
parentac1724ccfdb9056d59fc21500c57c4edc963e653 (diff)
downloadgcc-2acb33103c4cbc6766d8707ad58aa5cc9a804719.zip
gcc-2acb33103c4cbc6766d8707ad58aa5cc9a804719.tar.gz
gcc-2acb33103c4cbc6766d8707ad58aa5cc9a804719.tar.bz2
Change the way we split stores in BB vectorization
The following fixes missed optimizations due to the strange way we split stores in BB vectorization. The solution is to split at the failure boundary and not re-align that to the initial piece chosen vector size. Also re-analyze any larger matching rest. 2020-10-28 Richard Biener <rguenther@suse.de> * tree-vect-slp.c (vect_build_slp_instance): Split the store group at the failure boundary and also re-analyze a large enough matching rest. * gcc.dg/vect/bb-slp-68.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-68.c22
-rw-r--r--gcc/tree-vect-slp.c20
2 files changed, 35 insertions, 7 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-68.c b/gcc/testsuite/gcc.dg/vect/bb-slp-68.c
new file mode 100644
index 0000000..8718031
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-68.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_double } */
+/* { dg-additional-options "-mavx" { target avx } } */
+
+double x[10], y[6], z[4];
+
+void foo ()
+{
+ x[0] = y[0];
+ x[1] = y[1];
+ x[2] = y[2];
+ x[3] = y[3];
+ x[4] = y[4];
+ x[5] = y[5];
+ x[6] = z[0] + 1.;
+ x[7] = z[1] + 1.;
+ x[8] = z[2] + 1.;
+ x[9] = z[3] + 1.;
+}
+
+/* We want to have the store group split into 4, 2, 4 when using 32byte vectors. */
+/* { dg-final { scan-tree-dump-not "from scalars" "slp2" } } */
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 470b67d..50a2d37 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2412,15 +2412,21 @@ vect_build_slp_instance (vec_info *vinfo,
group1_size);
bool res = vect_analyze_slp_instance (vinfo, bst_map, stmt_info,
max_tree_size);
- /* If the first non-match was in the middle of a vector,
- skip the rest of that vector. Do not bother to re-analyze
- single stmt groups. */
- if (group1_size < i)
+ /* Split the rest at the failure point and possibly
+ re-analyze the remaining matching part if it has
+ at least two lanes. */
+ if (group1_size < i
+ && (i + 1 < group_size
+ || i - group1_size > 1))
{
- i = group1_size + const_nunits;
- if (i + 1 < group_size)
- rest = vect_split_slp_store_group (rest, const_nunits);
+ stmt_vec_info rest2 = rest;
+ rest = vect_split_slp_store_group (rest, i - group1_size);
+ if (i - group1_size > 1)
+ res |= vect_analyze_slp_instance (vinfo, bst_map,
+ rest2, max_tree_size);
}
+ /* Re-analyze the non-matching tail if it has at least
+ two lanes. */
if (i + 1 < group_size)
res |= vect_analyze_slp_instance (vinfo, bst_map,
rest, max_tree_size);