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>
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>
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 "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;
}
}