Hi!

As discussed in the PR, sel-sched doesn't handle correctly
tidying of empty blocks if fallthru predecessor ends with asm goto
that has some labels on the empty block in addition to the fallthru edge.
cfgrtl.c can handle that, so this patch just gives up on it on the sel-sched
side.  The testcase is new since the patch in the PR, tested with unpatched
and patched gcc (fails vs. works).

Bootstrapped/regtested on x86_64-linux and i686-linux (as usually, with rtl
checking).  Ok for trunk?

2012-09-05  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/54455
        * sel-sched-ir.c (maybe_tidy_empty_bb): Give up if previous fallthru
        bb ends up with asm goto referencing bb's label.

        * gcc.dg/54455.c: New test.

--- gcc/sel-sched-ir.c.jj       2012-08-15 10:55:30.000000000 +0200
+++ gcc/sel-sched-ir.c  2012-09-03 09:56:59.352233243 +0200
@@ -3686,6 +3686,22 @@ maybe_tidy_empty_bb (basic_block bb)
   FOR_EACH_EDGE (e, ei, bb->preds)
     if (e->flags & EDGE_COMPLEX)
       return false;
+    else if (e->flags & EDGE_FALLTHRU)
+      {
+       rtx note;
+       /* If prev bb ends with asm goto, see if any of the
+          ASM_OPERANDS_LABELs don't point to the fallthru
+          label.  Do not attempt to redirect it in that case.  */
+       if (JUMP_P (BB_END (e->src))
+           && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
+         {
+           int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
+
+           for (i = 0; i < n; ++i)
+             if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (bb))
+               return false;
+         }
+      }
 
   free_data_sets (bb);
 
--- gcc/testsuite/gcc.dg/54455.c.jj     2012-06-15 19:53:34.312404791 +0200
+++ gcc/testsuite/gcc.dg/54455.c        2012-09-05 15:05:02.328728962 +0200
@@ -0,0 +1,25 @@
+/* PR rtl-optimization/54455 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fschedule-insns -fselective-scheduling --param 
max-sched-extend-regions-iters=8" } */
+
+extern void fn1 (void), fn2 (void);
+
+static inline __attribute__((always_inline)) int
+foo (int *x, long y)
+{
+  asm goto ("" : : "r" (x), "r" (y) : "memory" : lab);
+  return 0;
+lab:
+  return 1;
+}
+
+void
+bar (int *x)
+{
+  if (foo (x, 23))
+    fn1 ();
+  else
+    fn2 ();
+
+  foo (x, 2);
+}

        Jakub

Reply via email to