[PATCH] Fix PR64284

Richard Biener rguenther@suse.de
Fri Dec 12 11:55:00 GMT 2014


The following patch fixes PR64284 by removing loops we copied
the header for with FSM threading.  There may be better solutions,
but at least for the testcase it looks difficult to update loops
within the constraints of the calling passes.

Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu.

Richard.

2014-12-12  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/64284
	* tree-ssa-threadupdate.c (duplicate_seme_region): Mark
	the loop for removal if we copied the loop header.

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

Index: gcc/tree-ssa-threadupdate.c
===================================================================
--- gcc/tree-ssa-threadupdate.c	(revision 218621)
+++ gcc/tree-ssa-threadupdate.c	(working copy)
@@ -2364,7 +2364,7 @@ duplicate_seme_region (edge entry, edge
 		       basic_block *region_copy)
 {
   unsigned i;
-  bool free_region_copy = false, copying_header = false;
+  bool free_region_copy = false;
   struct loop *loop = entry->dest->loop_father;
   edge exit_copy;
   edge redirected;
@@ -2388,10 +2388,7 @@ duplicate_seme_region (edge entry, edge
 
   initialize_original_copy_tables ();
 
-  if (copying_header)
-    set_loop_copy (loop, loop_outer (loop));
-  else
-    set_loop_copy (loop, loop);
+  set_loop_copy (loop, loop);
 
   if (!region_copy)
     {
@@ -2453,6 +2450,8 @@ duplicate_seme_region (edge entry, edge
   }
 
   /* Redirect the entry and add the phi node arguments.  */
+  if (entry->dest == loop->header)
+    mark_loop_for_removal (loop);
   redirected = redirect_edge_and_branch (entry, get_bb_copy (entry->dest));
   gcc_assert (redirected != NULL);
   flush_pending_stmts (entry);
Index: gcc/testsuite/gcc.dg/torture/pr64284.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr64284.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr64284.c	(working copy)
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int *a;
+int b;
+int
+fn1() {
+    enum { QSTRING } c = 0;
+    while (1) {
+	switch (*a) {
+	  case '\'':
+	  c = 0;
+	  default:
+	  switch (c)
+	  case 0:
+	    if (b)
+	      return 0;
+	    c = 1;
+	}
+	a++;
+    }
+}



More information about the Gcc-patches mailing list