re PR tree-optimization/80549 (wrong code at -O2 and -O3 in both 32-bit and 64-bit modes on x86_64-linux-gnu (executable does not terminate))
2017-05-02 Richard Biener <rguenther@suse.de> PR tree-optimization/80549 * tree-cfgcleanup.c (mfb_keep_latches): New helper. (cleanup_tree_cfg_noloop): Create forwarders to known loop headers if they do not have a preheader. * gcc.dg/torture/pr80549.c: New testcase. From-SVN: r247486
This commit is contained in:
parent
51956afe27
commit
e7d70c6c3b
4 changed files with 108 additions and 0 deletions
|
@ -1,3 +1,10 @@
|
|||
2017-05-02 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/80549
|
||||
* tree-cfgcleanup.c (mfb_keep_latches): New helper.
|
||||
(cleanup_tree_cfg_noloop): Create forwarders to known loop
|
||||
headers if they do not have a preheader.
|
||||
|
||||
2017-05-02 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR other/80589
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2017-05-02 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/80549
|
||||
* gcc.dg/torture/pr80549.c: New testcase.
|
||||
|
||||
2017-05-02 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
|
||||
|
||||
* gcc.dg/pr78138.c: Use __SIZE_TYPE__ instead of
|
||||
|
|
33
gcc/testsuite/gcc.dg/torture/pr80549.c
Normal file
33
gcc/testsuite/gcc.dg/torture/pr80549.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
signed char a, b;
|
||||
int c;
|
||||
short d;
|
||||
void fn1(int p1)
|
||||
{
|
||||
short e = 4;
|
||||
int f;
|
||||
d = 0;
|
||||
for (; d <= 0; d++)
|
||||
e = 0;
|
||||
if (e)
|
||||
goto L1;
|
||||
L2:
|
||||
if (p1) {
|
||||
a = 9;
|
||||
for (; a; ++a) {
|
||||
f = 5;
|
||||
for (; f != 32; ++f)
|
||||
c = 8;
|
||||
L1:
|
||||
if (b)
|
||||
goto L2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
fn1(1);
|
||||
return 0;
|
||||
}
|
|
@ -739,6 +739,11 @@ cleanup_tree_cfg_1 (void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static bool
|
||||
mfb_keep_latches (edge e)
|
||||
{
|
||||
return ! dominated_by_p (CDI_DOMINATORS, e->src, e->dest);
|
||||
}
|
||||
|
||||
/* Remove unreachable blocks and other miscellaneous clean up work.
|
||||
Return true if the flowgraph was modified, false otherwise. */
|
||||
|
@ -766,6 +771,64 @@ cleanup_tree_cfg_noloop (void)
|
|||
changed = false;
|
||||
}
|
||||
|
||||
/* Ensure that we have single entries into loop headers. Otherwise
|
||||
if one of the entries is becoming a latch due to CFG cleanup
|
||||
(from formerly being part of an irreducible region) then we mess
|
||||
up loop fixup and associate the old loop with a different region
|
||||
which makes niter upper bounds invalid. See for example PR80549.
|
||||
This needs to be done before we remove trivially dead edges as
|
||||
we need to capture the dominance state before the pending transform. */
|
||||
if (current_loops)
|
||||
{
|
||||
loop_p loop;
|
||||
unsigned i;
|
||||
FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop)
|
||||
if (loop && loop->header)
|
||||
{
|
||||
basic_block bb = loop->header;
|
||||
edge_iterator ei;
|
||||
edge e;
|
||||
bool found_latch = false;
|
||||
bool any_abnormal = false;
|
||||
unsigned n = 0;
|
||||
/* We are only interested in preserving existing loops, but
|
||||
we need to check whether they are still real and of course
|
||||
if we need to add a preheader at all. */
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
if (e->flags & EDGE_ABNORMAL)
|
||||
{
|
||||
any_abnormal = true;
|
||||
break;
|
||||
}
|
||||
if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
|
||||
{
|
||||
found_latch = true;
|
||||
continue;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
/* If we have more than one entry to the loop header
|
||||
create a forwarder. */
|
||||
if (found_latch && ! any_abnormal && n > 1)
|
||||
{
|
||||
edge fallthru = make_forwarder_block (bb, mfb_keep_latches,
|
||||
NULL);
|
||||
loop->header = fallthru->dest;
|
||||
if (! loops_state_satisfies_p (LOOPS_NEED_FIXUP))
|
||||
{
|
||||
/* The loop updating from the CFG hook is incomplete
|
||||
when we have multiple latches, fixup manually. */
|
||||
remove_bb_from_loops (fallthru->src);
|
||||
loop_p cloop = loop;
|
||||
FOR_EACH_EDGE (e, ei, fallthru->src->preds)
|
||||
cloop = find_common_loop (cloop, e->src->loop_father);
|
||||
add_bb_to_loop (fallthru->src, cloop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changed |= cleanup_tree_cfg_1 ();
|
||||
|
||||
gcc_assert (dom_info_available_p (CDI_DOMINATORS));
|
||||
|
|
Loading…
Add table
Reference in a new issue