When checking whether a value that is used outside the vectorized
region can be supported, the vectorizable_live_operation function
calculates which vector contains the result, and which lane of that
vector we need. Previously, this calculation gave the wrong answer
for BB SLP with a variable-length vector type (eventually generating
invalid offsets such as BIT_FIELD_REF <_251, 32, POLY_INT_CST
[96, 128]> to access the third element of a group using type VNx4SI)
because it reused logic intended for loop vectorization, which selects
the 'last' occurrence of a scalar index relative to the group size
(which is a multiple of the vector length). For BB SLP with a
predicate mask, only the first SLP_TREE_LANES elements are well
defined.

gcc/ChangeLog:

        * tree-vect-loop.cc (vectorizable_live_operation): Simplify the
        calculation of the index of the final result to avoid
        generating invalid polynomial offsets relative to the end of
        variable-length vector types, which is what happens if the code
        for loop vectorization is reused for basic block SLP.
---
 gcc/tree-vect-loop.cc | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index ed1b131064a..448d0c3f27d 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -10250,12 +10250,16 @@ vectorizable_live_operation (vec_info *vinfo, 
stmt_vec_info stmt_info,
 
   gcc_assert (slp_index >= 0);
 
-  /* Get the last occurrence of the scalar index from the concatenation of
-     all the slp vectors. Calculate which slp vector it is and the index
-     within.  */
-  int num_scalar = SLP_TREE_LANES (slp_node);
   int num_vec = vect_get_num_copies (vinfo, slp_node);
-  poly_uint64 pos = (num_vec * nunits) - num_scalar + slp_index;
+  poly_uint64 pos = slp_index;
+  if (loop_vinfo)
+    {
+      /* Get the last occurrence of the scalar index from the concatenation of
+        all the slp vectors. Calculate which slp vector it is and the index
+        within.  */
+      int num_scalar = SLP_TREE_LANES (slp_node);
+      pos += (num_vec * nunits) - num_scalar;
+    }
 
   /* Calculate which vector contains the result, and which lane of
      that vector we need.  */
-- 
2.43.0

Reply via email to