diff options
author | Richard Biener <rguenther@suse.de> | 2013-03-28 09:55:15 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-03-28 09:55:15 +0000 |
commit | a64b9c261d9d2c12b98bd14f5f1bf27e3bcb6bdd (patch) | |
tree | fcc4b9380bfadbb4d5f3785c7d03fcf3f6818fc9 | |
parent | a9dc2a2f95a6a88c99a75aa16f7a43f2c2c3e93a (diff) | |
download | gcc-a64b9c261d9d2c12b98bd14f5f1bf27e3bcb6bdd.zip gcc-a64b9c261d9d2c12b98bd14f5f1bf27e3bcb6bdd.tar.gz gcc-a64b9c261d9d2c12b98bd14f5f1bf27e3bcb6bdd.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/O3-pr36098.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/fast-math-slp-38.c | 22 | ||||
-rw-r--r-- | gcc/tree-vect-slp.c | 20 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 18 |
6 files changed, 67 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2dda70c..8a96fcb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3867796..ca73236 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/vect/O3-pr36098.c b/gcc/testsuite/gcc.dg/vect/O3-pr36098.c index 1c445be..9e87b23 100644 --- a/gcc/testsuite/gcc.dg/vect/O3-pr36098.c +++ b/gcc/testsuite/gcc.dg/vect/O3-pr36098.c @@ -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" } } */ - diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-slp-38.c b/gcc/testsuite/gcc.dg/vect/fast-math-slp-38.c new file mode 100644 index 0000000..241f9f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-slp-38.c @@ -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" } } */ diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 8ef5d06..e925f57 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -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 ()) { diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index a714428..4bd8415 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -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) |