diff mbox series

Fix PR92241, turn asserts into vectorization fails

Message ID nycvar.YFH.7.76.1910281332530.5566@zhemvz.fhfr.qr
State New
Headers show
Series Fix PR92241, turn asserts into vectorization fails | expand

Commit Message

Richard Biener Oct. 28, 2019, 12:34 p.m. UTC
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  <rguenther@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.
diff mbox series

Patch

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;
+  }
+}