re PR middle-end/66251 (ICE in vect_get_vec_def_for_operand, at tree-vect-stmts.c...
authorMichael Matz <matz@suse.de>
Tue, 26 May 2015 16:00:32 +0000 (16:00 +0000)
committerMichael Matz <matz@gcc.gnu.org>
Tue, 26 May 2015 16:00:32 +0000 (16:00 +0000)
PR middle-end/66251

* tree-vect-stmts.c (vect_model_store_cost): Handled strided group
stores.
(vect_create_vectorized_demotion_stmts): Always set
STMT_VINFO_VEC_STMT, also with SLP.
(vectorizable_store): Handle strided group stores.

testsuite/:
PR middle-end/66251
* gcc.dg/vect/pr66251.c: New test.

From-SVN: r223704

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

index cc7c30a88975149ade128354f91a588e836bb0a3..69289e6a8df83503439eabaf531fda2e74036a74 100644 (file)
@@ -1,3 +1,13 @@
+2015-05-26  Michael Matz  <matz@suse.de>
+
+       PR middle-end/66251
+
+       * tree-vect-stmts.c (vect_model_store_cost): Handled strided group
+       stores.
+       (vect_create_vectorized_demotion_stmts): Always set
+       STMT_VINFO_VEC_STMT, also with SLP.
+       (vectorizable_store): Handle strided group stores.
+
 2015-05-26  Venkataramanan Kumar  <venkataramanan.kumar@amd.com>
 
        PR target/66049
index aa74501e1f513aff2fd724779a4456914bd74e0c..7ed1c92d27e396652267bd1ad2b3b602cd0782a8 100644 (file)
@@ -1,3 +1,8 @@
+2015-05-26  Michael Matz  <matz@suse.de>
+
+       PR middle-end/66251
+       * gcc.dg/vect/pr66251.c: New test.
+
 2015-05-26  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/66142
diff --git a/gcc/testsuite/gcc.dg/vect/pr66251.c b/gcc/testsuite/gcc.dg/vect/pr66251.c
new file mode 100644 (file)
index 0000000..e39f700
--- /dev/null
@@ -0,0 +1,79 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_double } */
+/* { dg-require-effective-target vect_floatint_cvt } */
+/* { dg-require-effective-target vect_intfloat_cvt } */
+/* { dg-require-effective-target vect_pack_trunc } */
+/* { dg-require-effective-target vect_unpack } */
+/* { dg-require-effective-target vect_hw_misalign } */
+
+#include "tree-vect.h"
+
+void __attribute__((noinline,noclone))
+test1(_Complex double *a, _Complex int *b, int stride, int n)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    {
+      a[i*stride] = b[i*stride];
+    }
+}
+
+void __attribute__((noinline,noclone))
+test2(_Complex int *a, _Complex double *b, int stride, int n)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    {
+      a[i*stride] = b[i*stride];
+    }
+}
+
+_Complex int ia[256];
+_Complex double da[256];
+
+extern void abort (void);
+
+int main ()
+{
+  int i;
+  int stride;
+
+  check_vect ();
+
+  for (stride = 1; stride < 15; stride++)
+    {
+      for (i = 0; i < 256; i++)
+       {
+         __real__ ia[i] = (i + stride) % 19;
+         __imag__ ia[i] = (i + stride) % 23;
+         __asm__ volatile ("");
+       }
+
+      test1(da, ia, stride, 256/stride);
+
+      for (i = 0; i < 256/stride; i++)
+       {
+         if (da[i*stride] != ia[i*stride])
+           abort ();
+       }
+
+      for (i = 0; i < 256; i++)
+       {
+         __real__ da[i] = (i + stride + 1) % 29;
+         __imag__ da[i] = (i + stride + 1) % 31;
+         __asm__ volatile ("");
+       }
+
+      test2(ia, da, stride, 256/stride);
+
+      for (i = 0; i < 256/stride; i++)
+       {
+         if (da[i*stride] != ia[i*stride])
+           abort ();
+       }
+    }
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
index 1e7b13562df1e4eb5f67d2fc8a567e33a22533f5..83039f1ad39474c268cfe08df964a25a31f5b965 100644 (file)
@@ -1000,7 +1000,8 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
      equivalent to the cost of GROUP_SIZE separate stores.  If a grouped
      access is instead being provided by a permute-and-store operation,
      include the cost of the permutes.  */
-  if (!store_lanes_p && group_size > 1)
+  if (!store_lanes_p && group_size > 1
+      && !STMT_VINFO_STRIDED_P (stmt_info))
     {
       /* Uses a high and low interleave or shuffle operations for each
         needed permute.  */
@@ -1014,21 +1015,24 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
                          group_size);
     }
 
+  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
   /* Costs of the stores.  */
-  if (STMT_VINFO_STRIDED_P (stmt_info))
+  if (STMT_VINFO_STRIDED_P (stmt_info)
+      && !STMT_VINFO_GROUPED_ACCESS (stmt_info))
     {
       /* N scalar stores plus extracting the elements.  */
-      tree vectype = STMT_VINFO_VECTYPE (stmt_info);
       inside_cost += record_stmt_cost (body_cost_vec,
                                       ncopies * TYPE_VECTOR_SUBPARTS (vectype),
                                       scalar_store, stmt_info, 0, vect_body);
-      inside_cost += record_stmt_cost (body_cost_vec,
-                                      ncopies * TYPE_VECTOR_SUBPARTS (vectype),
-                                      vec_to_scalar, stmt_info, 0, vect_body);
     }
   else
     vect_get_store_cost (first_dr, ncopies, &inside_cost, body_cost_vec);
 
+  if (STMT_VINFO_STRIDED_P (stmt_info))
+    inside_cost += record_stmt_cost (body_cost_vec,
+                                    ncopies * TYPE_VECTOR_SUBPARTS (vectype),
+                                    vec_to_scalar, stmt_info, 0, vect_body);
+
   if (dump_enabled_p ())
     dump_printf_loc (MSG_NOTE, vect_location,
                      "vect_model_store_cost: inside_cost = %d, "
@@ -3377,15 +3381,13 @@ vect_create_vectorized_demotion_stmts (vec<tree> *vec_oprnds,
             (or in STMT_VINFO_RELATED_STMT chain).  */
          if (slp_node)
            SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
+
+         if (!*prev_stmt_info)
+           STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
          else
-           {
-             if (!*prev_stmt_info)
-               STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
-             else
-               STMT_VINFO_RELATED_STMT (*prev_stmt_info) = new_stmt;
+           STMT_VINFO_RELATED_STMT (*prev_stmt_info) = new_stmt;
 
-             *prev_stmt_info = vinfo_for_stmt (new_stmt);
-           }
+         *prev_stmt_info = vinfo_for_stmt (new_stmt);
        }
     }
 
@@ -5155,15 +5157,27 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
     {
       grouped_store = true;
       first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
-      if (!slp && !PURE_SLP_STMT (stmt_info))
+      group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
+      if (!slp
+         && !PURE_SLP_STMT (stmt_info)
+         && !STMT_VINFO_STRIDED_P (stmt_info))
        {
-         group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
          if (vect_store_lanes_supported (vectype, group_size))
            store_lanes_p = true;
          else if (!vect_grouped_store_supported (vectype, group_size))
            return false;
        }
 
+      if (STMT_VINFO_STRIDED_P (stmt_info)
+         && (slp || PURE_SLP_STMT (stmt_info))
+         && (group_size > nunits
+             || nunits % group_size != 0))
+       {
+         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                          "unhandled strided group store\n");
+         return false;
+       }
+
       if (first_stmt == stmt)
        {
           /* STMT is the leader of the group. Check the operands of all the
@@ -5286,10 +5300,23 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
             ...
          */
 
+      unsigned nstores = nunits;
+      tree ltype = elem_type;
+      if (slp)
+       {
+         nstores = nunits / group_size;
+         if (group_size < nunits)
+           ltype = build_vector_type (elem_type, group_size);
+         else
+           ltype = vectype;
+         ltype = build_aligned_type (ltype, TYPE_ALIGN (elem_type));
+         ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
+       }
+
       ivstep = stride_step;
       ivstep = fold_build2 (MULT_EXPR, TREE_TYPE (ivstep), ivstep,
                            build_int_cst (TREE_TYPE (ivstep),
-                                          ncopies * nunits));
+                                          ncopies * nstores));
 
       standard_iv_increment_position (loop, &incr_gsi, &insert_after);
 
@@ -5315,22 +5342,22 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
          else
            vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, vec_oprnd);
 
-         for (i = 0; i < nunits; i++)
+         for (i = 0; i < nstores; i++)
            {
              tree newref, newoff;
              gimple incr, assign;
-             tree size = TYPE_SIZE (elem_type);
+             tree size = TYPE_SIZE (ltype);
              /* Extract the i'th component.  */
              tree pos = fold_build2 (MULT_EXPR, bitsizetype, bitsize_int (i),
                                      size);
-             tree elem = fold_build3 (BIT_FIELD_REF, elem_type, vec_oprnd,
+             tree elem = fold_build3 (BIT_FIELD_REF, ltype, vec_oprnd,
                                       size, pos);
 
              elem = force_gimple_operand_gsi (gsi, elem, true,
                                               NULL_TREE, true,
                                               GSI_SAME_STMT);
 
-             newref = build2 (MEM_REF, TREE_TYPE (vectype),
+             newref = build2 (MEM_REF, ltype,
                               running_off, alias_off);
 
              /* And store it to *running_off.  */