summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr33953.c35
-rw-r--r--gcc/tree-vect-transform.c49
4 files changed, 87 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0d0f62beb1e..1093ef3b261 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2007-11-12 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/33953
+ * tree-vect-transform.c (vectorizable_operation): In case of SLP,
+ allocate vec_oprnds1 according to the number of created vector
+ statements. In case of shift with scalar argument, store scalar operand
+ for every vector statement to be created for the SLP node. Fix a
+ comment.
+
2007-11-10 Steven Bosscher <stevenb.gcc@gmail.com>
* gcse.c (CUID_INSN): Remove.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b55f3c053ee..476b82b63bf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-11-12 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/33953
+ * gcc.dg/vect/pr33953.c: New testcase.
+
2007-11-11 Tom Tromey <tromey@redhat.com>
PR c++/17577:
diff --git a/gcc/testsuite/gcc.dg/vect/pr33953.c b/gcc/testsuite/gcc.dg/vect/pr33953.c
new file mode 100644
index 00000000000..ef1e248d711
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr33953.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+typedef unsigned int UINT32;
+
+void blockmove_NtoN_blend_noremap32 (const UINT32 *srcdata, int srcwidth,
+ int srcheight, int srcmodulo,
+ UINT32 *dstdata, int dstmodulo,
+ int srcshift)
+{
+ UINT32 *end;
+
+ while (srcheight)
+ {
+ while (dstdata <= end - 8)
+ {
+ dstdata[0] |= srcdata[0] << srcshift;
+ dstdata[1] |= srcdata[1] << srcshift;
+ dstdata[2] |= srcdata[2] << srcshift;
+ dstdata[3] |= srcdata[3] << srcshift;
+ dstdata[4] |= srcdata[4] << srcshift;
+ dstdata[5] |= srcdata[5] << srcshift;
+ dstdata[6] |= srcdata[6] << srcshift;
+ dstdata[7] |= srcdata[7] << srcshift;
+ dstdata += 8;
+ srcdata += 8;
+ }
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
+
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index 736f0c9687d..faf3b3ade22 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -3785,6 +3785,8 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
int j, i;
VEC(tree,heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL;
tree vop0, vop1;
+ unsigned int k;
+ bool scalar_shift_arg = false;
/* FORNOW: SLP with multiple types is not supported. The SLP analysis verifies
this, so we can safely override NCOPIES with 1 here. */
@@ -3901,14 +3903,18 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
/* Invariant argument is needed for a vector shift
by a scalar shift operand. */
optab_op2_mode = insn_data[icode].operand[2].mode;
- if (! (VECTOR_MODE_P (optab_op2_mode)
- || dt[1] == vect_constant_def
- || dt[1] == vect_invariant_def))
+ if (!VECTOR_MODE_P (optab_op2_mode))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "operand mode requires invariant argument.");
- return false;
- }
+ if (dt[1] != vect_constant_def && dt[1] != vect_invariant_def)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "operand mode requires invariant"
+ " argument.");
+ return false;
+ }
+
+ scalar_shift_arg = true;
+ }
}
if (!vec_stmt) /* transformation not required. */
@@ -3928,10 +3934,21 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
/* Handle def. */
vec_dest = vect_create_destination_var (scalar_dest, vectype);
+ /* Allocate VECs for vector operands. In case of SLP, vector operands are
+ created in the previous stages of the recursion, so no allocation is
+ needed, except for the case of shift with scalar shift argument. In that
+ case we store the scalar operand in VEC_OPRNDS1 for every vector stmt to
+ be created to vectorize the SLP group, i.e., SLP_NODE->VEC_STMTS_SIZE.
+ In case of loop-based vectorization we allocate VECs of size 1. We
+ allocate VEC_OPRNDS1 only in case of binary operation. */
if (!slp_node)
- vec_oprnds0 = VEC_alloc (tree, heap, 1);
- if (op_type == binary_op)
- vec_oprnds1 = VEC_alloc (tree, heap, 1);
+ {
+ vec_oprnds0 = VEC_alloc (tree, heap, 1);
+ if (op_type == binary_op)
+ vec_oprnds1 = VEC_alloc (tree, heap, 1);
+ }
+ else if (scalar_shift_arg)
+ vec_oprnds1 = VEC_alloc (tree, heap, slp_node->vec_stmts_size);
/* In case the vectorization factor (VF) is bigger than the number
of elements that we can fit in a vectype (nunits), we have to generate
@@ -4006,10 +4023,20 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
fprintf (vect_dump, "operand 1 using scalar mode.");
vec_oprnd1 = op1;
VEC_quick_push (tree, vec_oprnds1, vec_oprnd1);
+ if (slp_node)
+ {
+ /* Store vec_oprnd1 for every vector stmt to be created
+ for SLP_NODE. We check during the analysis that all the
+ shift arguments are the same.
+ TODO: Allow different constants for different vector
+ stmts generated for an SLP instance. */
+ for (k = 0; k < slp_node->vec_stmts_size - 1; k++)
+ VEC_quick_push (tree, vec_oprnds1, vec_oprnd1);
+ }
}
}
- /* vec_oprnd is available if operand 1 should be of a scalar-type
+ /* vec_oprnd1 is available if operand 1 should be of a scalar-type
(a special case for certain kind of vector shifts); otherwise,
operand 1 should be of a vector type (the usual case). */
if (op_type == binary_op && !vec_oprnd1)