From: Fei Yang Date: Fri, 12 Jun 2020 10:37:00 +0000 (+0100) Subject: vect: Fix an ICE in vect_loop_versioning [PR95570] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d30846a02eb9ea43b61311e74fbf05692ffefba2;p=gcc.git vect: Fix an ICE in vect_loop_versioning [PR95570] In the test case for PR95570, the only data reference in the loop is a gather-statter access. Scalar evolution analysis for this data reference failed, so DR_STEP is NULL_TREE. This leads to the segmentation fault. We should filter out scatter-gather access in vect_enhance_data_refs_alignment. 2020-06-12 Felix Yang gcc/ PR tree-optimization/95570 * tree-vect-data-refs.c (vect_relevant_for_alignment_p): New function. (vect_verify_datarefs_alignment): Call it to filter out data references in the loop whose alignment is irrelevant. (vect_get_peeling_costs_all_drs): Likewise. (vect_peeling_supportable): Likewise. (vect_enhance_data_refs_alignment): Likewise. gcc/testsuite/ PR tree-optimization/95570 * gcc.dg/vect/pr95570.c: New test. --- diff --git a/gcc/testsuite/gcc.dg/vect/pr95570.c b/gcc/testsuite/gcc.dg/vect/pr95570.c new file mode 100644 index 00000000000..b9362614004 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr95570.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a+sve -msve-vector-bits=256 -mstrict-align -fwrapv" { target aarch64*-*-* } } */ + +int x[8][32]; + +void +foo (int start) +{ + for (int i = start; i < start + 16; i++) + x[start][i] = i; +} diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 39d5a1b554c..3e86980172e 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -1129,6 +1129,35 @@ vect_update_misalignment_for_peel (dr_vec_info *dr_info, SET_DR_MISALIGNMENT (dr_info, DR_MISALIGNMENT_UNKNOWN); } +/* Return true if alignment is relevant for DR_INFO. */ + +static bool +vect_relevant_for_alignment_p (dr_vec_info *dr_info) +{ + stmt_vec_info stmt_info = dr_info->stmt; + + if (!STMT_VINFO_RELEVANT_P (stmt_info)) + return false; + + /* For interleaving, only the alignment of the first access matters. */ + if (STMT_VINFO_GROUPED_ACCESS (stmt_info) + && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt_info) + return false; + + /* Scatter-gather and invariant accesses continue to address individual + scalars, so vector-level alignment is irrelevant. */ + if (STMT_VINFO_GATHER_SCATTER_P (stmt_info) + || integer_zerop (DR_STEP (dr_info->dr))) + return false; + + /* Strided accesses perform only component accesses, alignment is + irrelevant for them. */ + if (STMT_VINFO_STRIDED_P (stmt_info) + && !STMT_VINFO_GROUPED_ACCESS (stmt_info)) + return false; + + return true; +} /* Function verify_data_ref_alignment @@ -1169,20 +1198,7 @@ vect_verify_datarefs_alignment (loop_vec_info vinfo) FOR_EACH_VEC_ELT (datarefs, i, dr) { dr_vec_info *dr_info = vinfo->lookup_dr (dr); - stmt_vec_info stmt_info = dr_info->stmt; - - if (!STMT_VINFO_RELEVANT_P (stmt_info)) - continue; - - /* For interleaving, only the alignment of the first access matters. */ - if (STMT_VINFO_GROUPED_ACCESS (stmt_info) - && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt_info) - continue; - - /* Strided accesses perform only component accesses, alignment is - irrelevant for them. */ - if (STMT_VINFO_STRIDED_P (stmt_info) - && !STMT_VINFO_GROUPED_ACCESS (stmt_info)) + if (!vect_relevant_for_alignment_p (dr_info)) continue; opt_result res = verify_data_ref_alignment (vinfo, dr_info); @@ -1415,20 +1431,7 @@ vect_get_peeling_costs_all_drs (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; - if (!STMT_VINFO_RELEVANT_P (stmt_info)) - continue; - - /* For interleaving, only the alignment of the first access - matters. */ - if (STMT_VINFO_GROUPED_ACCESS (stmt_info) - && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt_info) - continue; - - /* Strided accesses perform only component accesses, alignment is - irrelevant for them. */ - if (STMT_VINFO_STRIDED_P (stmt_info) - && !STMT_VINFO_GROUPED_ACCESS (stmt_info)) + if (!vect_relevant_for_alignment_p (dr_info)) continue; int save_misalignment; @@ -1548,17 +1551,7 @@ vect_peeling_supportable (loop_vec_info loop_vinfo, dr_vec_info *dr0_info, continue; dr_vec_info *dr_info = loop_vinfo->lookup_dr (dr); - stmt_vec_info stmt_info = dr_info->stmt; - /* For interleaving, only the alignment of the first access - matters. */ - if (STMT_VINFO_GROUPED_ACCESS (stmt_info) - && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt_info) - continue; - - /* Strided accesses perform only component accesses, alignment is - irrelevant for them. */ - if (STMT_VINFO_STRIDED_P (stmt_info) - && !STMT_VINFO_GROUPED_ACCESS (stmt_info)) + if (!vect_relevant_for_alignment_p (dr_info)) continue; save_misalignment = DR_MISALIGNMENT (dr_info); @@ -2197,21 +2190,13 @@ 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; - - /* For interleaving, only the alignment of the first access - matters. */ if (aligned_access_p (dr_info) - || (STMT_VINFO_GROUPED_ACCESS (stmt_info) - && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt_info)) + || !vect_relevant_for_alignment_p (dr_info)) continue; + stmt_vec_info stmt_info = dr_info->stmt; if (STMT_VINFO_STRIDED_P (stmt_info)) { - /* Strided loads perform only component accesses, alignment is - irrelevant for them. */ - if (!STMT_VINFO_GROUPED_ACCESS (stmt_info)) - continue; do_versioning = false; break; }