aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-03-28 09:55:15 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-03-28 09:55:15 +0000
commita64b9c261d9d2c12b98bd14f5f1bf27e3bcb6bdd (patch)
treefcc4b9380bfadbb4d5f3785c7d03fcf3f6818fc9 /gcc
parenta9dc2a2f95a6a88c99a75aa16f7a43f2c2c3e93a (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/vect/O3-pr36098.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-slp-38.c22
-rw-r--r--gcc/tree-vect-slp.c20
-rw-r--r--gcc/tree-vect-stmts.c18
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)