aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2017-01-03 22:31:23 -0700
committerJeff Law <law@gcc.gnu.org>2017-01-03 22:31:23 -0700
commit1c06f07f71fad83bc2fd358a09757a7ef725ef6a (patch)
treef4eebb0e6cb731198ae71d0ade4382185c995f55
parent60fb638f9c08e2cf73605fc5a60531215098a82d (diff)
downloadgcc-1c06f07f71fad83bc2fd358a09757a7ef725ef6a.zip
gcc-1c06f07f71fad83bc2fd358a09757a7ef725ef6a.tar.gz
gcc-1c06f07f71fad83bc2fd358a09757a7ef725ef6a.tar.bz2
re PR tree-optimization/78856 (wrong code at -O3 on x86_64-linux-gnu (in both 32-bit and 64-bit modes))
PR tree-optimizatin/78856 * tree-ssa-threadupdate.c: Include tree-vectorizer.h. (mark_threaded_blocks): Remove code to truncate thread paths that cross multiple loop headers. Instead invalidate the cached loop iteration information and handle case of a thread path walking into an irreducible region. PR tree-optimization/78856 * gcc.c-torture/execute/pr78856.c: New test. From-SVN: r244045
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr78856.c25
-rw-r--r--gcc/tree-ssa-threadupdate.c31
4 files changed, 49 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3114e02..6b2888f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2017-01-03 Jeff Law <law@redhat.com>
+
+ PR tree-optimizatin/78856
+ * tree-ssa-threadupdate.c: Include tree-vectorizer.h.
+ (mark_threaded_blocks): Remove code to truncate thread paths that
+ cross multiple loop headers. Instead invalidate the cached loop
+ iteration information and handle case of a thread path walking
+ into an irreducible region.
+
2016-12-30 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78900
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cd2a065..cadfbc9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-01-03 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/78856
+ * gcc.c-torture/execute/pr78856.c: New test.
+
2017-01-03 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78953
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78856.c b/gcc/testsuite/gcc.c-torture/execute/pr78856.c
new file mode 100644
index 0000000..80f2317
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr78856.c
@@ -0,0 +1,25 @@
+extern void exit (int);
+
+int a, b, c, d, e, f[3];
+
+int main()
+{
+ while (d)
+ while (1)
+ ;
+ int g = 0, h, i = 0;
+ for (; g < 21; g += 9)
+ {
+ int j = 1;
+ for (h = 0; h < 3; h++)
+ f[h] = 1;
+ for (; j < 10; j++) {
+ d = i && (b ? 0 : c);
+ i = 1;
+ if (g)
+ a = e;
+ }
+ }
+ exit (0);
+}
+
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index adbb6e0..2da93a8 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "dbgcnt.h"
#include "tree-cfg.h"
+#include "tree-vectorizer.h"
/* Given a block B, update the CFG and SSA graph to reflect redirecting
one or more in-edges to B to instead reach the destination of an
@@ -2084,10 +2085,8 @@ 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 break assumptions made by the loop optimization code.
-
- We don't want to blindly cancel the requests. We can instead do better
- by trimming off the end of the jump thread path. */
+ 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);
@@ -2102,26 +2101,16 @@ mark_threaded_blocks (bitmap threaded_blocks)
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)
{
- /* Trim from entry I onwards. */
- for (unsigned int j = i; j < path->length (); j++)
- delete (*path)[j];
- path->truncate (i);
-
- /* Now that we've truncated the path, make sure
- what's left is still valid. We need at least
- two edges on the path and the last edge can not
- be a joiner. This should never happen, but let's
- be safe. */
- if (path->length () < 2
- || (path->last ()->type
- == EDGE_COPY_SRC_JOINER_BLOCK))
- {
- delete_jump_thread_path (path);
- e->aux = NULL;
- }
+ vect_free_loop_info_assumptions (dest->loop_father);
break;
}
}