re PR tree-optimization/68017 (ICE on valid code at -O3 with -g enabled on x86_64...
authorRichard Biener <rguenther@suse.de>
Tue, 20 Oct 2015 12:34:19 +0000 (12:34 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 20 Oct 2015 12:34:19 +0000 (12:34 +0000)
2015-10-20  Richard Biener  <rguenther@suse.de>

PR tree-optimization/68017
* tree-tailcall.c (eliminate_tail_call): Remove stmts backwards.

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

From-SVN: r229073

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

index 45fc66ab95efd4dce38a5827f1ee02773b29c8e5..f79e71d5483cd6d72844619643cdc5eb66c8fb44 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-20  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/68017
+       * tree-tailcall.c (eliminate_tail_call): Remove stmts backwards.
+
 2015-10-20  Martin Liska  <mliska@suse.cz>
 
        * cgraphclones.c (cgraph_node::create_virtual_clone):
index 4415ac38fe02e80337cc4c6db88046417d587a7b..617ecf4d8b32f7f731fd5a8d6a672619fdb09c66 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-20  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/68017
+       * gcc.dg/torture/pr68017.c: New testcase.
+
 2015-10-20  Szabolcs Nagy  <szabolcs.nagy@arm.com>
 
        PR target/66912
diff --git a/gcc/testsuite/gcc.dg/torture/pr68017.c b/gcc/testsuite/gcc.dg/torture/pr68017.c
new file mode 100644 (file)
index 0000000..1fc2191
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-g" } */
+
+long long a;
+
+short
+fn1 (short p1, unsigned short p2)
+{
+  return p1 + p2;
+}
+
+short
+fn2 ()
+{
+  int b = a ? fn1 (fn2 (), a) : 0;
+  return b;
+}
index e97f6db89d8ee054cb1dc372687bfe8cafe67293..098fff07d2faeaffaa0411ec613060d7cad5ebc6 100644 (file)
@@ -847,17 +847,21 @@ eliminate_tail_call (struct tailcall *t)
      possibly unreachable code in other blocks is removed later in
      cfg cleanup.  */
   gsi = t->call_gsi;
-  gsi_next (&gsi);
-  while (!gsi_end_p (gsi))
+  gimple_stmt_iterator gsi2 = gsi_last_bb (gimple_bb (gsi_stmt (gsi)));
+  while (gsi_stmt (gsi2) != gsi_stmt (gsi))
     {
-      gimple *t = gsi_stmt (gsi);
+      gimple *t = gsi_stmt (gsi2);
       /* Do not remove the return statement, so that redirect_edge_and_branch
         sees how the block ends.  */
-      if (gimple_code (t) == GIMPLE_RETURN)
-       break;
-
-      gsi_remove (&gsi, true);
-      release_defs (t);
+      if (gimple_code (t) != GIMPLE_RETURN)
+       {
+         gimple_stmt_iterator gsi3 = gsi2;
+         gsi_prev (&gsi2);
+         gsi_remove (&gsi3, true);
+         release_defs (t);
+       }
+      else
+       gsi_prev (&gsi2);
     }
 
   /* Number of executions of function has reduced by the tailcall.  */