Inductions are not vectorized as cycle but materialized from SCEV data.
Filling in backedge SLP nodes confuses this process.

Bootstrapped / tested on x86_64-unknown-linux-gnu, pushed.

2020-10-21  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/97500
        * tree-vect-slp.c (vect_analyze_slp_backedges): Do not
        fill backedges for inductions.

        * gfortran.dg/pr97500.f90: New testcase.
---
 gcc/testsuite/gfortran.dg/pr97500.f90 | 35 +++++++++++++++++++++++++++
 gcc/tree-vect-slp.c                   |  6 +++++
 2 files changed, 41 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/pr97500.f90

diff --git a/gcc/testsuite/gfortran.dg/pr97500.f90 
b/gcc/testsuite/gfortran.dg/pr97500.f90
new file mode 100644
index 00000000000..d63b8616ad6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr97500.f90
@@ -0,0 +1,35 @@
+! { dg-do run }
+! { dg-additional-options "-ftree-vectorize -fno-guess-branch-probability" }
+module testmod
+  implicit none
+
+  contains
+
+  subroutine foo(n)
+    integer, intent(in) :: n
+    real :: r(0:n,-n:n), a(0:n,-n:n), dj
+    integer :: k, j
+
+    ! initialize with some dummy values
+    do j = -n, n
+      a(:, j) = j
+      r(:,j) = j + 1
+    end do
+
+    ! here be dragons
+    do k = 0, n
+      dj = r(k, k - 2) * a(k, k - 2)
+      r(k,k) = a(k, k - 1) * dj
+    enddo
+
+    if (r(0,0) .ne. -2.) STOP 1
+
+  end subroutine
+
+end module
+
+program test
+  use testmod
+  implicit none
+  call foo(5)
+end program
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 0c1447e7aa0..e3f94cb8a2d 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2380,6 +2380,12 @@ vect_analyze_slp_backedges (vec_info *vinfo, slp_tree 
node,
     if (child)
       vect_analyze_slp_backedges (vinfo, child, bst_map, visited);
 
+  /* Inductions are not vectorized by vectorizing their defining cycle
+     but by materializing the values from SCEV data.  */
+  if (STMT_VINFO_DEF_TYPE (SLP_TREE_REPRESENTATIVE (node))
+      == vect_induction_def)
+    return;
+
   if (gphi *phi = dyn_cast <gphi *> (SLP_TREE_REPRESENTATIVE (node)->stmt))
     for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
       {
-- 
2.26.2

Reply via email to