re PR tree-optimization/71752 (ICE in compute_live_loop_exits, at tree-ssa-loop-manip...
authorAlan Hayward <alan.hayward@arm.com>
Wed, 17 Aug 2016 15:31:44 +0000 (15:31 +0000)
committerAlan Hayward <alahay01@gcc.gnu.org>
Wed, 17 Aug 2016 15:31:44 +0000 (15:31 +0000)
2015-08-17  Alan Hayward <alan.hayward@arm.com>

PR tree-optimization/71752
* tree-vect-loop.c (vectorizable_reduction): Keep SLP operand ordering.
* tree-vect-slp.c (vect_get_slp_defs): Handle null operands.

PR tree-optimization/71752
* gcc.dg/vect/pr71752.c: New

From-SVN: r239542

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr71752.c [new file with mode: 0644]
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c

index 8c27eae13d785bf74128b74eb8380c54b6a85a8b..6f6314671aa398214a7bcddc787a5bdf129d1222 100644 (file)
@@ -1,3 +1,9 @@
+2015-08-17  Alan Hayward <alan.hayward@arm.com>
+
+       PR tree-optimization/71752
+       * tree-vect-loop.c (vectorizable_reduction): Keep SLP operand ordering.
+       * tree-vect-slp.c (vect_get_slp_defs): Handle null operands.
+
 2016-08-17  Jakub Jelinek  <jakub@redhat.com>
 
        * gimple-fold.c (gimple_fold_call): Use gimple_call_noreturn_p
index 98d030dc41991efa967fe707cad397f3a045ec9a..2c6ed263dca7327cd71555da58fb14c8321eea80 100644 (file)
@@ -1,3 +1,8 @@
+2015-08-17  Alan Hayward <alan.hayward@arm.com>
+
+       PR tree-optimization/71752
+       * gcc.dg/vect/pr71752.c: New
+
 2016-08-17  Uros Bizjak  <ubizjak@gmail.com>
 
        * gfortran.dg/dec_init_2.f90: Use dg-add-options ieee.
diff --git a/gcc/testsuite/gcc.dg/vect/pr71752.c b/gcc/testsuite/gcc.dg/vect/pr71752.c
new file mode 100644 (file)
index 0000000..8d26754
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+unsigned int q4, yg;
+
+unsigned int
+w6 (unsigned int z5, unsigned int jv)
+{
+  unsigned int *f2 = &jv;
+
+  while (*f2 < 21)
+    {
+      q4 -= jv;
+      z5 -= jv;
+      f2 = &yg;
+      ++(*f2);
+    }
+  return z5;
+}
+
index 4957b66c4320aa1572da04eb81f7c0fe7468f1b9..c9ba5810e708154a3f7eb2d3c02daea0a30db281 100644 (file)
@@ -5444,7 +5444,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
   auto_vec<tree> vect_defs;
   auto_vec<gimple *> phis;
   int vec_num;
-  tree def0, def1, tem, op0, op1 = NULL_TREE;
+  tree def0, def1, tem, op1 = NULL_TREE;
   bool first_p = true;
   tree cr_index_scalar_type = NULL_TREE, cr_index_vector_type = NULL_TREE;
   tree cond_reduc_val = NULL_TREE, const_cond_cmp = NULL_TREE;
@@ -6090,29 +6090,36 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
       /* Handle uses.  */
       if (j == 0)
         {
-          op0 = ops[!reduc_index];
-          if (op_type == ternary_op)
-            {
-              if (reduc_index == 0)
-                op1 = ops[2];
-              else
-                op1 = ops[1];
-            }
+         if (slp_node)
+           {
+             /* Get vec defs for all the operands except the reduction index,
+               ensuring the ordering of the ops in the vector is kept.  */
+             auto_vec<tree, 3> slp_ops;
+             auto_vec<vec<tree>, 3> vec_defs;
 
-          if (slp_node)
-            vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
-                               slp_node, -1);
+             slp_ops.quick_push ((reduc_index == 0) ? NULL : ops[0]);
+             slp_ops.quick_push ((reduc_index == 1) ? NULL : ops[1]);
+             if (op_type == ternary_op)
+               slp_ops.quick_push ((reduc_index == 2) ? NULL : ops[2]);
+
+             vect_get_slp_defs (slp_ops, slp_node, &vec_defs, -1);
+
+             vec_oprnds0.safe_splice (vec_defs[(reduc_index == 0) ? 1 : 0]);
+             if (op_type == ternary_op)
+               vec_oprnds1.safe_splice (vec_defs[(reduc_index == 2) ? 1 : 2]);
+           }
           else
-            {
+           {
               loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index],
                                                             stmt);
               vec_oprnds0.quick_push (loop_vec_def0);
               if (op_type == ternary_op)
                {
+                op1 = (reduc_index == 0) ? ops[2] : ops[1];
                  loop_vec_def1 = vect_get_vec_def_for_operand (op1, stmt);
                  vec_oprnds1.quick_push (loop_vec_def1);
                }
-            }
+           }
         }
       else
         {
index fb325d54f1084461d44cd54a98e5b7f99541a188..5a611e42556e0931a372a6c626cc24846f11029d 100644 (file)
@@ -3194,24 +3194,32 @@ vect_get_slp_defs (vec<tree> ops, slp_tree slp_node,
 {
   gimple *first_stmt;
   int number_of_vects = 0, i;
-  unsigned int child_index = 0;
   HOST_WIDE_INT lhs_size_unit, rhs_size_unit;
   slp_tree child = NULL;
   vec<tree> vec_defs;
   tree oprnd;
-  bool vectorized_defs;
+  bool first_iteration = true;
 
   first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0];
   FOR_EACH_VEC_ELT (ops, i, oprnd)
     {
+      bool vectorized_defs = false;
+
+      if (oprnd == NULL)
+       {
+         vec_defs = vNULL;
+         vec_defs.create (0);
+         vec_oprnds->quick_push (vec_defs);
+         continue;
+       }
+
       /* For each operand we check if it has vectorized definitions in a child
         node or we need to create them (for invariants and constants).  We
         check if the LHS of the first stmt of the next child matches OPRND.
         If it does, we found the correct child.  Otherwise, we call
-        vect_get_constant_vectors (), and not advance CHILD_INDEX in order
-        to check this child node for the next operand.  */
-      vectorized_defs = false;
-      if (SLP_TREE_CHILDREN (slp_node).length () > child_index)
+        vect_get_constant_vectors ().  */
+      for (unsigned int child_index = 0;
+          child_index < SLP_TREE_CHILDREN (slp_node).length (); child_index++)
         {
           child = SLP_TREE_CHILDREN (slp_node)[child_index];
 
@@ -3231,30 +3239,25 @@ vect_get_slp_defs (vec<tree> ops, slp_tree slp_node,
                     statements.  */
                  number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child);
                  vectorized_defs = true;
-                 child_index++;
+                 break;
                }
            }
-         else
-           child_index++;
         }
 
-      if (!vectorized_defs)
-        {
-          if (i == 0)
-            {
-              number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
-              /* Number of vector stmts was calculated according to LHS in
-                 vect_schedule_slp_instance (), fix it by replacing LHS with
-                 RHS, if necessary.  See vect_get_smallest_scalar_type () for
-                 details.  */
-              vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit,
-                                             &rhs_size_unit);
-              if (rhs_size_unit != lhs_size_unit)
-                {
-                  number_of_vects *= rhs_size_unit;
-                  number_of_vects /= lhs_size_unit;
-                }
-            }
+      if (!vectorized_defs && first_iteration)
+       {
+         number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
+         /* Number of vector stmts was calculated according to LHS in
+            vect_schedule_slp_instance (), fix it by replacing LHS with
+            RHS, if necessary.  See vect_get_smallest_scalar_type () for
+            details.  */
+         vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit,
+                                        &rhs_size_unit);
+         if (rhs_size_unit != lhs_size_unit)
+           {
+             number_of_vects *= rhs_size_unit;
+             number_of_vects /= lhs_size_unit;
+           }
         }
 
       /* Allocate memory for vectorized defs.  */
@@ -3276,6 +3279,8 @@ vect_get_slp_defs (vec<tree> ops, slp_tree slp_node,
       /* For reductions, we only need initial values.  */
       if (reduc_index != -1)
         return;
+
+      first_iteration = false;
     }
 }