aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-01-23 22:29:17 +0000
committerJeff Law <law@gcc.gnu.org>2017-01-23 15:29:17 -0700
commit108fdd6d848eb083021de4a43f3e682fa7babbf3 (patch)
treeabeeed22e3f2d4c6218cc99541dddd430b990a67 /gcc
parent01f26e0e1f69a8462e20a44eb9f15ae9c1b541fe (diff)
downloadgcc-108fdd6d848eb083021de4a43f3e682fa7babbf3.zip
gcc-108fdd6d848eb083021de4a43f3e682fa7babbf3.tar.gz
gcc-108fdd6d848eb083021de4a43f3e682fa7babbf3.tar.bz2
re PR tree-optimization/79088 (wrong code at -O2 on x86_64-linux-gnu)
2017-01-23 Richard Biener <rguenther@suse.de> PR tree-optimization/79088 PR tree-optimization/79188 * tree-ssa-threadupdate.c (mark_threaded_blocks): Move code resetting loop bounds after last path deletion. Reset loop bounds of the target loop, make code match the comments. * tree-ssa-threadbackwards.c (pass_early_thread_jumps::execute): Make sure loops need no fixups. * gcc.dg/torture/pr79088.c: New testcase. * gcc.dg/torture/pr79188.c: Likewise. From-SVN: r244837
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr79088.c23
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr79188.c44
-rw-r--r--gcc/tree-ssa-threadbackward.c4
-rw-r--r--gcc/tree-ssa-threadupdate.c76
6 files changed, 128 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 468e012..8df91c7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2017-01-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/79088
+ PR tree-optimization/79188
+ * tree-ssa-threadupdate.c (mark_threaded_blocks): Move code
+ resetting loop bounds after last path deletion. Reset loop
+ bounds of the target loop, make code match the comments.
+ * tree-ssa-threadbackwards.c (pass_early_thread_jumps::execute):
+ Make sure loops need no fixups.
+
2017-01-23 Kelvin Nilsen <kelvin@gcc.gnu.org>
* config/rs6000/rs6000-builtin.def (VSIEDPF): Add scalar insert
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 004bff9..c05ea54 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2017-01-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/79088
+ PR tree-optimization/79188
+ * gcc.dg/torture/pr79088.c: New testcase.
+ * gcc.dg/torture/pr79188.c: Likewise.
+
2017-01-23 Kelvin Nilsen <kelvin@gcc.gnu.org>
* gcc.target/powerpc/bfp/scalar-insert-exp-3.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr79088.c b/gcc/testsuite/gcc.dg/torture/pr79088.c
new file mode 100644
index 0000000..7c78f15
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr79088.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+int a, b, c, d, e = 1;
+
+int main ()
+{
+ int f;
+ if (a)
+ goto L;
+ for (f = 0; f < e; e++)
+ {
+L:
+ if (d)
+ continue;
+ if (c)
+ goto L;
+ for (a = 0; a < 6; a++)
+ for (f = 0; f < 3; f++)
+ while (b)
+ c++;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr79188.c b/gcc/testsuite/gcc.dg/torture/pr79188.c
new file mode 100644
index 0000000..fc3208c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr79188.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+int a, b, c, d, e, f, h, j, k;
+
+static void fn1 ()
+{
+ int g = 1, i;
+ if (!f)
+ {
+ for (; d < 1; d++)
+ for (i = 0, j = 1; i < 1; i = j)
+ a = 2;
+ for (; e < 1; e++)
+ {
+ for (; k; k++)
+ L:
+ ;
+ for (c = 0; c < 2; c++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ for (; h; h++)
+ g = 0;
+ b = 0;
+ }
+ if (b)
+ goto L;
+ }
+ a = 0;
+ }
+ if (g < 0)
+ goto L;
+ }
+}
+
+int main ()
+{
+ fn1 ();
+
+ if (a != 0)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c
index e09ecb8..51f30a7 100644
--- a/gcc/tree-ssa-threadbackward.c
+++ b/gcc/tree-ssa-threadbackward.c
@@ -865,6 +865,8 @@ pass_early_thread_jumps::gate (function *fun ATTRIBUTE_UNUSED)
unsigned int
pass_early_thread_jumps::execute (function *fun)
{
+ loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+
/* Try to thread each block with more than one successor. */
basic_block bb;
FOR_EACH_BB_FN (bb, fun)
@@ -873,6 +875,8 @@ pass_early_thread_jumps::execute (function *fun)
find_jump_threads_backwards (bb, false);
}
thread_through_all_blocks (true);
+
+ loop_optimizer_finalize ();
return 0;
}
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index f85fed3..8e08ae2 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -2086,42 +2086,6 @@ mark_threaded_blocks (bitmap threaded_blocks)
else
bitmap_copy (threaded_blocks, tmp);
- /* Look for jump threading paths which cross multiple loop headers.
-
- The code to thread through loop headers will change the CFG in ways
- that invalidate the cached loop iteration information. So we must
- detect that case and wipe the cached information. */
- EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
- {
- basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- if (e->aux)
- {
- vec<jump_thread_edge *> *path = THREAD_PATH (e);
-
- for (unsigned int i = 0, crossed_headers = 0;
- i < path->length ();
- i++)
- {
- basic_block dest = (*path)[i]->e->dest;
- basic_block src = (*path)[i]->e->src;
- crossed_headers += (dest == dest->loop_father->header);
- /* If we step from a block outside an irreducible region
- to a block inside an irreducible region, then we have
- crossed into a loop. */
- crossed_headers += ((src->flags & BB_IRREDUCIBLE_LOOP)
- != (dest->flags & BB_IRREDUCIBLE_LOOP));
- if (crossed_headers > 1)
- {
- vect_free_loop_info_assumptions (dest->loop_father);
- break;
- }
- }
- }
- }
- }
-
/* If we have a joiner block (J) which has two successors S1 and S2 and
we are threading though S1 and the final destination of the thread
is S2, then we must verify that any PHI nodes in S2 have the same
@@ -2166,6 +2130,46 @@ mark_threaded_blocks (bitmap threaded_blocks)
}
}
+ /* Look for jump threading paths which cross multiple loop headers.
+
+ The code to thread through loop headers will change the CFG in ways
+ that invalidate the cached loop iteration information. So we must
+ detect that case and wipe the cached information. */
+ EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
+ {
+ basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ if (e->aux)
+ {
+ vec<jump_thread_edge *> *path = THREAD_PATH (e);
+
+ for (unsigned int i = 0, crossed_headers = 0;
+ i < path->length ();
+ i++)
+ {
+ basic_block dest = (*path)[i]->e->dest;
+ basic_block src = (*path)[i]->e->src;
+ /* If we enter a loop. */
+ if (flow_loop_nested_p (src->loop_father, dest->loop_father))
+ ++crossed_headers;
+ /* If we step from a block outside an irreducible region
+ to a block inside an irreducible region, then we have
+ crossed into a loop. */
+ else if (! (src->flags & BB_IRREDUCIBLE_LOOP)
+ && (dest->flags & BB_IRREDUCIBLE_LOOP))
+ ++crossed_headers;
+ if (crossed_headers > 1)
+ {
+ vect_free_loop_info_assumptions
+ ((*path)[path->length () - 1]->e->dest->loop_father);
+ break;
+ }
+ }
+ }
+ }
+ }
+
BITMAP_FREE (tmp);
}