diff options
author | Richard Biener <rguenther@suse.de> | 2021-10-25 13:39:07 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-10-26 12:29:48 +0200 |
commit | 94f28340513753ba94ab483e93ce1d096842a5ad (patch) | |
tree | 5003f5167c34608c17e64b23298438c50a57a2ed /gcc/tree-vect-data-refs.c | |
parent | 54e4e1769e44b925c35c0ffc11723027ff855bd7 (diff) | |
download | gcc-94f28340513753ba94ab483e93ce1d096842a5ad.zip gcc-94f28340513753ba94ab483e93ce1d096842a5ad.tar.gz gcc-94f28340513753ba94ab483e93ce1d096842a5ad.tar.bz2 |
Move negative stride bias out of dr_misalignment
This moves applying of a bias for negative stride accesses out of
dr_misalignment in favor of a more general optional offset argument.
The negative bias is now computed by get_load_store_type and applied
accordingly to determine the alignment support scheme. Likewise
the peeling/versioning code is adjusted albeit that still assumes
we'll end up with VMAT_CONTIGUOUS_DOWN or VMAT_CONTIGUOUS_REVERSE
but at least when not so (VMAT_STRIDED_SLP is one possibility) then
get_load_store_type will _not_ falsely report an aligned access but
instead an access with known misalignment.
This fixes PR96109.
2021-10-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/96109
* tree-vectorizer.h (dr_misalignment): Add optional offset
parameter.
* tree-vect-data-refs.c (dr_misalignment): Likewise. Remove
offset applied for negative stride accesses.
(vect_enhance_data_refs_alignment): Compute negative stride
access offset and pass it to dr_misalignment.
* tree-vect-stmts.c (get_negative_load_store_type): Pass
negative offset to dr_misalignment.
(get_group_load_store_type): Likewise.
(get_load_store_type): Likewise.
(vectorizable_store): Remove asserts about alignment.
(vectorizable_load): Likewise.
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 46360c5..cda89ef 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -887,10 +887,11 @@ vect_slp_analyze_instance_dependence (vec_info *vinfo, slp_instance instance) return res; } -/* Return the misalignment of DR_INFO accessed in VECTYPE. */ +/* Return the misalignment of DR_INFO accessed in VECTYPE with OFFSET + applied. */ int -dr_misalignment (dr_vec_info *dr_info, tree vectype) +dr_misalignment (dr_vec_info *dr_info, tree vectype, poly_int64 offset) { HOST_WIDE_INT diff = 0; /* Alignment is only analyzed for the first element of a DR group, @@ -919,13 +920,9 @@ dr_misalignment (dr_vec_info *dr_info, tree vectype) targetm.vectorize.preferred_vector_alignment (vectype))) return DR_MISALIGNMENT_UNKNOWN; - /* If this is a backward running DR then first access in the larger - vectype actually is N-1 elements before the address in the DR. - Adjust misalign accordingly. */ - poly_int64 misalignment = misalign + diff; - if (tree_int_cst_sgn (DR_STEP (dr_info->dr)) < 0) - misalignment += ((TYPE_VECTOR_SUBPARTS (vectype) - 1) - * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype)))); + /* Apply the offset from the DR group start and the externally supplied + offset which can for example result from a negative stride access. */ + poly_int64 misalignment = misalign + diff + offset; /* vect_compute_data_ref_alignment will have ensured that target_alignment is constant and otherwise set misalign to DR_MISALIGNMENT_UNKNOWN. */ @@ -1549,8 +1546,15 @@ vect_get_peeling_costs_all_drs (loop_vec_info loop_vinfo, int misalignment; unsigned HOST_WIDE_INT alignment; + bool negative = tree_int_cst_compare (DR_STEP (dr_info->dr), + size_zero_node) < 0; + poly_int64 off = 0; + if (negative) + off = ((TYPE_VECTOR_SUBPARTS (vectype) - 1) + * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype)))); + if (npeel == 0) - misalignment = dr_misalignment (dr_info, vectype); + misalignment = dr_misalignment (dr_info, vectype, off); else if (dr_info == dr0_info || vect_dr_aligned_if_peeled_dr_is (dr_info, dr0_info)) misalignment = 0; @@ -1560,7 +1564,7 @@ vect_get_peeling_costs_all_drs (loop_vec_info loop_vinfo, misalignment = DR_MISALIGNMENT_UNKNOWN; else { - misalignment = dr_misalignment (dr_info, vectype); + misalignment = dr_misalignment (dr_info, vectype, off); misalignment += npeel * TREE_INT_CST_LOW (DR_STEP (dr_info->dr)); misalignment &= alignment - 1; } @@ -1960,8 +1964,11 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) */ unsigned int target_align = DR_TARGET_ALIGNMENT (dr_info).to_constant (); - unsigned int dr_size = vect_get_scalar_dr_size (dr_info); - unsigned int mis = dr_misalignment (dr_info, vectype); + unsigned HOST_WIDE_INT dr_size = vect_get_scalar_dr_size (dr_info); + poly_int64 off = 0; + if (negative) + off = (TYPE_VECTOR_SUBPARTS (vectype) - 1) * -dr_size; + unsigned int mis = dr_misalignment (dr_info, vectype, off); mis = negative ? mis : -mis; if (mis != 0) npeel_tmp = (mis & (target_align - 1)) / dr_size; @@ -2238,8 +2245,13 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) updating DR_MISALIGNMENT values. The peeling factor is the vectorization factor minus the misalignment as an element count. */ + tree vectype = STMT_VINFO_VECTYPE (stmt_info); + poly_int64 off = 0; + if (negative) + off = ((TYPE_VECTOR_SUBPARTS (vectype) - 1) + * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype)))); unsigned int mis - = dr_misalignment (dr0_info, STMT_VINFO_VECTYPE (stmt_info)); + = dr_misalignment (dr0_info, vectype, off); mis = negative ? mis : -mis; /* If known_alignment_for_access_p then we have set DR_MISALIGNMENT which is only done if we know it at compiler @@ -2383,19 +2395,27 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) FOR_EACH_VEC_ELT (datarefs, i, dr) { dr_vec_info *dr_info = loop_vinfo->lookup_dr (dr); - stmt_vec_info stmt_info = dr_info->stmt; - tree vectype = STMT_VINFO_VECTYPE (stmt_info); - int misalignment; - if ((misalignment = dr_misalignment (dr_info, vectype)) == 0 - || !vect_relevant_for_alignment_p (dr_info)) + if (!vect_relevant_for_alignment_p (dr_info)) continue; + stmt_vec_info stmt_info = dr_info->stmt; if (STMT_VINFO_STRIDED_P (stmt_info)) { do_versioning = false; break; } + tree vectype = STMT_VINFO_VECTYPE (stmt_info); + bool negative = tree_int_cst_compare (DR_STEP (dr), + size_zero_node) < 0; + poly_int64 off = 0; + if (negative) + off = ((TYPE_VECTOR_SUBPARTS (vectype) - 1) + * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype)))); + int misalignment; + if ((misalignment = dr_misalignment (dr_info, vectype, off)) == 0) + continue; + enum dr_alignment_support supportable_dr_alignment = vect_supportable_dr_alignment (loop_vinfo, dr_info, vectype, misalignment); |