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