re PR tree-optimization/37021 (Fortran Complex reduction / multiplication not vectorized)

2013-03-28  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/37021
	* tree-vect-slp.c (vect_build_slp_tree): When not unrolling
	do not restrict gaps between groups.
	* tree-vect-stmts.c (vectorizable_load): Properly account for
	a gap between groups.

	* gcc.dg/vect/fast-math-slp-38.c: New testcase.
	* gcc.dg/vect/O3-pr36098.c: Un-XFAIL.

From-SVN: r197189
This commit is contained in:
Richard Biener 2013-03-28 09:55:15 +00:00 committed by Richard Biener
parent a9dc2a2f95
commit a64b9c261d
6 changed files with 67 additions and 10 deletions

View File

@ -1,3 +1,11 @@
2013-03-28 Richard Biener <rguenther@suse.de>
PR tree-optimization/37021
* tree-vect-slp.c (vect_build_slp_tree): When not unrolling
do not restrict gaps between groups.
* tree-vect-stmts.c (vectorizable_load): Properly account for
a gap between groups.
2013-03-28 Eric Botcazou <ebotcazou@adacore.com>
* toplev.c (process_options): Do not disable -fomit-frame-pointer on a

View File

@ -1,3 +1,9 @@
2013-03-28 Richard Biener <rguenther@suse.de>
PR tree-optimization/37021
* gcc.dg/vect/fast-math-slp-38.c: New testcase.
* gcc.dg/vect/O3-pr36098.c: Un-XFAIL.
2013-03-27 Tobias Burnus <burnus@net-b.de>
PR fortran/56650

View File

@ -17,6 +17,5 @@ void foo (int ncons, t_sortblock *sb, int *iatom)
iatom[m]=sb[i].iatom[m];
}
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */

View File

@ -0,0 +1,22 @@
/* { dg-do compile } */
/* { dg-require-effective-target vect_double } */
double self[1024];
double a[1024][1024];
double b[1024];
void __attribute__((noinline,noclone))
foo (void)
{
int i, j;
for (i = 0; i < 1024; i+=6)
for (j = 0; j < 1024; j+=6)
{
self[i] = self[i] + a[i][j]*b[j];
self[i+1] = self[i+1] + a[i][j+1]*b[j+1];
}
}
/* { 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" } } */

View File

@ -740,11 +740,16 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
else
{
/* Load. */
/* FORNOW: Check that there is no gap between the loads. */
if ((GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
&& GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
|| (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) != stmt
&& GROUP_GAP (vinfo_for_stmt (stmt)) != 1))
/* FORNOW: Check that there is no gap between the loads
and no gap between the groups when we need to load
multiple groups at once.
??? We should enhance this to only disallow gaps
inside vectors. */
if ((ncopies > 1
&& GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
&& GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
|| (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) != stmt
&& GROUP_GAP (vinfo_for_stmt (stmt)) != 1))
{
if (dump_enabled_p ())
{
@ -762,7 +767,10 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
/* Check that the size of interleaved loads group is not
greater than the SLP group size. */
if (loop_vinfo
&& GROUP_SIZE (vinfo_for_stmt (stmt)) > ncopies * group_size)
&& GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
&& ((GROUP_SIZE (vinfo_for_stmt (stmt))
- GROUP_GAP (vinfo_for_stmt (stmt)))
> ncopies * group_size))
{
if (dump_enabled_p ())
{

View File

@ -4316,7 +4316,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
gimple ptr_incr;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies;
int i, j, group_size;
int i, j, group_size, group_gap;
tree msq = NULL_TREE, lsq;
tree offset = NULL_TREE;
tree realignment_token = NULL_TREE;
@ -4766,15 +4766,20 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
if (SLP_INSTANCE_LOAD_PERMUTATION (slp_node_instance).exists ())
slp_perm = true;
group_gap = GROUP_GAP (vinfo_for_stmt (first_stmt));
}
else
vec_num = group_size;
{
vec_num = group_size;
group_gap = 0;
}
}
else
{
first_stmt = stmt;
first_dr = dr;
group_size = vec_num = 1;
group_gap = 0;
}
alignment_support_scheme = vect_supportable_dr_alignment (first_dr, false);
@ -5134,6 +5139,15 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (slp && !slp_perm)
SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
}
/* Bump the vector pointer to account for a gap. */
if (slp && group_gap != 0)
{
tree bump = size_binop (MULT_EXPR,
TYPE_SIZE_UNIT (elem_type),
size_int (group_gap));
dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
stmt, bump);
}
}
if (slp && !slp_perm)