When no longer restricting vector types of externs/constants we
have to make sure to zero-pad elements in vect_create_constant_vectors
which was missing.  The testcases expands the already known case in
vectorizable_conversion which was tailored exactly to one input
and one output vector to the case of three output vectors produced
from two (or rather one and a half) input vectors.

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

        PR tree-optimization/127058
        PR tree-optimization/127051
        * tree-vect-slp.cc (vect_create_constant_vectors): Zero-pad
        excess elements.
        * tree-vect-stmts.cc (vect_create_vectorized_demotion_stmts):
        Change 'half' parameter to indicate optional fixed number
        of vectors to produce.
        (vectorizable_conversion): Adjust.

        * gcc.dg/vect/bb-slp-pr127051.c: New testcase.
        * gfortran.dg/vect/pr127058.f90: Likewise.
---
 gcc/testsuite/gcc.dg/vect/bb-slp-pr127051.c | 17 ++++++++++++++
 gcc/testsuite/gfortran.dg/vect/pr127058.f90 | 25 +++++++++++++++++++++
 gcc/tree-vect-data-refs.cc                  |  3 ++-
 gcc/tree-vect-slp.cc                        |  6 ++++-
 gcc/tree-vect-stmts.cc                      | 12 +++++-----
 5 files changed, 55 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr127051.c
 create mode 100644 gcc/testsuite/gfortran.dg/vect/pr127058.f90

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr127051.c 
b/gcc/testsuite/gcc.dg/vect/bb-slp-pr127051.c
new file mode 100644
index 00000000000..f1ef6704c02
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr127051.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mno-avx" { target { x86_64-*-* i?86-*-* } } } */
+
+int b(int c, int d, int e, int f, int g, int h)
+{
+  long long a = c;
+  a += d;
+  a += e;
+  a += f;
+  a += g;
+  a += h;
+  return a;
+}
+
+/* With SSE we should be able to reduce all 6 lanes with V2DI, two
+   vec_unpack_lo_expr and one vec_unpack_hi_expr (dumped twice).  */
+/* { dg-final { scan-tree-dump-times "vec_unpack" 6 "slp2" { target { 
x86_64-*-* i?86-*-* } } } } */
diff --git a/gcc/testsuite/gfortran.dg/vect/pr127058.f90 
b/gcc/testsuite/gfortran.dg/vect/pr127058.f90
new file mode 100644
index 00000000000..57c30621ea3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/vect/pr127058.f90
@@ -0,0 +1,25 @@
+! { dg-do compile }
+! { dg-additional-options "-Ofast" }
+! { dg-additional-options "-mcpu=neoverse-v1" { target { aarch64-*-* } } }
+
+MODULE a
+    integer, parameter ::      b = selected_real_kind(12)
+    integer, parameter :: d     =  10
+    real(b) e(1,d)
+    CONTAINS
+    SUBROUTINE f(ime ,jme)
+    REAL, DIMENSION( ime,d,jme )  :: g
+    INTEGER  c,h,l,k,aa,ab
+        DO h = jts,jte
+        DO l = its,aa
+        if (m.eq.1) THEN
+           do c = 1,ab
+            do k = 1,d
+               e(c,k) = g(i,k,j)
+            enddo
+            enddo
+        endif
+        end do
+    end do
+    end
+end
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index aab8ca21568..827e0965d9c 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -5354,7 +5354,8 @@ vect_analyze_data_refs (vec_info *vinfo, bool *fatal)
          tree init_offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset),
                                          init, offset);
          tree init_addr = fold_build_pointer_plus (base, init_offset);
-         tree init_ref = build_fold_indirect_ref (init_addr);
+         tree init_ref = build2 (MEM_REF, TREE_TYPE (DR_REF (dr)),
+                                 init_addr, build_zero_cst (ptr_type_node));
 
          if (dump_enabled_p ())
            dump_printf_loc (MSG_NOTE, vect_location,
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 18fb1168a3b..b5ac8a0e5d6 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -10908,11 +10908,15 @@ vect_create_constant_vectors (vec_info *vinfo, 
slp_tree op_node)
 
   number_of_copies = nunits * number_of_vectors / group_size;
 
-  number_of_places_left_in_vector = nunits;
   constant_p = true;
   tree uniform_elt = NULL_TREE;
   tree_vector_builder elts (vector_type, nunits, 1);
   elts.quick_grow (nunits);
+  /* Zero-pad the last vector if necessary.  */
+  number_of_places_left_in_vector
+    = nunits - nunits * number_of_vectors % group_size;
+  for (i = nunits; i > number_of_places_left_in_vector; --i)
+    elts[i-1] = build_zero_cst (TREE_TYPE (vector_type));
   stmt_vec_info insert_after = NULL;
   for (j = 0; j < number_of_copies; j++)
     {
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 62823cf547e..9a6d4176de4 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -5185,8 +5185,8 @@ vect_create_vectorized_demotion_stmts (vec_info *vinfo, 
vec<tree> *vec_oprnds,
 /* Create vectorized promotion statements for vector operands from VEC_OPRNDS0
    and VEC_OPRNDS1, for a binary operation associated with scalar statement
    STMT_INFO.  For multi-step conversions store the resulting vectors and
-   call the function recursively.  When HALF is true only generate half
-   of the result.  */
+   call the function recursively.  When NUM_VECTORS is not -1U then only
+   NUM_VECTORS will be produced.  */
 
 static void
 vect_create_vectorized_promotion_stmts (vec_info *vinfo,
@@ -5196,14 +5196,15 @@ vect_create_vectorized_promotion_stmts (vec_info *vinfo,
                                        gimple_stmt_iterator *gsi,
                                        code_helper ch1,
                                        code_helper ch2, int op_type,
-                                       bool half)
+                                       unsigned num_vectors)
 {
   int i;
   tree vop0, vop1, new_tmp1, new_tmp2;
   gimple *new_stmt1, *new_stmt2;
   vec<tree> vec_tmp = vNULL;
 
-  vec_tmp.create ((half ? 1 : 2) * vec_oprnds0->length ());
+  vec_tmp.create (num_vectors != -1U
+                 ? num_vectors : 2 * vec_oprnds0->length ());
   FOR_EACH_VEC_ELT (*vec_oprnds0, i, vop0)
     {
       if (op_type == binary_op)
@@ -5876,8 +5877,7 @@ vectorizable_conversion (vec_info *vinfo,
                                                    &vec_oprnds1, stmt_info,
                                                    this_dest, gsi,
                                                    c1, c2, op_type,
-                                                   vec_oprnds0.length ()
-                                                   == num_vectors);
+                                                   i == 0 ? num_vectors : -1u);
        }
 
       FOR_EACH_VEC_ELT (vec_oprnds0, i, vop0)
-- 
2.51.0

Reply via email to