re PR tree-optimization/69740 (gcc ICE at -O2 and above on valid code on x86_64-linux-gnu in "verify_loop_structure")

PR tree-optimization/69740
	* cfghooks.c (remove_edge): Request loop fixups if we delete
	an edge that might turn an irreducible loop into a natural
	loop.
	* cfgloop.h (check_verify_loop_structure): Clear LOOPS_NEED_FIXUP.
	Move after definition of loops_state_clear.

	PR tree-optimization/69740
	* gcc.c-torture/compile/pr69740-1.c: New test.
	* gcc.c-torture/compile/pr69740-2.c: New test.

Co-Authored-By: Jeff Law <law@redhat.com>

From-SVN: r234036
This commit is contained in:
Richard Biener 2016-03-07 17:01:54 +00:00 committed by Jeff Law
parent 55a82b661e
commit a84a49b7e7
6 changed files with 84 additions and 11 deletions

View File

@ -1,3 +1,13 @@
2016-02-26 Richard Biener <rguenther@suse.de>
Jeff Law <law@redhat.com>
PR tree-optimization/69740
* cfghooks.c (remove_edge): Request loop fixups if we delete
an edge that might turn an irreducible loop into a natural
loop.
* cfgloop.h (check_verify_loop_structure): Clear LOOPS_NEED_FIXUP.
Move after definition of loops_state_clear.
2016-03-07 Bin Cheng <bin.cheng@arm.com>
PR rtl-optimization/69052

View File

@ -408,7 +408,20 @@ void
remove_edge (edge e)
{
if (current_loops != NULL)
rescan_loop_exit (e, false, true);
{
rescan_loop_exit (e, false, true);
/* Removal of an edge inside an irreducible region or which leads
to an irreducible region can turn the region into a natural loop.
In that case, ask for the loop structure fixups.
FIXME: Note that LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS is not always
set, so always ask for fixups when removing an edge in that case. */
if (!loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
|| (e->flags & EDGE_IRREDUCIBLE_LOOP)
|| (e->dest->flags & BB_IRREDUCIBLE_LOOP))
loops_state_set (LOOPS_NEED_FIXUP);
}
/* This is probably not needed, but it doesn't hurt. */
/* FIXME: This should be called via a remove_edge hook. */

View File

@ -314,16 +314,6 @@ extern void delete_loop (struct loop *);
extern void verify_loop_structure (void);
/* Check loop structure invariants, if internal consistency checks are
enabled. */
static inline void
checking_verify_loop_structure (void)
{
if (flag_checking)
verify_loop_structure ();
}
/* Loop analysis. */
extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
gcov_type expected_loop_iterations_unbounded (const struct loop *);
@ -546,6 +536,28 @@ loops_state_clear (unsigned flags)
loops_state_clear (cfun, flags);
}
/* Check loop structure invariants, if internal consistency checks are
enabled. */
static inline void
checking_verify_loop_structure (void)
{
/* VERIFY_LOOP_STRUCTURE essentially asserts that no loops need fixups.
The loop optimizers should never make changes to the CFG which
require loop fixups. But the low level CFG manipulation code may
set the flag conservatively.
Go ahead and clear the flag here. That avoids the assert inside
VERIFY_LOOP_STRUCTURE, and if there is an inconsistency in the loop
structures VERIFY_LOOP_STRUCTURE will detect it.
This also avoid the compile time cost of excessive fixups. */
loops_state_clear (LOOPS_NEED_FIXUP);
if (flag_checking)
verify_loop_structure ();
}
/* Loop iterators. */
/* Flags for loop iteration. */

View File

@ -1,3 +1,10 @@
2016-02-26 Richard Biener <rguenther@suse.de>
Jeff Law <law@redhat.com>
PR tree-optimization/69740
* gcc.c-torture/compile/pr69740-1.c: New test.
* gcc.c-torture/compile/pr69740-2.c: New test.
2016-03-07 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* lib/target-supports.exp

View File

@ -0,0 +1,12 @@
char a;
short b;
void fn1() {
if (b)
;
else {
int c[1] = {0};
l1:;
}
if (a)
goto l1;
}

View File

@ -0,0 +1,19 @@
inline int foo(int *p1, int p2) {
int z = *p1;
while (z > p2)
p2 = 2;
return z;
}
int main() {
int i;
for (;;) {
int j, k;
i = foo(&k, 7);
if (k)
j = i;
else
k = j;
if (2 != j)
__builtin_abort();
}
}