re PR tree-optimization/88031 (ICE in vectorizable_reduction, at tree-vect-loop.c...
authorRichard Biener <rguenther@suse.de>
Thu, 15 Nov 2018 13:42:13 +0000 (13:42 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 15 Nov 2018 13:42:13 +0000 (13:42 +0000)
2018-11-15  Richard Biener  <rguenther@suse.de>

PR tree-optimization/88031
* tree-vect-loop.c (vectorizable_reduction): Move check
for multiple types earlier so we get the expected dump.
Simplify calls to vectorizable_condition.
* tree-vect-stmts.h (vectorizable_condition): Update prototype.
* tree-vect-stmts.c (vectorizable_condition): Instead of
reduc_def and reduc_index take just a flag.  Simplify
code-generation now that we can rely on the defs being set up.
(vectorizable_comparison): Remove unused argument.

* gcc.dg/pr88031.c: New testcase.

From-SVN: r266182

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr88031.c [new file with mode: 0644]
gcc/tree-vect-loop.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h

index 6258974e3e54ee28e5024db1cac79b37e9d96597..df863230c1c54ac93e42c8cd115ed0f2d431388f 100644 (file)
@@ -1,3 +1,15 @@
+2018-11-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/88031
+       * tree-vect-loop.c (vectorizable_reduction): Move check
+       for multiple types earlier so we get the expected dump.
+       Simplify calls to vectorizable_condition.
+       * tree-vect-stmts.h (vectorizable_condition): Update prototype.
+       * tree-vect-stmts.c (vectorizable_condition): Instead of
+       reduc_def and reduc_index take just a flag.  Simplify
+       code-generation now that we can rely on the defs being set up.
+       (vectorizable_comparison): Remove unused argument.
+
 2018-11-15  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/88030
index 3b0b6093f29468b8b42e35ea62d3d18bcbfc2c95..ee0d920c73e4cbe882745eb2c7113d894f708ec4 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/88031
+       * gcc.dg/pr88031.c: New testcase.
+
 2018-11-15  Wilco Dijkstra  <wdijkstr@arm.com>  
 
        * gcc.target/aarch64/pr62178.c: Fix spaces.
diff --git a/gcc/testsuite/gcc.dg/pr88031.c b/gcc/testsuite/gcc.dg/pr88031.c
new file mode 100644 (file)
index 0000000..2c1d1c1
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a[512];
+int b;
+void d()
+{
+  unsigned char c;
+  for (; b; b++) {
+      c = 1;
+      for (; c; c <<= 1) {
+         a[b] <<= 8;
+         if (b & c)
+           a[b] = 1;
+      }
+  }
+}
index dac6bb87847487e63f873f09c49aa15bb9de4514..f2d9d8ac2bc44398f955650591eea20dc7fca8a5 100644 (file)
@@ -6491,14 +6491,24 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
         double_reduc = true;
     }
 
+  vect_reduction_type reduction_type
+    = STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info);
+  if ((double_reduc || reduction_type != TREE_CODE_REDUCTION)
+      && ncopies > 1)
+    {
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                        "multiple types in double reduction or condition "
+                        "reduction.\n");
+      return false;
+    }
+
   if (code == COND_EXPR)
     {
       /* Only call during the analysis stage, otherwise we'll lose
-        STMT_VINFO_TYPE.  We'll pass ops[0] as reduc_op, it's only
-        used as a flag during analysis.  */
+        STMT_VINFO_TYPE.  */
       if (!vec_stmt && !vectorizable_condition (stmt_info, gsi, NULL,
-                                               ops[0], 0, NULL,
-                                               cost_vec))
+                                               true, NULL, cost_vec))
         {
           if (dump_enabled_p ())
            dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -6598,8 +6608,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
           (and also the same tree-code) when generating the epilog code and
           when generating the code inside the loop.  */
 
-  vect_reduction_type reduction_type
-    = STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info);
   if (orig_stmt_info
       && (reduction_type == TREE_CODE_REDUCTION
          || reduction_type == FOLD_LEFT_REDUCTION))
@@ -6689,16 +6697,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
       return false;
     }
 
-  if ((double_reduc || reduction_type != TREE_CODE_REDUCTION)
-      && ncopies > 1)
-    {
-      if (dump_enabled_p ())
-       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                        "multiple types in double reduction or condition "
-                        "reduction.\n");
-      return false;
-    }
-
   /* For SLP reductions, see if there is a neutral value we can use.  */
   tree neutral_op = NULL_TREE;
   if (slp_node)
@@ -6963,7 +6961,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
     {
       gcc_assert (!slp_node);
       return vectorizable_condition (stmt_info, gsi, vec_stmt,
-                                    NULL, reduc_index, NULL, NULL);
+                                    true, NULL, NULL);
     }
 
   /* Create the destination vector  */
@@ -6995,9 +6993,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
         {
           gcc_assert (!slp_node);
          vectorizable_condition (stmt_info, gsi, vec_stmt,
-                                 PHI_RESULT (phis[0]->stmt),
-                                 reduc_index, NULL, NULL);
-          /* Multiple types are not supported for condition.  */
+                                 true, NULL, NULL);
           break;
         }
       if (code == LSHIFT_EXPR
index 74646570e2a3b6963cb9e1bf5b332024c2c77173..a67a7f4e34848fba52201d90e31ffe632eb78a0b 100644 (file)
@@ -8675,17 +8675,14 @@ vect_is_simple_cond (tree cond, vec_info *vinfo,
    stmt using VEC_COND_EXPR  to replace it, put it in VEC_STMT, and insert it
    at GSI.
 
-   When STMT_INFO is vectorized as a nested cycle, REDUC_DEF is the vector
-   variable to be used at REDUC_INDEX (in then clause if REDUC_INDEX is 1,
-   and in else clause if it is 2).
+   When STMT_INFO is vectorized as a nested cycle, for_reduction is true.
 
    Return true if STMT_INFO is vectorizable in this way.  */
 
 bool
 vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
-                       stmt_vec_info *vec_stmt, tree reduc_def,
-                       int reduc_index, slp_tree slp_node,
-                       stmt_vector_for_cost *cost_vec)
+                       stmt_vec_info *vec_stmt, bool for_reduction,
+                       slp_tree slp_node, stmt_vector_for_cost *cost_vec)
 {
   vec_info *vinfo = stmt_info->vinfo;
   tree scalar_dest = NULL_TREE;
@@ -8714,7 +8711,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
   tree vec_cmp_type;
   bool masked = false;
 
-  if (reduc_index && STMT_SLP_TYPE (stmt_info))
+  if (for_reduction && STMT_SLP_TYPE (stmt_info))
     return false;
 
   vect_reduction_type reduction_type
@@ -8726,7 +8723,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
 
       if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
          && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
-              && reduc_def))
+              && for_reduction))
        return false;
 
       /* FORNOW: not yet supported.  */
@@ -8758,7 +8755,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
     ncopies = vect_get_num_copies (loop_vinfo, vectype);
 
   gcc_assert (ncopies >= 1);
-  if (reduc_index && ncopies > 1)
+  if (for_reduction && ncopies > 1)
     return false; /* FORNOW */
 
   cond_expr = gimple_assign_rhs1 (stmt);
@@ -8928,22 +8925,12 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
                                                    stmt_info, comp_vectype);
                  vect_is_simple_use (cond_expr1, loop_vinfo, &dts[1]);
                }
-             if (reduc_index == 1)
-               vec_then_clause = reduc_def;
-             else
-               {
-                 vec_then_clause = vect_get_vec_def_for_operand (then_clause,
-                                                                 stmt_info);
-                 vect_is_simple_use (then_clause, loop_vinfo, &dts[2]);
-               }
-             if (reduc_index == 2)
-               vec_else_clause = reduc_def;
-             else
-               {
-                 vec_else_clause = vect_get_vec_def_for_operand (else_clause,
-                                                                 stmt_info);
-                 vect_is_simple_use (else_clause, loop_vinfo, &dts[3]);
-               }
+             vec_then_clause = vect_get_vec_def_for_operand (then_clause,
+                                                             stmt_info);
+             vect_is_simple_use (then_clause, loop_vinfo, &dts[2]);
+             vec_else_clause = vect_get_vec_def_for_operand (else_clause,
+                                                             stmt_info);
+             vect_is_simple_use (else_clause, loop_vinfo, &dts[3]);
            }
        }
       else
@@ -9023,7 +9010,6 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
                  vect_finish_stmt_generation (stmt_info, new_stmt, gsi);
                  vec_compare = vec_compare_name;
                }
-             gcc_assert (reduc_index == 2);
              gcall *new_stmt = gimple_build_call_internal
                (IFN_FOLD_EXTRACT_LAST, 3, else_clause, vec_compare,
                 vec_then_clause);
@@ -9085,7 +9071,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
 
 static bool
 vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
-                        stmt_vec_info *vec_stmt, tree reduc_def,
+                        stmt_vec_info *vec_stmt,
                         slp_tree slp_node, stmt_vector_for_cost *cost_vec)
 {
   vec_info *vinfo = stmt_info->vinfo;
@@ -9123,9 +9109,7 @@ vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
     ncopies = vect_get_num_copies (loop_vinfo, vectype);
 
   gcc_assert (ncopies >= 1);
-  if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
-      && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
-          && reduc_def))
+  if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
     return false;
 
   if (STMT_VINFO_LIVE_P (stmt_info))
@@ -9556,9 +9540,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool *need_to_vectorize,
                                     node_instance, cost_vec)
          || vectorizable_induction (stmt_info, NULL, NULL, node, cost_vec)
          || vectorizable_shift (stmt_info, NULL, NULL, node, cost_vec)
-         || vectorizable_condition (stmt_info, NULL, NULL, NULL, 0, node,
+         || vectorizable_condition (stmt_info, NULL, NULL, false, node,
                                     cost_vec)
-         || vectorizable_comparison (stmt_info, NULL, NULL, NULL, node,
+         || vectorizable_comparison (stmt_info, NULL, NULL, node,
                                      cost_vec));
   else
     {
@@ -9575,9 +9559,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool *need_to_vectorize,
              || vectorizable_load (stmt_info, NULL, NULL, node, node_instance,
                                    cost_vec)
              || vectorizable_store (stmt_info, NULL, NULL, node, cost_vec)
-             || vectorizable_condition (stmt_info, NULL, NULL, NULL, 0, node,
+             || vectorizable_condition (stmt_info, NULL, NULL, false, node,
                                         cost_vec)
-             || vectorizable_comparison (stmt_info, NULL, NULL, NULL, node,
+             || vectorizable_comparison (stmt_info, NULL, NULL, node,
                                          cost_vec));
     }
 
@@ -9680,13 +9664,13 @@ vect_transform_stmt (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
       break;
 
     case condition_vec_info_type:
-      done = vectorizable_condition (stmt_info, gsi, &vec_stmt, NULL, 0,
+      done = vectorizable_condition (stmt_info, gsi, &vec_stmt, false,
                                     slp_node, NULL);
       gcc_assert (done);
       break;
 
     case comparison_vec_info_type:
-      done = vectorizable_comparison (stmt_info, gsi, &vec_stmt, NULL,
+      done = vectorizable_comparison (stmt_info, gsi, &vec_stmt,
                                      slp_node, NULL);
       gcc_assert (done);
       break;
index 7f21622ebfe1a8f5026a8e2990923b1d347d2800..f1c186b8af5fc62478853dcb61ef84fe8f900936 100644 (file)
@@ -1481,7 +1481,7 @@ extern void vect_remove_stores (stmt_vec_info);
 extern opt_result vect_analyze_stmt (stmt_vec_info, bool *, slp_tree,
                                     slp_instance, stmt_vector_for_cost *);
 extern bool vectorizable_condition (stmt_vec_info, gimple_stmt_iterator *,
-                                   stmt_vec_info *, tree, int, slp_tree,
+                                   stmt_vec_info *, bool, slp_tree,
                                    stmt_vector_for_cost *);
 extern bool vectorizable_shift (stmt_vec_info, gimple_stmt_iterator *,
                                stmt_vec_info *, slp_tree,