From 2b8b43c93c16e3e541e2a9310dec14b29dcd816c Mon Sep 17 00:00:00 2001
From: Fei Yang <felix.yang@huawei.com>
Date: Wed, 10 Jun 2020 11:21:18 +0800
Subject: [PATCH] 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-10  Felix Yang  <felix.yang@huawei.com>

gcc/
        PR tree-optimization/95570
        * tree-vect-data-refs.c (vect_verify_datarefs_alignment): Filter
        out gather-scatter and invariant accesses when iterating over all
        data references.
        (vect_get_peeling_costs_all_drs): Likewise.
        (vect_peeling_supportable): Likewise, and filter out irrelevant data
        references.
        (vect_enhance_data_refs_alignment): Likewise when checking if
        versioning for alignment is needed.

gcc/testsuite/

        PR tree-optimization/95570
        * gcc.dg/vect/pr95570.c: New test.
---
 gcc/testsuite/gcc.dg/vect/pr95570.c | 11 +++++++++++
 gcc/tree-vect-data-refs.c           | 30 ++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr95570.c

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 fe543606a52..3ccba9fb7c8 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -1170,7 +1170,6 @@ vect_verify_datarefs_alignment (loop_vec_info vinfo)
     {
       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;
 
@@ -1179,6 +1178,12 @@ vect_verify_datarefs_alignment (loop_vec_info vinfo)
 	  && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt_info)
 	continue;
 
+      /* For scatter-gather or invariant accesses there is nothing
+	 to enhance.  */
+      if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
+	  || integer_zerop (DR_STEP (dr)))
+	continue;
+
       /* Strided accesses perform only component accesses, alignment is
 	 irrelevant for them.  */
       if (STMT_VINFO_STRIDED_P (stmt_info)
@@ -1425,6 +1430,12 @@ vect_get_peeling_costs_all_drs (loop_vec_info loop_vinfo,
 	  && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt_info)
 	continue;
 
+      /* For scatter-gather or invariant accesses there is nothing
+	 to enhance.  */
+      if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
+	|| integer_zerop (DR_STEP (dr)))
+	continue;
+
       /* Strided accesses perform only component accesses, alignment is
          irrelevant for them.  */
       if (STMT_VINFO_STRIDED_P (stmt_info)
@@ -1549,12 +1560,21 @@ vect_peeling_supportable (loop_vec_info loop_vinfo, dr_vec_info *dr0_info,
 
       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;
 
+      /* For scatter-gather or invariant accesses there is nothing
+	 to enhance.  */
+      if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
+	|| integer_zerop (DR_STEP (dr)))
+	continue;
+
       /* Strided accesses perform only component accesses, alignment is
 	 irrelevant for them.  */
       if (STMT_VINFO_STRIDED_P (stmt_info)
@@ -2198,6 +2218,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
         {
 	  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.  */
@@ -2206,6 +2228,12 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
 		  && DR_GROUP_FIRST_ELEMENT (stmt_info) != stmt_info))
 	    continue;
 
+	  /* For scatter-gather or invariant accesses there is nothing
+	     to enhance.  */
+	  if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
+	    || integer_zerop (DR_STEP (dr)))
+	    continue;
+
 	  if (STMT_VINFO_STRIDED_P (stmt_info))
 	    {
 	      /* Strided loads perform only component accesses, alignment is
-- 
2.19.1

