]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/45709 (internal compiler error: in add_phi_arg, at tree-phino...
authorRichard Guenther <rguenther@suse.de>
Sat, 18 Sep 2010 18:53:53 +0000 (18:53 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Sat, 18 Sep 2010 18:53:53 +0000 (18:53 +0000)
2010-09-18  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/45709
* tree-inline.c (copy_phis_for_bb): Delay commit of edge
insertions until after all PHI nodes of the block are processed.

* g++.dg/torture/pr45709.C: New testcase.
* g++.dg/torture/pr45709-2.C: Likewise.

From-SVN: r164400

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr45709-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/pr45709.C [new file with mode: 0644]
gcc/tree-inline.c

index 77ccff35dbd69bccdcb490c66df2987e374444c6..01389454afa12edca9362091556ce9c8cddb66a7 100644 (file)
@@ -1,3 +1,9 @@
+2010-09-18  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/45709
+       * tree-inline.c (copy_phis_for_bb): Delay commit of edge
+       insertions until after all PHI nodes of the block are processed.
+
 2010-09-01  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gimplify.c (gimplify_init_constructor): Do not create a temporary for
index 3394b20a873acb25c64c234a2ebb28cf72f9bfc4..8ab1e45fcb28c40b8634870df1364f465db0d973 100644 (file)
@@ -1,3 +1,9 @@
+2010-09-18  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/45709
+       * g++.dg/torture/pr45709.C: New testcase.
+       * g++.dg/torture/pr45709-2.C: Likewise.
+
 2010-08-11  Richard Guenther  <rguenther@suse.de>
 
        PR c/44555
diff --git a/gcc/testsuite/g++.dg/torture/pr45709-2.C b/gcc/testsuite/g++.dg/torture/pr45709-2.C
new file mode 100644 (file)
index 0000000..1f6a234
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile }
+
+struct Region {
+    int storage[4];
+    int count;
+};
+static inline Region subtract(int lhs)
+{
+  Region reg;
+  int* storage = reg.storage;
+  int* storage2 = reg.storage;
+  if (lhs > 0)
+    storage++, storage2--;
+  reg.count = storage - reg.storage + storage2 - reg.storage;
+  return reg;
+}
+void bar(int a)
+{
+  const Region copyBack(subtract(a));
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr45709.C b/gcc/testsuite/g++.dg/torture/pr45709.C
new file mode 100644 (file)
index 0000000..1584ec7
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-do compile }
+
+struct Region {
+    int storage[4];
+    int count;
+};
+static inline Region subtract(int lhs)
+{
+  Region reg;
+  int* storage = reg.storage;
+  if (lhs > 0)
+    storage++;
+  reg.count = storage - reg.storage;
+  return reg;
+}
+void bar(int a)
+{
+  const Region copyBack(subtract(a));
+}
index 4da4a09ec1b3bf321a322dcbb7918cdf990085ea..94f08dee9d8028872e4b91b706680b1a6942a9c7 100644 (file)
@@ -1204,13 +1204,14 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
   basic_block new_bb = bb->aux;
   edge_iterator ei;
   tree phi;
+  edge new_edge;
+  bool inserted = false;
 
   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
     {
       tree res = PHI_RESULT (phi);
       tree new_res = res;
       tree new_phi;
-      edge new_edge;
 
       if (is_gimple_reg (res))
        {
@@ -1234,12 +1235,18 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
                  tree stmts = NULL_TREE;
                  new_arg = force_gimple_operand (new_arg, &stmts,
                                                  true, NULL);
-                 bsi_insert_on_edge_immediate (new_edge, stmts);
+                 bsi_insert_on_edge (new_edge, stmts);
+                 inserted = true;
                }
              add_phi_arg (new_phi, new_arg, new_edge);
            }
        }
     }
+
+  /* Commit the delayed edge insertions.  */
+  if (inserted)
+    FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
+      bsi_commit_one_edge_insert (new_edge, NULL);
 }
 
 /* Wrapper for remap_decl so it can be used as a callback.  */