Hi,
this patch fixes the testcasein PR63186. Here a forced label is used and fnsplit
decides to split its use from definition that does not work.  There is code that
is supposed to prevent this. It however works on non-ssa declarations in general
and it has an optimization - it allows the non-ssa declarations to be split when
their liveranes do not overlap by skipping all the definitions in header
parts that do not lead to function call.  This doesn't work for labels: we 
really
want to consider all label definitions in this case.

I also added minor optimization skipping all non-forced labels to save non-ssa
verficiation pass when there are no non-ssa vars involved (the common case)

Bootstrapped/regtested x86_64-linux, will commit it tomorrow if there are
no complains.

Honza
        PR tree-optimization/63186
        * gcc.dg/pr63186.c: New testcase.
        * ipa-split.c (test_nonssa_use): Skip non-forced labels.
        (verify_non_ssa_vars): Verify blocks not leading to the call
        for label definitions.
        (mark_nonssa_use): Skip non-forced labels.
Index: testsuite/gcc.dg/pr63186.c
===================================================================
--- testsuite/gcc.dg/pr63186.c  (revision 0)
+++ testsuite/gcc.dg/pr63186.c  (revision 0)
@@ -0,0 +1,30 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+void *a;
+int b, c, d;
+
+void
+bar ()
+{
+  switch (c)
+    {
+    case 0:
+    lab:
+      __asm__ ("");
+      return;
+    default:
+      break;
+    }
+  b = 0;
+  d = 0;
+  a = &&lab;
+}
+
+void
+foo ()
+{
+  bar ();
+}
+main()
+{
+}
Index: ipa-split.c
===================================================================
--- ipa-split.c (revision 215104)
+++ ipa-split.c (working copy)
@@ -167,7 +167,11 @@ test_nonssa_use (gimple, tree t, tree, v
       || (TREE_CODE (t) == VAR_DECL
          && auto_var_in_fn_p (t, current_function_decl))
       || TREE_CODE (t) == RESULT_DECL
-      || TREE_CODE (t) == LABEL_DECL)
+        /* Normal labels are part of CFG and will be handled gratefuly.
+           Forced labels however can be used directly by statements and
+           need to stay in one partition along with their uses.  */
+      || (TREE_CODE (t) == LABEL_DECL
+         && FORCED_LABEL (t)))
     return bitmap_bit_p ((bitmap)data, DECL_UID (t));
 
   /* For DECL_BY_REFERENCE, the return value is actually a pointer.  We want
@@ -213,6 +217,7 @@ verify_non_ssa_vars (struct split_point
   edge e;
   edge_iterator ei;
   bool ok = true;
+  basic_block bb;
 
   FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
     if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
@@ -225,8 +230,8 @@ verify_non_ssa_vars (struct split_point
   while (!worklist.is_empty ())
     {
       gimple_stmt_iterator bsi;
-      basic_block bb = worklist.pop ();
 
+      bb = worklist.pop ();
       FOR_EACH_EDGE (e, ei, bb->preds)
        if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
            && bitmap_set_bit (seen, e->src->index))
@@ -250,10 +255,10 @@ verify_non_ssa_vars (struct split_point
          if (gimple_code (stmt) == GIMPLE_LABEL
              && test_nonssa_use (stmt, gimple_label_label (stmt),
                                  NULL_TREE, non_ssa_vars))
-         {
-           ok = false;
-           goto done;
-         }
+           {
+             ok = false;
+             goto done;
+           }
        }
       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
        {
@@ -286,6 +291,27 @@ verify_non_ssa_vars (struct split_point
            }
        }
     }
+
+  /* Verify that the rest of function does not define any label
+     used by the split part.  */
+  FOR_EACH_BB_FN (bb, cfun)
+    if (!bitmap_bit_p (current->split_bbs, bb->index)
+       && !bitmap_bit_p (seen, bb->index))
+      {
+        gimple_stmt_iterator bsi;
+        for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+         if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL
+             && test_nonssa_use (gsi_stmt (bsi),
+                                 gimple_label_label (gsi_stmt (bsi)),
+                                 NULL_TREE, non_ssa_vars))
+           {
+             ok = false;
+             goto done;
+           }
+         else if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL)
+           break;
+      }
+    
 done:
   BITMAP_FREE (seen);
   worklist.release ();
@@ -735,7 +761,8 @@ mark_nonssa_use (gimple, tree t, tree, v
   if ((TREE_CODE (t) == VAR_DECL
        && auto_var_in_fn_p (t, current_function_decl))
       || TREE_CODE (t) == RESULT_DECL
-      || TREE_CODE (t) == LABEL_DECL)
+      || (TREE_CODE (t) == LABEL_DECL
+         && FORCED_LABEL (t)))
     bitmap_set_bit ((bitmap)data, DECL_UID (t));
 
   /* For DECL_BY_REFERENCE, the return value is actually a pointer.  We want

Reply via email to