vect: Fix an ICE in vect_loop_versioning [PR95570]
authorFei Yang <felix.yang@huawei.com>
Fri, 12 Jun 2020 10:37:00 +0000 (11:37 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Fri, 12 Jun 2020 10:37:00 +0000 (11:37 +0100)
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.

gcc/testsuite/gcc.dg/vect/pr95570.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c

diff --git a/gcc/testsuite/gcc.dg/vect/pr95570.c b/gcc/testsuite/gcc.dg/vect/pr95570.c
new file mode 100644 (file)
index 0000000..b936261
--- /dev/null
@@ -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;
+}
index 39d5a1b554c5422c529a947faa798e142cdfc7aa..3e86980172ee267893d7fcead2414d311d7ec55e 100644 (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;
            }