From 1c06f07f71fad83bc2fd358a09757a7ef725ef6a Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 3 Jan 2017 22:31:23 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 ++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.c-torture/execute/pr78856.c | 25 +++++++++++++++ gcc/tree-ssa-threadupdate.c | 31 ++++++------------- 4 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr78856.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3114e02af67..6b2888f36f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-01-03 Jeff Law + + 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 PR target/78900 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd2a065ec14..cadfbc977ce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-01-03 Jeff Law + + PR tree-optimization/78856 + * gcc.c-torture/execute/pr78856.c: New test. + 2017-01-03 Michael Meissner 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 00000000000..80f2317a15b --- /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 adbb6e01c3f..2da93a803d4 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; } } -- 2.30.2