diff mbox

Fix PR68870

Message ID alpine.LSU.2.11.1512161554090.3571@t29.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Dec. 16, 2015, 2:55 p.m. UTC
This extends the previous fix for the CFG cleanup issue WRT dead SSA
defs to properly avoid doing sth fancy with conditons in the first pass.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-12-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/68870
	* tree-cfgcleanup.c (cleanup_control_expr_graph): Add first_p
	parameter, if set only perform trivial constant folding.
	Queue other blocks with conditions for later processing.
	(cleanup_control_flow_bb): Add first_p parameter and pass it through.
	(cleanup_tree_cfg_1): Pass true for the first iteration
	cleanup_control_expr_graph.

	* gcc.dg/torture/pr68870.c: New testcase.
diff mbox

Patch

Index: gcc/tree-cfgcleanup.c
===================================================================
--- gcc/tree-cfgcleanup.c	(revision 231673)
+++ gcc/tree-cfgcleanup.c	(working copy)
@@ -78,7 +78,8 @@  remove_fallthru_edge (vec<edge, va_gc> *
    at block BB.  */
 
 static bool
-cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
+cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi,
+			    bool first_p)
 {
   edge taken_edge;
   bool retval = false;
@@ -95,15 +96,26 @@  cleanup_control_expr_graph (basic_block
       switch (gimple_code (stmt))
 	{
 	case GIMPLE_COND:
-	  {
-	    code_helper rcode;
-	    tree ops[3] = {};
-	    if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges,
-				 no_follow_ssa_edges)
-		&& rcode == INTEGER_CST)
-	      val = ops[0];
-	    break;
-	  }
+	  /* During a first iteration on the CFG only remove trivially
+	     dead edges but mark other conditions for re-evaluation.  */
+	  if (first_p)
+	    {
+	      val = const_binop (gimple_cond_code (stmt), boolean_type_node,
+				 gimple_cond_lhs (stmt),
+				 gimple_cond_rhs (stmt));
+	      if (! val)
+		bitmap_set_bit (cfgcleanup_altered_bbs, bb->index);
+	    }
+	  else
+	    {
+	      code_helper rcode;
+	      tree ops[3] = {};
+	      if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges,
+				   no_follow_ssa_edges)
+		  && rcode == INTEGER_CST)
+		val = ops[0];
+	    }
+	  break;
 
 	case GIMPLE_SWITCH:
 	  val = gimple_switch_index (as_a <gswitch *> (stmt));
@@ -176,7 +188,7 @@  cleanup_call_ctrl_altering_flag (gimple
    true if anything changes.  */
 
 static bool
-cleanup_control_flow_bb (basic_block bb)
+cleanup_control_flow_bb (basic_block bb, bool first_p)
 {
   gimple_stmt_iterator gsi;
   bool retval = false;
@@ -199,7 +211,7 @@  cleanup_control_flow_bb (basic_block bb)
       || gimple_code (stmt) == GIMPLE_SWITCH)
     {
       gcc_checking_assert (gsi_stmt (gsi_last_bb (bb)) == stmt);
-      retval |= cleanup_control_expr_graph (bb, gsi);
+      retval |= cleanup_control_expr_graph (bb, gsi, first_p);
     }
   else if (gimple_code (stmt) == GIMPLE_GOTO
 	   && TREE_CODE (gimple_goto_dest (stmt)) == ADDR_EXPR
@@ -680,7 +692,7 @@  cleanup_tree_cfg_1 (void)
     {
       bb = BASIC_BLOCK_FOR_FN (cfun, i);
       if (bb)
-	retval |= cleanup_control_flow_bb (bb);
+	retval |= cleanup_control_flow_bb (bb, true);
     }
 
   /* After doing the above SSA form should be valid (or an update SSA
@@ -708,7 +720,7 @@  cleanup_tree_cfg_1 (void)
       if (!bb)
 	continue;
 
-      retval |= cleanup_control_flow_bb (bb);
+      retval |= cleanup_control_flow_bb (bb, false);
       retval |= cleanup_tree_cfg_bb (bb);
     }
 
Index: gcc/testsuite/gcc.dg/torture/pr68870.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr68870.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr68870.c	(working copy)
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+
+int printf (const char *, ...);
+
+int a, f, g;
+char b, d;
+short c;
+static short e;
+
+char
+fn1 ()
+{
+  for (; b; b++)
+    {
+      int h = 5;
+      for (a = 0; a < 1; a++)
+	{
+	  for (d = 0; d < 1; d++)
+	    for (c = 0; c < 1; c++)
+	      for (; e >= 0;)
+		return 5;
+	  if (f)
+	    h = 0;
+	}
+      if (h)
+	printf ("%d", 0);
+    }
+  return g;
+}