aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2018-08-22 12:59:08 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-08-22 12:59:08 +0000
commit203942b8af64926d787b4a545184866f9572978d (patch)
treeffad8552037dadd3226d870423889ab2c571d625 /gcc/tree-vect-data-refs.c
parent3ad3b3ac8c3eae606897ceba5811760f030fdac1 (diff)
downloadgcc-203942b8af64926d787b4a545184866f9572978d.zip
gcc-203942b8af64926d787b4a545184866f9572978d.tar.gz
gcc-203942b8af64926d787b4a545184866f9572978d.tar.bz2
Make the vectoriser drop to strided accesses for stores with gaps
We could vectorise: for (...) { a[0] = ...; a[1] = ...; a[2] = ...; a[3] = ...; a += stride; } (including the case when stride == 8) but not: for (...) { a[0] = ...; a[1] = ...; a[2] = ...; a[3] = ...; a += 8; } (where the stride is always 8). The former was treated as a "grouped and strided" store, while the latter was treated as a grouped store with gaps, which we don't support. This patch makes us treat groups of stores with gaps at the end as strided groups too. I tried to go through all uses of STMT_VINFO_STRIDED_P and all vector uses of DR_STEP to see whether there were any hard-baked assumptions, but couldn't see any. I wondered whether we should relax: /* We do not have to consider dependences between accesses that belong to the same group, unless the stride could be smaller than the group size. */ if (DR_GROUP_FIRST_ELEMENT (stmtinfo_a) && (DR_GROUP_FIRST_ELEMENT (stmtinfo_a) == DR_GROUP_FIRST_ELEMENT (stmtinfo_b)) && !STMT_VINFO_STRIDED_P (stmtinfo_a)) return false; for cases in which the step is constant and the absolute step is known to be greater than the group size, but data dependence analysis should already return chrec_known for those cases. The new test is a version of vect-avg-15.c with the variable step replaced by a constant one. A natural follow-on would be to do the same for groups with gaps in the middle: /* Check that the distance between two accesses is equal to the type size. Otherwise, we have gaps. */ diff = (TREE_INT_CST_LOW (DR_INIT (data_ref)) - TREE_INT_CST_LOW (prev_init)) / type_size; if (diff != 1) { [...] if (DR_IS_WRITE (data_ref)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "interleaved store with gaps\n"); return false; } But I think we should do that separately and see what the fallout from this change is first. 2018-08-22 Richard Sandiford <richard.sandiford@arm.com> gcc/ * tree-vect-data-refs.c (vect_analyze_group_access_1): Convert grouped stores with gaps to a strided group. gcc/testsuite/ * gcc.dg/vect/vect-avg-16.c: New test. * gcc.dg/vect/slp-37.c: Expect the loop to be vectorized. * gcc.dg/vect/vect-strided-u8-i8-gap4.c, * gcc.dg/vect/vect-strided-u8-i8-gap4-big-array.c: Likewise for the second loop in main1. From-SVN: r263772
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r--gcc/tree-vect-data-refs.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index d70d207..e0d0533 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -2633,10 +2633,8 @@ vect_analyze_group_access_1 (dr_vec_info *dr_info)
if (groupsize != count
&& !DR_IS_READ (dr))
{
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "interleaved store with gaps\n");
- return false;
+ groupsize = count;
+ STMT_VINFO_STRIDED_P (stmt_info) = true;
}
/* If there is a gap after the last load in the group it is the
@@ -2652,6 +2650,8 @@ vect_analyze_group_access_1 (dr_vec_info *dr_info)
"Detected interleaving ");
if (DR_IS_READ (dr))
dump_printf (MSG_NOTE, "load ");
+ else if (STMT_VINFO_STRIDED_P (stmt_info))
+ dump_printf (MSG_NOTE, "strided store ");
else
dump_printf (MSG_NOTE, "store ");
dump_printf (MSG_NOTE, "of size %u starting with ",