It turns out (well, I anticipated that...) that we cannot easily
update the reduction chain during pattern detection in some of
the more contrieved cases.  Instead of ICEing in this case the
following makes us give up instead.

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

Richard.

2019-10-28  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/92241
        * tree-vect-loop.c (vect_fixup_scalar_cycles_with_patterns): When
        we failed to update the reduction index do not use the pattern
        stmts for the reduction chain.
        (vectorizable_reduction): When the reduction chain is corrupt,
        fail.
        * tree-vect-patterns.c (vect_mark_pattern_stmts): Stop when we
        fail to update the reduction chain.

        * gcc.dg/torture/pr92241.c: New testcase.

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c        (revision 277513)
+++ gcc/tree-vect-loop.c        (working copy)
@@ -689,13 +689,16 @@ vect_fixup_scalar_cycles_with_patterns (
        stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (first);
        while (next)
          {
-           if (! STMT_VINFO_IN_PATTERN_P (next))
+           if (! STMT_VINFO_IN_PATTERN_P (next)
+               || STMT_VINFO_REDUC_IDX (STMT_VINFO_RELATED_STMT (next)) == -1)
              break;
            next = REDUC_GROUP_NEXT_ELEMENT (next);
          }
-       /* If not all stmt in the chain are patterns try to handle
-          the chain without patterns.  */
-       if (! next)
+       /* If not all stmt in the chain are patterns or if we failed
+          to update STMT_VINFO_REDUC_IDX try to handle the chain
+          without patterns.  */
+       if (! next
+           && STMT_VINFO_REDUC_IDX (STMT_VINFO_RELATED_STMT (first)) != -1)
          {
            vect_fixup_reduc_chain (first);
            LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo)[i]
@@ -5730,7 +5745,15 @@ vectorizable_reduction (stmt_vec_info st
     {
       stmt_vec_info def = loop_vinfo->lookup_def (reduc_def);
       def = vect_stmt_to_vectorize (def);
-      gcc_assert (STMT_VINFO_REDUC_IDX (def) != -1);
+      if (STMT_VINFO_REDUC_IDX (def) == -1)
+       {
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                            "reduction chain broken by patterns.\n");
+         return false;
+       }
+      if (!REDUC_GROUP_FIRST_ELEMENT (def))
+       only_slp_reduc_chain = false;
       if (!REDUC_GROUP_FIRST_ELEMENT (def))
        only_slp_reduc_chain = false;
       reduc_def = gimple_op (def->stmt, 1 + STMT_VINFO_REDUC_IDX (def));
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c    (revision 277513)
+++ gcc/tree-vect-patterns.c    (working copy)
@@ -5110,6 +5110,9 @@ vect_mark_pattern_stmts (stmt_vec_info o
     for (gimple_stmt_iterator si = gsi_start (def_seq);
         !gsi_end_p (si); gsi_next (&si))
       {
+       if (dump_enabled_p ())
+         dump_printf_loc (MSG_NOTE, vect_location,
+                          "extra pattern stmt: %G", gsi_stmt (si));
        stmt_vec_info pattern_stmt_info
          = vect_init_pattern_stmt (gsi_stmt (si),
                                    orig_stmt_info, pattern_vectype);
@@ -5169,10 +5172,13 @@ vect_mark_pattern_stmts (stmt_vec_info o
                found = true;
                break;
              }
-         if (found && s == pattern_stmt)
-           break;
          if (s == pattern_stmt)
-           gcc_unreachable ();
+           {
+             if (!found && dump_enabled_p ())
+               dump_printf_loc (MSG_NOTE, vect_location,
+                                "failed to update reduction index");
+             break;
+           }
          if (gsi_end_p (si))
            s = pattern_stmt;
          else
Index: gcc/testsuite/gcc.dg/torture/pr92241.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr92241.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr92241.c      (working copy)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize" } */
+
+int a, b;
+char c[2];
+void d() {
+  char e;
+  for (; b; b--) {
+    e = 0;
+    for (; e <= 1; e++)
+      a &= c[b + e] && 1;
+  }
+}

Reply via email to