From 66ff513e39b8d87b83e0a15d71f12b088374f3cd Mon Sep 17 00:00:00 2001
From: Felix Yang <felix.yang@huawei.com>
Date: Tue, 31 Mar 2020 16:41:56 +0800
Subject: [PATCH] vect: ICE: in vectorizable_load, at tree-vect-stmts.c:9173
 [PR94398]

In the testcase for PR94398, we're trying to compute:

  alignment_support_scheme
    = vect_supportable_dr_alignment (first_dr_info, false);
  gcc_assert (alignment_support_scheme);

even for VMAT_GATHER_SCATTER, which always accesses individual elements.
Here we should set alignment_support_scheme to dr_unaligned_supported
the gather/scatter case instead of calling vect_supportable_dr_alignment.

    2020-03-31  Felix Yang  <felix.yang@huawei.com>

    gcc/
    PR tree-optimization/94398
    * tree-vect-stmts.c (vectorizable_store): Instead of calling
    vect_supportable_dr_alignment, set alignment_support_scheme to
    dr_unaligned_supported for gather-scatter accesses.
    (vectorizable_load): Likewise.

    gcc/testsuite/
    PR tree-optimization/94398
    * gcc.target/aarch64/pr94398.c: New test.
---
 gcc/ChangeLog                              |  8 ++++++++
 gcc/testsuite/ChangeLog                    |  5 +++++
 gcc/testsuite/gcc.target/aarch64/pr94398.c | 24 ++++++++++++++++++++++++
 gcc/tree-vect-stmts.c                      | 20 ++++++++++++++++----
 4 files changed, 53 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/pr94398.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 101956a..5b8844b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2020-03-31  Felix Yang  <felix.yang@huawei.com>
+
+	PR tree-optimization/94398
+	* tree-vect-stmts.c (vectorizable_store): Instead of calling
+	vect_supportable_dr_alignment, set alignment_support_scheme to
+	dr_unaligned_supported for gather-scatter accesses.
+	(vectorizable_load): Likewise.
+
 2020-03-30  David Malcolm  <dmalcolm@redhat.com>
 
 	* lra.c (finish_insn_code_data_once): Set the array elements
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c72aa9a..23e43a5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-03-31  Felix Yang  <felix.yang@huawei.com>
+
+	PR tree-optimization/94398
+	* gcc.target/aarch64/pr94398.c: New test.
+
 2020-03-30  David Malcolm  <dmalcolm@redhat.com>
 
 	* jit.dg/all-non-failing-tests.h: Add test-empty.c
diff --git a/gcc/testsuite/gcc.target/aarch64/pr94398.c b/gcc/testsuite/gcc.target/aarch64/pr94398.c
new file mode 100644
index 0000000..42152cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr94398.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-vectorize -funsafe-math-optimizations -march=armv8.2-a+sve -mstrict-align" } */
+
+float
+foo(long n, float *x, int inc_x,
+            float *y, int inc_y)
+{
+  float dot = 0.0;
+  int ix = 0, iy = 0;
+
+  if (n < 0) {
+    return dot;
+  }
+
+  int i = 0;
+  while (i < n) {
+    dot += y[iy] * x[ix];
+    ix  += inc_x;
+    iy  += inc_y;
+    i++;
+  }
+
+  return dot;
+}
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 12beef6..46bc2bd 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -8051,8 +8051,14 @@ vectorizable_store (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
   auto_vec<tree> dr_chain (group_size);
   oprnds.create (group_size);
 
-  alignment_support_scheme
-    = vect_supportable_dr_alignment (first_dr_info, false);
+  /* Gather-scatter accesses perform only component accesses, alignment
+     is irrelevant for them.  */
+  if (memory_access_type == VMAT_GATHER_SCATTER)
+    alignment_support_scheme = dr_unaligned_supported;
+  else
+    alignment_support_scheme
+      = vect_supportable_dr_alignment (first_dr_info, false);
+
   gcc_assert (alignment_support_scheme);
   vec_loop_masks *loop_masks
     = (loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)
@@ -9168,8 +9174,14 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
       ref_type = reference_alias_ptr_type (DR_REF (first_dr_info->dr));
     }
 
-  alignment_support_scheme
-    = vect_supportable_dr_alignment (first_dr_info, false);
+  /* Gather-scatter accesses perform only component accesses, alignment
+     is irrelevant for them.  */
+  if (memory_access_type == VMAT_GATHER_SCATTER)
+    alignment_support_scheme = dr_unaligned_supported;
+  else
+    alignment_support_scheme
+      = vect_supportable_dr_alignment (first_dr_info, false);
+
   gcc_assert (alignment_support_scheme);
   vec_loop_masks *loop_masks
     = (loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)
-- 
1.8.3.1

