From e004aa11b1d261b597aa3e062204af61762ba6a9 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 3 Jun 2015 13:10:13 +0000 Subject: [PATCH] tree-vect-data-refs.c (vect_analyze_group_access): Properly compute GROUP_GAP for the first element. 2015-06-03 Richard Biener * 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 --- gcc/ChangeLog | 7 +++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/vect/bb-slp-36.c | 35 ++++++++++++++++++++++ gcc/tree-vect-data-refs.c | 42 +++++++++++++++------------ gcc/tree-vect-slp.c | 18 +++++------- 5 files changed, 76 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-36.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cab2f38ad3c..f4d83dbfb6f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-06-03 Richard Biener + + * 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 * config/rl78/rl78-real.md: Add peepholes to avoid a register diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 55672821460..43604b732dc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-06-03 Richard Biener + + * gcc.dg/vect/bb-slp-36.c: New testcase. + 2015-06-03 Ilya Enkovich * 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 00000000000..f424d128353 --- /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 5c3fa3d56d9..a019dba3ebd 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 9e36d9cccab..5fd16352e39 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 ()) { -- 2.30.2