Commit ef3cfba2 by Jeff Law Committed by Jeff Law

re PR tree-optimization/58640 (wrong code (segfaults) at -O3 on x86_64-linux-gnu)

	PR tree-optimization/58640
	* tree-ssa-threadupdate.c (mark_threaded_blocks): Truncate jump threading
	paths that cross over two loop entry points.

	* gcc.c-torture/execute/pr58640.c: New test.

From-SVN: r203463
parent 6e8b7d9c
2013-10-11 Jeff Law <law@redhat.com>
PR tree-optimization/58640
* tree-ssa-threadupdate.c (mark_threaded_blocks): Truncate jump threading
paths that cross over two loop entry points.
2013-10-11 Bill Schmidt <wschmidt@linux.vnet.ibm.com> 2013-10-11 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* config/rs6000/vsx.md (*vsx_le_perm_load_v2di): Generalize to * config/rs6000/vsx.md (*vsx_le_perm_load_v2di): Generalize to
......
2013-10-11 Jeff Law <law@redhat.com>
* gcc.c-torture/execute/pr58640.c: New test.
2013-10-11 Paolo Carlini <paolo.carlini@oracle.com> 2013-10-11 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58633 PR c++/58633
......
int a, b, c, d = 1, e;
static signed char
foo ()
{
int f, g = a;
for (f = 1; f < 3; f++)
for (; b < 1; b++)
{
if (d)
for (c = 0; c < 4; c++)
for (f = 0; f < 3; f++)
{
for (e = 0; e < 1; e++)
a = g;
if (f)
break;
}
else if (f)
continue;
return 0;
}
return 0;
}
int
main ()
{
foo ();
exit (0);
}
...@@ -1354,6 +1354,68 @@ mark_threaded_blocks (bitmap threaded_blocks) ...@@ -1354,6 +1354,68 @@ mark_threaded_blocks (bitmap threaded_blocks)
else else
bitmap_copy (threaded_blocks, tmp); 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 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. */
EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
{
basic_block bb = BASIC_BLOCK (i);
FOR_EACH_EDGE (e, ei, bb->preds)
{
if (e->aux)
{
vec<jump_thread_edge *> *path = THREAD_PATH (e);
/* Basically we're looking for a situation where we can see
3 or more loop structures on a jump threading path. */
struct loop *first_father = (*path)[0]->e->src->loop_father;
struct loop *second_father = NULL;
for (unsigned int i = 0; i < path->length (); i++)
{
/* See if this is a loop father we have not seen before. */
if ((*path)[i]->e->dest->loop_father != first_father
&& (*path)[i]->e->dest->loop_father != second_father)
{
/* We've already seen two loop fathers, so we
need to trim this jump threading path. */
if (second_father != NULL)
{
/* 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))
{
for (unsigned int i = 0; i < path->length (); i++)
delete (*path)[i];
path->release ();
e->aux = NULL;
}
break;
}
else
{
second_father = (*path)[i]->e->dest->loop_father;
}
}
}
}
}
}
BITMAP_FREE (tmp); BITMAP_FREE (tmp);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment