re PR tree-optimization/37021 (Fortran Complex reduction / multiplication not vectorized)
authorRichard Biener <rguenther@suse.de>
Thu, 28 Mar 2013 09:55:15 +0000 (09:55 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 28 Mar 2013 09:55:15 +0000 (09:55 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/O3-pr36098.c
gcc/testsuite/gcc.dg/vect/fast-math-slp-38.c [new file with mode: 0644]
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c

index 2dda70c13820af377c47a853eca7507d2d6a14f7..8a96fcb7cdb3d54095fe2812f8b409ff724b94b7 100644 (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
index 386779695d2a5c1df36bfddc8aeb7ce3729dd820..ca732361f513c2e1ad04bd7f71d2bbaca621f358 100644 (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
index 1c445be9e204a07b82b2402e0a07869145f068a2..9e87b2372db8e0b58f0351b5aaaded401965c797 100644 (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" } } */
-
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 (file)
index 0000000..241f9f5
--- /dev/null
@@ -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" } } */
index 8ef5d0684b48271145c4a4b0c571b1f08f711692..e925f57a2f5f015d342c9406ecfcd3967e5cab68 100644 (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 ())
                     {
index a7144288f1ffae4c98df21235b3891002a1688a7..4bd841564188d71214c0d34f57bf1ceba4050f41 100644 (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)