aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-06-03 13:10:13 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-06-03 13:10:13 +0000
commite004aa11b1d261b597aa3e062204af61762ba6a9 (patch)
treea02fed610be6458820ef2510b8d689c0791fa6aa /gcc
parentfddde8d3d82bf11fa191d067dcf3ed505224089a (diff)
downloadgcc-e004aa11b1d261b597aa3e062204af61762ba6a9.zip
gcc-e004aa11b1d261b597aa3e062204af61762ba6a9.tar.gz
gcc-e004aa11b1d261b597aa3e062204af61762ba6a9.tar.bz2
tree-vect-data-refs.c (vect_analyze_group_access): Properly compute GROUP_GAP for the first element.
2015-06-03 Richard Biener <rguenther@suse.de> * tree-vect-data-refs.c (vect_analyze_group_access): Properly compute GROUP_GAP for the first element. * tree-vect-slp.c (vect_build_slp_tree_1): Remove restriction on in-group gaps. * gcc.dg/vect/bb-slp-36.c: New testcase. From-SVN: r224077
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-36.c35
-rw-r--r--gcc/tree-vect-data-refs.c42
-rw-r--r--gcc/tree-vect-slp.c18
5 files changed, 76 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cab2f38..f4d83db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-06-03 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-data-refs.c (vect_analyze_group_access): Properly
+ compute GROUP_GAP for the first element.
+ * tree-vect-slp.c (vect_build_slp_tree_1): Remove restriction
+ on in-group gaps.
+
2015-06-03 Nick Clifton <nickc@redhat.com>
* config/rl78/rl78-real.md: Add peepholes to avoid a register
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5567282..43604b7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2015-06-03 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/vect/bb-slp-36.c: New testcase.
+
2015-06-03 Ilya Enkovich <ilya.enkovich@intel.com>
* gcc.dg/lto/chkp-removed-alias_0.c: New.
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-36.c b/gcc/testsuite/gcc.dg/vect/bb-slp-36.c
new file mode 100644
index 0000000..f424d12
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-36.c
@@ -0,0 +1,35 @@
+/* { dg-require-effective-target vect_int } */
+
+#include "tree-vect.h"
+
+extern void abort (void);
+
+int a[8], b[8];
+
+void __attribute__((noinline,noclone))
+foo(void)
+{
+ a[0] = b[0];
+ a[1] = b[0];
+ a[2] = b[3];
+ a[3] = b[3];
+ a[4] = b[4];
+ a[5] = b[7];
+ a[6] = b[4];
+ a[7] = b[7];
+}
+
+int main()
+{
+ int i;
+ check_vect ();
+ for (i = 0; i < 8; ++i)
+ b[i] = i;
+ foo ();
+ if (a[0] != 0 || a[1] != 0 || a[2] != 3 || a[3] != 3
+ || a[4] != 4 || a[5] != 7 || a[6] != 4 || a[7] != 7)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" { target vect_perm } } } */
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 5c3fa3d..a019dba 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -2205,29 +2205,33 @@ vect_analyze_group_access (struct data_reference *dr)
/* Check that the size of the interleaving is equal to count for stores,
i.e., that there are no gaps. */
- if (groupsize != count)
+ if (groupsize != count
+ && !DR_IS_READ (dr))
{
- if (DR_IS_READ (dr))
- {
- slp_impossible = true;
- /* There is a gap after the last load in the group. This gap is a
- difference between the groupsize and the number of elements.
- When there is no gap, this difference should be 0. */
- GROUP_GAP (vinfo_for_stmt (stmt)) = groupsize - count;
- }
- else
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "interleaved store with gaps\n");
- return false;
- }
- }
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "interleaved store with gaps\n");
+ return false;
+ }
+
+ /* If there is a gap after the last load in the group it is the
+ difference between the groupsize and the last accessed
+ element.
+ When there is no gap, this difference should be 0. */
+ GROUP_GAP (vinfo_for_stmt (stmt)) = groupsize - last_accessed_element;
GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize;
if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "Detected interleaving of size %d\n", (int)groupsize);
+ {
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Detected interleaving of size %d starting with ",
+ (int)groupsize);
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
+ if (GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "There is a gap of %d elements after the group\n",
+ (int)GROUP_GAP (vinfo_for_stmt (stmt)));
+ }
/* SLP: create an SLP data structure for every interleaving group of
stores for further analysis in vect_analyse_slp. */
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 9e36d9c..5fd1635 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -777,17 +777,13 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
(*max_nunits, group_size) / group_size;
/* FORNOW: Check that there is no gap between the loads
and no gap between the groups when we need to load
- multiple groups at once.
- ??? We should enhance this to only disallow gaps
- inside vectors. */
- if ((unrolling_factor > 1
- && ((GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
- && GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
- /* If the group is split up then GROUP_GAP
- isn't correct here, nor is GROUP_FIRST_ELEMENT. */
- || GROUP_SIZE (vinfo_for_stmt (stmt)) > group_size))
- || (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) != stmt
- && GROUP_GAP (vinfo_for_stmt (stmt)) != 1))
+ multiple groups at once. */
+ if (unrolling_factor > 1
+ && ((GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
+ && GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
+ /* If the group is split up then GROUP_GAP
+ isn't correct here, nor is GROUP_FIRST_ELEMENT. */
+ || GROUP_SIZE (vinfo_for_stmt (stmt)) > group_size))
{
if (dump_enabled_p ())
{