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
This commit is contained in:
Jeff Law 2017-01-03 22:31:23 -07:00 committed by Jeff Law
parent 60fb638f9c
commit 1c06f07f71
4 changed files with 49 additions and 21 deletions

View File

@ -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> 2016-12-30 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78900 PR target/78900

View File

@ -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> 2017-01-03 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78953 PR target/78953

View File

@ -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);
}

View File

@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h" #include "cfgloop.h"
#include "dbgcnt.h" #include "dbgcnt.h"
#include "tree-cfg.h" #include "tree-cfg.h"
#include "tree-vectorizer.h"
/* Given a block B, update the CFG and SSA graph to reflect redirecting /* 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 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. /* Look for jump threading paths which cross multiple loop headers.
The code to thread through loop headers will change the CFG in ways The code to thread through loop headers will change the CFG in ways
that break assumptions made by the loop optimization code. that invalidate the cached loop iteration information. So we must
detect that case and wipe the cached information. */
We don't want to blindly cancel the requests. We can instead do better
by trimming off the end of the jump thread path. */
EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi) EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
{ {
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i); basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
@ -2102,26 +2101,16 @@ mark_threaded_blocks (bitmap threaded_blocks)
i++) i++)
{ {
basic_block dest = (*path)[i]->e->dest; basic_block dest = (*path)[i]->e->dest;
basic_block src = (*path)[i]->e->src;
crossed_headers += (dest == dest->loop_father->header); 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) if (crossed_headers > 1)
{ {
/* Trim from entry I onwards. */ vect_free_loop_info_assumptions (dest->loop_father);
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;
}
break; break;
} }
} }