re PR tree-optimization/81410 (-O3 breaks code)
authorRichard Biener <rguenther@suse.de>
Tue, 18 Jul 2017 13:55:47 +0000 (13:55 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 18 Jul 2017 13:55:47 +0000 (13:55 +0000)
2017-06-18  Richard Biener  <rguenther@suse.de>

PR tree-optimization/81410
* tree-vect-stmts.c (vectorizable_load): Properly adjust for
the gap in the ! slp_perm SLP case after each group.

* gcc.dg/vect/pr81410.c: New testcase.

From-SVN: r250312

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr81410.c [new file with mode: 0644]
gcc/tree-vect-stmts.c

index 601de6a110ad71d7d99abaf1beb7c27a59f1db3e..d6ffb757d01d55b43807050b3be8833f9a566c2a 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-18  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81410
+       * tree-vect-stmts.c (vectorizable_load): Properly adjust for
+       the gap in the ! slp_perm SLP case after each group.
+
 2017-07-18  Jan Hubicka  <hubicka@ucw.cz>
 
        PR middle-end/81463
index 01f24abca7cd3454d4bc5091fc5aed1c019b7e09..80d57b8773dca16b3025ad55a11191c7d556a409 100644 (file)
@@ -1,3 +1,8 @@
+2017-06-18  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81410
+       * gcc.dg/vect/pr81410.c: New testcase.
+
 2017-07-18  Jan Hubicka  <hubicka@ucw.cz>
 
        PR middle-end/81462
diff --git a/gcc/testsuite/gcc.dg/vect/pr81410.c b/gcc/testsuite/gcc.dg/vect/pr81410.c
new file mode 100644 (file)
index 0000000..929850f
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_long_long } */
+
+#include "tree-vect.h"
+
+typedef long long uint64_t;
+uint64_t x[24];
+uint64_t y[16];
+uint64_t z[8];
+
+void __attribute__((noinline)) foo()
+{
+  for (int i = 0; i < 8; ++i)
+    {
+      y[2*i] = x[3*i];
+      y[2*i + 1] = x[3*i + 1];
+      z[i] = 1;
+    }
+}
+
+int main()
+{
+  check_vect ();
+
+  for (int i = 0; i < 24; ++i)
+    {
+      x[i] = i;
+      __asm__ volatile ("" : : : "memory");
+    }
+  foo ();
+  for (int i = 0; i < 8; ++i)
+    if (y[2*i] != 3*i || y[2*i+1] != 3*i + 1)
+      __builtin_abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
index 90770a35af1adee8e14ef907efcc2b5339677753..c50555499d295cec663cf32d29f43bdcb3d8da99 100644 (file)
@@ -7118,6 +7118,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
     {
       first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
       group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
+      int group_gap = GROUP_GAP (vinfo_for_stmt (first_stmt));
       /* For SLP vectorization we directly vectorize a subchain
          without permutation.  */
       if (slp && ! SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
@@ -7153,10 +7154,15 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
             not only the number of vector stmts the permutation result
             fits in.  */
          if (slp_perm)
-           vec_num = (group_size * vf + nunits - 1) / nunits;
+           {
+             vec_num = (group_size * vf + nunits - 1) / nunits;
+             group_gap_adj = vf * group_size - nunits * vec_num;
+           }
          else
-           vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
-         group_gap_adj = vf * group_size - nunits * vec_num;
+           {
+             vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
+             group_gap_adj = group_gap;
+           }
        }
       else
        vec_num = group_size;
@@ -7316,6 +7322,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
     aggr_type = vectype;
 
   prev_stmt_info = NULL;
+  int group_elt = 0;
   for (j = 0; j < ncopies; j++)
     {
       /* 1. Create the vector or array pointer update chain.  */
@@ -7603,10 +7610,27 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
              /* Store vector loads in the corresponding SLP_NODE.  */
              if (slp && !slp_perm)
                SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
+
+             /* With SLP permutation we load the gaps as well, without
+                we need to skip the gaps after we manage to fully load
+                all elements.  group_gap_adj is GROUP_SIZE here.  */
+             group_elt += nunits;
+             if (group_gap_adj != 0 && ! slp_perm
+                 && group_elt == group_size - group_gap_adj)
+               {
+                 bool ovf;
+                 tree bump
+                   = wide_int_to_tree (sizetype,
+                                       wi::smul (TYPE_SIZE_UNIT (elem_type),
+                                                 group_gap_adj, &ovf));
+                 dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
+                                                stmt, bump);
+                 group_elt = 0;
+               }
            }
          /* Bump the vector pointer to account for a gap or for excess
             elements loaded for a permuted SLP load.  */
-         if (group_gap_adj != 0)
+         if (group_gap_adj != 0 && slp_perm)
            {
              bool ovf;
              tree bump