tree-optimization/106182 - LC SSA after CFG cleanup
authorRichard Biener <rguenther@suse.de>
Mon, 4 Jul 2022 13:03:33 +0000 (15:03 +0200)
committerRichard Biener <rguenther@suse.de>
Tue, 5 Jul 2022 07:28:45 +0000 (09:28 +0200)
The testcase shows that when cleaning up the CFG we can end up
with broken LC SSA (for virtual operands with the testcase).  The
case here involves deleting a loop after which it is not enough
to scan the blocks with changed loop depth for SSA uses that need
to be rewritten.  So make fix_loop_sturcture return the sum of
the number of new loops and the number of deleted loops.

PR tree-optimization/106182
* loop-init.cc (fix_loop_structure): Return the number
of newly discovered plus the number of deleted loops.
* tree-cfgcleanup.cc (repair_loop_structures): Adjust
variable name.

* gcc.dg/torture/pr106182.c: New testcase.

gcc/loop-init.cc
gcc/testsuite/gcc.dg/torture/pr106182.c [new file with mode: 0644]
gcc/tree-cfgcleanup.cc

index 648aa29..b9e0797 100644 (file)
@@ -194,7 +194,7 @@ loop_fini_done:
    If CHANGED_BBS is not NULL, basic blocks whose loop depth has changed are
    marked in it.
 
-   Returns the number of new discovered loops.  */
+   Returns the number of new discovered plus the number of removed loops.  */
 
 unsigned
 fix_loop_structure (bitmap changed_bbs)
@@ -277,7 +277,7 @@ fix_loop_structure (bitmap changed_bbs)
     }
 
   /* Finally free deleted loops.  */
-  bool any_deleted = false;
+  unsigned n_deleted = 0;
   class loop *loop;
   FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop)
     if (loop && loop->header == NULL)
@@ -311,12 +311,12 @@ fix_loop_structure (bitmap changed_bbs)
          }
        (*get_loops (cfun))[i] = NULL;
        flow_loop_free (loop);
-       any_deleted = true;
+       n_deleted++;
       }
 
   /* If we deleted loops then the cached scalar evolutions refering to
      those loops become invalid.  */
-  if (any_deleted && scev_initialized_p ())
+  if (n_deleted > 0 && scev_initialized_p ())
     scev_reset_htab ();
 
   loops_state_clear (LOOPS_NEED_FIXUP);
@@ -328,7 +328,7 @@ fix_loop_structure (bitmap changed_bbs)
 
   timevar_pop (TV_LOOP_INIT);
 
-  return number_of_loops (cfun) - old_nloops;
+  return number_of_loops (cfun) - old_nloops + n_deleted;
 }
 \f
 /* The RTL loop superpass.  The actual passes are subpasses.  See passes.cc for
diff --git a/gcc/testsuite/gcc.dg/torture/pr106182.c b/gcc/testsuite/gcc.dg/torture/pr106182.c
new file mode 100644 (file)
index 0000000..6b5c249
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-funswitch-loops" } */
+
+short var_32;
+int test_var_0;
+unsigned char test_var_6;
+char test_var_13;
+void test(int var_2)
+{
+  for (;;)
+    for (short i_7; i_7 < test_var_13; i_7 += 1)
+      for (; test_var_0;) {
+        for (; var_2;)
+          var_32 = 0;
+        for (char i_19; i_19 < test_var_6 + 135; i_19 += 200)
+          ;
+      }
+}
index a6d0bf2..3b24e02 100644 (file)
@@ -1170,13 +1170,13 @@ static void
 repair_loop_structures (void)
 {
   bitmap changed_bbs;
-  unsigned n_new_loops;
+  unsigned n_new_or_deleted_loops;
 
   calculate_dominance_info (CDI_DOMINATORS);
 
   timevar_push (TV_REPAIR_LOOPS);
   changed_bbs = BITMAP_ALLOC (NULL);
-  n_new_loops = fix_loop_structure (changed_bbs);
+  n_new_or_deleted_loops = fix_loop_structure (changed_bbs);
 
   /* This usually does nothing.  But sometimes parts of cfg that originally
      were inside a loop get out of it due to edge removal (since they
@@ -1184,7 +1184,7 @@ repair_loop_structures (void)
      irreducible loop can become reducible - in this case force a full
      rewrite into loop-closed SSA form.  */
   if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
-    rewrite_into_loop_closed_ssa (n_new_loops ? NULL : changed_bbs,
+    rewrite_into_loop_closed_ssa (n_new_or_deleted_loops ? NULL : changed_bbs,
                                  TODO_update_ssa);
 
   BITMAP_FREE (changed_bbs);