Hi,

As mentioned in the PR, a case has popped up which blew the
sh_optimize_sett_clrt pass away.  The quick fix was to bail out on
handle complex edges.  Tested with make all-gcc, running the sh.exp
tests.  Committed to trunk as r217987 and to 4.9 branch as r217989.

Cheers,
Oleg

gcc/ChangeLog:
        PR target/53976
        * config/sh/sh_optimize_sett_clrt.cc
        (sh_optimize_sett_clrt::find_last_ccreg_values): Return bool instead
        of void.  Abort at complex edges.
        (sh_optimize_sett_clrt::execute): Do nothing if find_last_ccreg_values
        returned false.
Index: gcc/config/sh/sh_optimize_sett_clrt.cc
===================================================================
--- gcc/config/sh/sh_optimize_sett_clrt.cc	(revision 217967)
+++ gcc/config/sh/sh_optimize_sett_clrt.cc	(working copy)
@@ -126,7 +126,7 @@
   // Given a start insn and its basic block, recursively determine all
   // possible ccreg values in all basic block paths that can lead to the
   // start insn.
-  void find_last_ccreg_values (rtx_insn *start_insn, basic_block bb,
+  bool find_last_ccreg_values (rtx_insn *start_insn, basic_block bb,
 			       std::vector<ccreg_value>& values_out,
 			       std::vector<basic_block>& prev_visited_bb) const;
 
@@ -239,8 +239,8 @@
 
 	    ccreg_values.clear ();
 	    visited_bbs.clear ();
-	    find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values,
-				    visited_bbs);
+	    bool ok = find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values,
+					      visited_bbs);
 
 	    log_msg ("number of ccreg values collected: %u\n",
 		     (unsigned int)ccreg_values.size ());
@@ -248,7 +248,7 @@
 	    // If all the collected values are equal and are equal to the
 	    // constant value of the setcc insn, the setcc insn can be
 	    // removed.
-	    if (all_ccreg_values_equal (ccreg_values)
+	    if (ok && all_ccreg_values_equal (ccreg_values)
 		&& rtx_equal_p (ccreg_values.front ().value, setcc_val))
 	      {
 		log_msg ("all values are ");
@@ -322,7 +322,7 @@
     gcc_unreachable ();
 }
 
-void
+bool
 sh_optimize_sett_clrt
 ::find_last_ccreg_values (rtx_insn *start_insn, basic_block bb,
 			  std::vector<ccreg_value>& values_out,
@@ -361,7 +361,7 @@
 	  log_msg ("\n");
 
 	  values_out.push_back (v);
-	  return;
+	  return true;
 	}
 
       if (any_condjump_p (i) && onlyjump_p (i) && !prev_visited_bb.empty ())
@@ -385,7 +385,7 @@
 	  log_msg ("\n");
 
 	  values_out.push_back (v);
-	  return;
+	  return true;
 	}
     }
 
@@ -406,10 +406,14 @@
       for (edge_iterator ei = ei_start (bb->preds); !ei_end_p (ei);
 	   ei_next (&ei))
 	{
+	  if (ei_edge (ei)->flags & EDGE_COMPLEX)
+	    log_return (false, "aborting due to complex edge\n");
+
 	  basic_block pred_bb = ei_edge (ei)->src;
 	  pred_bb_count += 1;
-	  find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out,
-				  prev_visited_bb);
+	  if (!find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out,
+				       prev_visited_bb))
+	    return false;
 	}
 
       prev_visited_bb.pop_back ();
@@ -432,6 +436,8 @@
 
     values_out.push_back (v);
   }
+
+  return true;
 }
 
 bool
Index: gcc/config/sh/sh_optimize_sett_clrt.cc
===================================================================
--- gcc/config/sh/sh_optimize_sett_clrt.cc	(revision 217987)
+++ gcc/config/sh/sh_optimize_sett_clrt.cc	(working copy)
@@ -111,7 +111,7 @@
   // Given a start insn and its basic block, recursively determine all
   // possible ccreg values in all basic block paths that can lead to the
   // start insn.
-  void find_last_ccreg_values (rtx start_insn, basic_block bb,
+  bool find_last_ccreg_values (rtx start_insn, basic_block bb,
 			       std::vector<ccreg_value>& values_out,
 			       std::vector<basic_block>& prev_visited_bb) const;
 
@@ -226,8 +226,8 @@
 
 	    ccreg_values.clear ();
 	    visited_bbs.clear ();
-	    find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values,
-				    visited_bbs);
+	    bool ok = find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values,
+					      visited_bbs);
 
 	    log_msg ("number of ccreg values collected: %u\n",
 		     (unsigned int)ccreg_values.size ());
@@ -235,7 +235,7 @@
 	    // If all the collected values are equal and are equal to the
 	    // constant value of the setcc insn, the setcc insn can be
 	    // removed.
-	    if (all_ccreg_values_equal (ccreg_values)
+	    if (ok && all_ccreg_values_equal (ccreg_values)
 		&& rtx_equal_p (ccreg_values.front ().value, setcc_val))
 	      {
 		log_msg ("all values are ");
@@ -309,7 +309,7 @@
     gcc_unreachable ();
 }
 
-void
+bool
 sh_optimize_sett_clrt
 ::find_last_ccreg_values (rtx start_insn, basic_block bb,
 			  std::vector<ccreg_value>& values_out,
@@ -348,7 +348,7 @@
 	  log_msg ("\n");
 
 	  values_out.push_back (v);
-	  return;
+	  return true;
 	}
 
       if (any_condjump_p (i) && onlyjump_p (i) && !prev_visited_bb.empty ())
@@ -372,7 +372,7 @@
 	  log_msg ("\n");
 
 	  values_out.push_back (v);
-	  return;
+	  return true;
 	}
     }
 
@@ -393,10 +393,14 @@
       for (edge_iterator ei = ei_start (bb->preds); !ei_end_p (ei);
 	   ei_next (&ei))
 	{
+	  if (ei_edge (ei)->flags & EDGE_COMPLEX)
+	    log_return (false, "aborting due to complex edge\n");
+
 	  basic_block pred_bb = ei_edge (ei)->src;
 	  pred_bb_count += 1;
-	  find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out,
-				  prev_visited_bb);
+	  if (!find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out,
+				       prev_visited_bb))
+	    return false;
 	}
 
       prev_visited_bb.pop_back ();
@@ -419,6 +423,8 @@
 
     values_out.push_back (v);
   }
+
+  return true;
 }
 
 bool

Reply via email to