re PR tree-optimization/79088 (wrong code at -O2 on x86_64-linux-gnu)
2017-01-23 Richard Biener <rguenther@suse.de> PR tree-optimization/79088 PR tree-optimization/79188 * tree-ssa-threadupdate.c (mark_threaded_blocks): Move code resetting loop bounds after last path deletion. Reset loop bounds of the target loop, make code match the comments. * tree-ssa-threadbackwards.c (pass_early_thread_jumps::execute): Make sure loops need no fixups. * gcc.dg/torture/pr79088.c: New testcase. * gcc.dg/torture/pr79188.c: Likewise. From-SVN: r244837
This commit is contained in:
parent
01f26e0e1f
commit
108fdd6d84
|
@ -1,3 +1,13 @@
|
|||
2017-01-23 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/79088
|
||||
PR tree-optimization/79188
|
||||
* tree-ssa-threadupdate.c (mark_threaded_blocks): Move code
|
||||
resetting loop bounds after last path deletion. Reset loop
|
||||
bounds of the target loop, make code match the comments.
|
||||
* tree-ssa-threadbackwards.c (pass_early_thread_jumps::execute):
|
||||
Make sure loops need no fixups.
|
||||
|
||||
2017-01-23 Kelvin Nilsen <kelvin@gcc.gnu.org>
|
||||
|
||||
* config/rs6000/rs6000-builtin.def (VSIEDPF): Add scalar insert
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2017-01-23 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/79088
|
||||
PR tree-optimization/79188
|
||||
* gcc.dg/torture/pr79088.c: New testcase.
|
||||
* gcc.dg/torture/pr79188.c: Likewise.
|
||||
|
||||
2017-01-23 Kelvin Nilsen <kelvin@gcc.gnu.org>
|
||||
|
||||
* gcc.target/powerpc/bfp/scalar-insert-exp-3.c: New test.
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
int a, b, c, d, e = 1;
|
||||
|
||||
int main ()
|
||||
{
|
||||
int f;
|
||||
if (a)
|
||||
goto L;
|
||||
for (f = 0; f < e; e++)
|
||||
{
|
||||
L:
|
||||
if (d)
|
||||
continue;
|
||||
if (c)
|
||||
goto L;
|
||||
for (a = 0; a < 6; a++)
|
||||
for (f = 0; f < 3; f++)
|
||||
while (b)
|
||||
c++;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
int a, b, c, d, e, f, h, j, k;
|
||||
|
||||
static void fn1 ()
|
||||
{
|
||||
int g = 1, i;
|
||||
if (!f)
|
||||
{
|
||||
for (; d < 1; d++)
|
||||
for (i = 0, j = 1; i < 1; i = j)
|
||||
a = 2;
|
||||
for (; e < 1; e++)
|
||||
{
|
||||
for (; k; k++)
|
||||
L:
|
||||
;
|
||||
for (c = 0; c < 2; c++)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (; h; h++)
|
||||
g = 0;
|
||||
b = 0;
|
||||
}
|
||||
if (b)
|
||||
goto L;
|
||||
}
|
||||
a = 0;
|
||||
}
|
||||
if (g < 0)
|
||||
goto L;
|
||||
}
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
fn1 ();
|
||||
|
||||
if (a != 0)
|
||||
__builtin_abort ();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -865,6 +865,8 @@ pass_early_thread_jumps::gate (function *fun ATTRIBUTE_UNUSED)
|
|||
unsigned int
|
||||
pass_early_thread_jumps::execute (function *fun)
|
||||
{
|
||||
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
|
||||
|
||||
/* Try to thread each block with more than one successor. */
|
||||
basic_block bb;
|
||||
FOR_EACH_BB_FN (bb, fun)
|
||||
|
@ -873,6 +875,8 @@ pass_early_thread_jumps::execute (function *fun)
|
|||
find_jump_threads_backwards (bb, false);
|
||||
}
|
||||
thread_through_all_blocks (true);
|
||||
|
||||
loop_optimizer_finalize ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2086,42 +2086,6 @@ mark_threaded_blocks (bitmap threaded_blocks)
|
|||
else
|
||||
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 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);
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
if (e->aux)
|
||||
{
|
||||
vec<jump_thread_edge *> *path = THREAD_PATH (e);
|
||||
|
||||
for (unsigned int i = 0, crossed_headers = 0;
|
||||
i < path->length ();
|
||||
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)
|
||||
{
|
||||
vect_free_loop_info_assumptions (dest->loop_father);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a joiner block (J) which has two successors S1 and S2 and
|
||||
we are threading though S1 and the final destination of the thread
|
||||
is S2, then we must verify that any PHI nodes in S2 have the same
|
||||
|
@ -2166,6 +2130,46 @@ 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 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);
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
if (e->aux)
|
||||
{
|
||||
vec<jump_thread_edge *> *path = THREAD_PATH (e);
|
||||
|
||||
for (unsigned int i = 0, crossed_headers = 0;
|
||||
i < path->length ();
|
||||
i++)
|
||||
{
|
||||
basic_block dest = (*path)[i]->e->dest;
|
||||
basic_block src = (*path)[i]->e->src;
|
||||
/* If we enter a loop. */
|
||||
if (flow_loop_nested_p (src->loop_father, dest->loop_father))
|
||||
++crossed_headers;
|
||||
/* If we step from a block outside an irreducible region
|
||||
to a block inside an irreducible region, then we have
|
||||
crossed into a loop. */
|
||||
else if (! (src->flags & BB_IRREDUCIBLE_LOOP)
|
||||
&& (dest->flags & BB_IRREDUCIBLE_LOOP))
|
||||
++crossed_headers;
|
||||
if (crossed_headers > 1)
|
||||
{
|
||||
vect_free_loop_info_assumptions
|
||||
((*path)[path->length () - 1]->e->dest->loop_father);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BITMAP_FREE (tmp);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue