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  <felix.yang@huawei.com>

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.
This commit is contained in:
Fei Yang 2020-06-12 11:37:00 +01:00 committed by Richard Sandiford
parent 135a8ad3a5
commit d30846a02e
2 changed files with 45 additions and 49 deletions

View file

@ -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;
}

View file

@ -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;
}