diff options
author | Richard Biener <rguenther@suse.de> | 2020-07-07 13:57:40 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2020-07-07 16:09:21 +0200 |
commit | f75211822f8d84bb706421d3692e6c1cdbdfc3a8 (patch) | |
tree | 9a9dee5881ce201dd515b0036a850fc16f80b743 /gcc/tree-vect-data-refs.c | |
parent | e1b0956a8e1f5609266cbe064b345bbb37b1e7e2 (diff) | |
download | gcc-f75211822f8d84bb706421d3692e6c1cdbdfc3a8.zip gcc-f75211822f8d84bb706421d3692e6c1cdbdfc3a8.tar.gz gcc-f75211822f8d84bb706421d3692e6c1cdbdfc3a8.tar.bz2 |
fix detection of negative step DR groups
This fixes a condition that caused all negative step DR groups to
be detected as single element interleaving. Such groups are
rejected by interleaving vectorization but miscompiled by SLP
which is fixed by forcing VMAT_STRIDED_SLP for now.
2020-07-07 Richard Biener <rguenther@suse.de>
* tree-vect-data-refs.c (vect_analyze_data_ref_accesses): Fix
group overlap condition to allow negative step DR groups.
* tree-vect-stmts.c (get_group_load_store_type): For
multi element SLP groups force VMAT_STRIDED_SLP when the step
is negative.
* gcc.dg/vect/slp-47.c: New testcase.
* gcc.dg/vect/slp-48.c: Likewise.
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 959c2d3..2b4421b 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3074,13 +3074,15 @@ vect_analyze_data_ref_accesses (vec_info *vinfo) if (!DR_IS_READ (dra) && init_b - init_prev != type_size_a) break; - /* If the step (if not zero or non-constant) is greater than the + /* If the step (if not zero or non-constant) is smaller than the difference between data-refs' inits this splits groups into suitable sizes. */ if (tree_fits_shwi_p (DR_STEP (dra))) { - HOST_WIDE_INT step = tree_to_shwi (DR_STEP (dra)); - if (step != 0 && step <= (init_b - init_a)) + unsigned HOST_WIDE_INT step + = absu_hwi (tree_to_shwi (DR_STEP (dra))); + if (step != 0 + && step <= (unsigned HOST_WIDE_INT)(init_b - init_a)) break; } } |