re PR tree-optimization/56756 (ICE: verify_ssa failed (definition in block n follows...
authorRichard Biener <rguenther@suse.de>
Tue, 16 Apr 2013 15:32:26 +0000 (15:32 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 16 Apr 2013 15:32:26 +0000 (15:32 +0000)
2013-04-16  Richard Biener  <rguenther@suse.de>

PR tree-optimization/56756
* tree-ssa-loop-im.c (struct first_mem_ref_loc_1): New functor.
(first_mem_ref_loc): New.
(execute_sm): Place the load temporarily before a previous
access instead of in the latch edge to ensure its SSA dependencies
are defined at points dominating the load.

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

From-SVN: r198001

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr56756.c [new file with mode: 0644]
gcc/tree-ssa-loop-im.c

index 3d7e60b213838f2f95c5687a2967a775f67942cf..60f941e5f9290de8777e637646ef111c76f66972 100644 (file)
@@ -1,3 +1,12 @@
+2013-04-16  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/56756
+       * tree-ssa-loop-im.c (struct first_mem_ref_loc_1): New functor.
+       (first_mem_ref_loc): New.
+       (execute_sm): Place the load temporarily before a previous
+       access instead of in the latch edge to ensure its SSA dependencies
+       are defined at points dominating the load.
+
 2013-04-16  Steven Bosscher  <steven@gcc.gnu.org>
 
        * cfgrtl.c (cfg_layout_merge_blocks): Revert r184005, implement
index deb85a7e36bd59d39d0874b0280aa8c8de024667..b3adc0ee2e2e4d9a64f78e37f82bbe5c8da217ca 100644 (file)
@@ -1,3 +1,8 @@
+2013-04-16  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/56756
+       * gcc.dg/torture/pr56756.c: New testcase.
+
 2013-04-16  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/56969
diff --git a/gcc/testsuite/gcc.dg/torture/pr56756.c b/gcc/testsuite/gcc.dg/torture/pr56756.c
new file mode 100644 (file)
index 0000000..470014d
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+
+int a, *b;
+
+void f(void)
+{
+  if(a)
+    {
+      int k;
+
+      for(a = 0; a < 1; a++)
+       {
+         int **q;
+         f();
+
+         for(; **q; ++**q)
+           lbl:
+               if(a)
+                 {
+                   a = 0;
+                   goto lbl;
+                 }
+
+         b = &k;
+       }
+    }
+  goto lbl;
+}
index 085789165a2e8effbca97dff0b4cd411b2f51f02..188af0012a7f828bcfe1c0364a4ba509b0b0bc9d 100644 (file)
@@ -1718,6 +1718,32 @@ rewrite_mem_refs (struct loop *loop, mem_ref_p ref, tree tmp_var)
   for_all_locs_in_loop (loop, ref, rewrite_mem_ref_loc (tmp_var));
 }
 
+/* Stores the first reference location in LOCP.  */
+
+struct first_mem_ref_loc_1
+{
+  first_mem_ref_loc_1 (mem_ref_loc_p *locp_) : locp (locp_) {}
+  bool operator()(mem_ref_loc_p loc);
+  mem_ref_loc_p *locp;
+};
+
+bool
+first_mem_ref_loc_1::operator()(mem_ref_loc_p loc)
+{
+  *locp = loc;
+  return true;
+}
+
+/* Returns the first reference location to REF in LOOP.  */
+
+static mem_ref_loc_p
+first_mem_ref_loc (struct loop *loop, mem_ref_p ref)
+{
+  mem_ref_loc_p locp = NULL;
+  for_all_locs_in_loop (loop, ref, first_mem_ref_loc_1 (&locp));
+  return locp;
+}
+
 /* The name and the length of the currently generated variable
    for lsm.  */
 #define MAX_LSM_NAME_LENGTH 40
@@ -2022,9 +2048,10 @@ execute_sm (struct loop *loop, vec<edge> exits, mem_ref_p ref)
   unsigned i;
   gimple load;
   struct fmt_data fmt_data;
-  edge ex, latch_edge;
+  edge ex;
   struct lim_aux_data *lim_data;
   bool multi_threaded_model_p = false;
+  gimple_stmt_iterator gsi;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -2049,9 +2076,10 @@ execute_sm (struct loop *loop, vec<edge> exits, mem_ref_p ref)
 
   rewrite_mem_refs (loop, ref, tmp_var);
 
-  /* Emit the load code into the latch, so that we are sure it will
-     be processed after all dependencies.  */
-  latch_edge = loop_latch_edge (loop);
+  /* Emit the load code on a random exit edge or into the latch if
+     the loop does not exit, so that we are sure it will be processed
+     by move_computations after all dependencies.  */
+  gsi = gsi_for_stmt (first_mem_ref_loc (loop, ref)->stmt);
 
   /* FIXME/TODO: For the multi-threaded variant, we could avoid this
      load altogether, since the store is predicated by a flag.  We
@@ -2060,7 +2088,7 @@ execute_sm (struct loop *loop, vec<edge> exits, mem_ref_p ref)
   lim_data = init_lim_data (load);
   lim_data->max_loop = loop;
   lim_data->tgt_loop = loop;
-  gsi_insert_on_edge (latch_edge, load);
+  gsi_insert_before (&gsi, load, GSI_SAME_STMT);
 
   if (multi_threaded_model_p)
     {
@@ -2068,7 +2096,7 @@ execute_sm (struct loop *loop, vec<edge> exits, mem_ref_p ref)
       lim_data = init_lim_data (load);
       lim_data->max_loop = loop;
       lim_data->tgt_loop = loop;
-      gsi_insert_on_edge (latch_edge, load);
+      gsi_insert_before (&gsi, load, GSI_SAME_STMT);
     }
 
   /* Sink the store to every exit from the loop.  */