aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSebastian Pop <s.pop@samsung.com>2015-02-26 13:56:39 +0000
committerJeff Law <law@gcc.gnu.org>2015-02-26 06:56:39 -0700
commitae762b31c4d775283ecbd629ba904b7ab9e600b4 (patch)
treece4b757be7776f3330ed6156248bb1ada1caf074 /gcc
parentdb847fa8f2cca6139188b8dfa0a7064319b19193 (diff)
downloadgcc-ae762b31c4d775283ecbd629ba904b7ab9e600b4.zip
gcc-ae762b31c4d775283ecbd629ba904b7ab9e600b4.tar.gz
gcc-ae762b31c4d775283ecbd629ba904b7ab9e600b4.tar.bz2
re PR middle-end/65048 (ICE in add_phi_args_after_copy_edge, at tree-cfg.c)
PR tree-optimization/65048 * tree-ssa-threadupdate.c (valid_jump_thread_path): New. (thread_through_all_blocks): Call valid_jump_thread_path. Remove invalid FSM jump-thread paths. PR tree-optimization/65048 * gcc.dg/tree-ssa/ssa-dom-thread-9.c: New. From-SVN: r221007
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c50
-rw-r--r--gcc/tree-ssa-threadupdate.c40
4 files changed, 96 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 98a0d24..73ef79d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-02-26 Sebastian Pop <s.pop@samsung.com>
+
+ PR tree-optimization/65048
+ * tree-ssa-threadupdate.c (valid_jump_thread_path): New.
+ (thread_through_all_blocks): Call valid_jump_thread_path.
+ Remove invalid FSM jump-thread paths.
+
2015-02-26 Jakub Jelinek <jakub@redhat.com>
* passes.c (ipa_write_summaries_1): Call lto_output_init_mode_table.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b1efb2b..f785408 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-02-26 Sebastian Pop <s.pop@samsung.com>
+
+ PR tree-optimization/65048
+ * gcc.dg/tree-ssa/ssa-dom-thread-9.c: New.
+
2015-02-26 Uros Bizjak <ubizjak@gmail.com>
* lib/gcc-dg.exp (cleanup-final-insns-dump): New procedure.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c
new file mode 100644
index 0000000..6be4203
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c
@@ -0,0 +1,50 @@
+/* PR 65048 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a, b, c, d;
+void fn (void);
+
+int
+foo (x)
+{
+ switch (x)
+ {
+ case 'A':
+ return 'T';
+ case 'U':
+ return 'A';
+ }
+}
+
+void
+bar (int x, int y)
+{
+ switch (c)
+ {
+ case 'U':
+ switch (x)
+ {
+ default:
+ fn ();
+ case 'G':
+ switch (y)
+ {
+ case 'A':
+ d = 7;
+ }
+ }
+ }
+}
+
+void
+baz (void)
+{
+ while (1)
+ {
+ a = foo ();
+ b = foo ();
+ bar (a, b);
+ }
+}
+
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 3326144..7a41ab2 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -2473,6 +2473,21 @@ duplicate_seme_region (edge entry, edge exit,
return true;
}
+/* Return true when PATH is a valid jump-thread path. */
+
+static bool
+valid_jump_thread_path (vec<jump_thread_edge *> *path)
+{
+ unsigned len = path->length ();
+
+ /* Check that the path is connected. */
+ for (unsigned int j = 0; j < len - 1; j++)
+ if ((*path)[j]->e->dest != (*path)[j+1]->e->src)
+ return false;
+
+ return true;
+}
+
/* Walk through all blocks and thread incoming edges to the appropriate
outgoing edge for each edge pair recorded in THREADED_EDGES.
@@ -2505,12 +2520,25 @@ thread_through_all_blocks (bool may_peel_loop_headers)
vec<jump_thread_edge *> *path = paths[i];
edge entry = (*path)[0]->e;
- if ((*path)[0]->type != EDGE_FSM_THREAD
- /* Do not jump-thread twice from the same block. */
- || bitmap_bit_p (threaded_blocks, entry->src->index)) {
- i++;
- continue;
- }
+ /* Only code-generate FSM jump-threads in this loop. */
+ if ((*path)[0]->type != EDGE_FSM_THREAD)
+ {
+ i++;
+ continue;
+ }
+
+ /* Do not jump-thread twice from the same block. */
+ if (bitmap_bit_p (threaded_blocks, entry->src->index)
+ /* Verify that the jump thread path is still valid: a
+ previous jump-thread may have changed the CFG, and
+ invalidated the current path. */
+ || !valid_jump_thread_path (path))
+ {
+ /* Remove invalid FSM jump-thread paths. */
+ delete_jump_thread_path (path);
+ paths.unordered_remove (i);
+ continue;
+ }
unsigned len = path->length ();
edge exit = (*path)[len - 1]->e;