From a84a49b7e7ac9b6f576508aa0683a4f14cb44f7d Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 7 Mar 2016 17:01:54 +0000 Subject: [PATCH] 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 From-SVN: r234036 --- gcc/ChangeLog | 10 ++++++ gcc/cfghooks.c | 15 ++++++++- gcc/cfgloop.h | 32 +++++++++++++------ gcc/testsuite/ChangeLog | 7 ++++ .../gcc.c-torture/compile/pr69740-1.c | 12 +++++++ .../gcc.c-torture/compile/pr69740-2.c | 19 +++++++++++ 6 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr69740-1.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr69740-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bab653018d5..9f83f366ab3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-02-26 Richard Biener + Jeff Law + + 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 PR rtl-optimization/69052 diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index bbb1017fd1f..06c05d1fb39 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -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. */ diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 882861c3d7e..54e738f20f4 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4447ba6bd5d..bf8e231065c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-02-26 Richard Biener + Jeff Law + + 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 * lib/target-supports.exp diff --git a/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c b/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c new file mode 100644 index 00000000000..ac867d8a999 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c @@ -0,0 +1,12 @@ +char a; +short b; +void fn1() { + if (b) + ; + else { + int c[1] = {0}; + l1:; + } + if (a) + goto l1; +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c b/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c new file mode 100644 index 00000000000..a89c9a0fd12 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c @@ -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(); + } +} -- 2.30.2