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