re PR middle-end/68870 (ICE on valid code at -O1, -O2 and -O3 on x86_64-linux-gnu)
authorRichard Biener <rguenther@suse.de>
Wed, 16 Dec 2015 14:56:10 +0000 (14:56 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 16 Dec 2015 14:56:10 +0000 (14:56 +0000)
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.

From-SVN: r231695

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr68870.c [new file with mode: 0644]
gcc/tree-cfgcleanup.c

index c04c01f86ead172d6c93fc401c4fd788e5d84bdb..90399d58f496eb04cec263388bd0aaf263f38f9d 100644 (file)
@@ -1,3 +1,13 @@
+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.
+
 2015-12-16  Nathan Sidwell  <nathan@acm.org>
 
        * config/nvptx/nvptx-protos.h (nvptx_hard_regno_mode_ok): Delete.
index 4a058fb7a01780b048a07727e49aeed0fd14cd3b..d4ee11c6ecbd9f163a413113234a99e3e8e6056c 100644 (file)
@@ -1,3 +1,8 @@
+2015-12-16  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/68870
+       * gcc.dg/torture/pr68870.c: New testcase.
+
 2015-12-16  Tom de Vries  <tom@codesourcery.com>
 
        * g++.dg/ipa/devirt-37.C: Update for new fre2 pass.
diff --git a/gcc/testsuite/gcc.dg/torture/pr68870.c b/gcc/testsuite/gcc.dg/torture/pr68870.c
new file mode 100644 (file)
index 0000000..1ad0f7b
--- /dev/null
@@ -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;
+}
index 3f50c66af6060d29ea1072533b776028681a9f7d..c5d94d07c82bb224142cb42c891ff1d30ec833b4 100644 (file)
@@ -78,7 +78,8 @@ remove_fallthru_edge (vec<edge, va_gc> *ev)
    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 bb, gimple_stmt_iterator gsi)
       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 *bb_end)
    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);
     }