]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/69740 (gcc ICE at -O2 and above on valid code on x86_64-linux...
authorRichard Biener <rguenther@suse.de>
Mon, 7 Mar 2016 17:01:54 +0000 (17:01 +0000)
committerJeff Law <law@gcc.gnu.org>
Mon, 7 Mar 2016 17:01:54 +0000 (10:01 -0700)
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

gcc/ChangeLog
gcc/cfghooks.c
gcc/cfgloop.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr69740-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr69740-2.c [new file with mode: 0644]

index bab653018d5f1ee8924c6ec6779de3a3bad63060..9f83f366ab397589a1c1765ddc11bda78898603b 100644 (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
index bbb1017fd1f951637314ce3a8e145acdb7f078d5..06c05d1fb39a6146de45ac0b71fda31284fb3994 100644 (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.  */
index 882861c3d7ef231fc80b6a03f2df06bd59e303d6..54e738f20f4c333722851f18ea8c419404a9e863 100644 (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.  */
index 4447ba6bd5d0539807338baccabef83205aacde8..bf8e231065c3d3f7fbb395b88de15085ff8c1095 100644 (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
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 (file)
index 0000000..ac867d8
--- /dev/null
@@ -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 (file)
index 0000000..a89c9a0
--- /dev/null
@@ -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();
+  }
+}