diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd2d1a37535..c5a80e1732b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2012-11-13 Jakub Jelinek + + PR rtl-optimization/54127 + * cfgrtl.c (force_nonfallthru_and_redirect): When redirecting + asm goto labels from BB_HEAD (e->dest) to target bb, decrement + LABEL_NUSES of BB_HEAD (e->dest) and increment LABEL_NUSES of + BB_HEAD (target) appropriately and adjust JUMP_LABEL and/or + REG_LABEL_TARGET and REG_LABEL_OPERAND. + 2012-11-12 Jakub Jelinek * asan.c (instrument_builtin_call) : Fix up @@ -11,7 +20,7 @@ 2012-11-12 David Edelsohn - * asan.c: Include tm_p.h + * asan.c: Include tm_p.h. 2012-11-12 John David Anglin diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 1f601e51d03..8855bdf9861 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1424,14 +1424,46 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) && (note = extract_asm_operands (PATTERN (BB_END (e->src))))) { int i, n = ASM_OPERANDS_LABEL_LENGTH (note); + bool adjust_jump_target = false; for (i = 0; i < n; ++i) { if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (e->dest)) - XEXP (ASM_OPERANDS_LABEL (note, i), 0) = block_label (target); + { + LABEL_NUSES (XEXP (ASM_OPERANDS_LABEL (note, i), 0))--; + XEXP (ASM_OPERANDS_LABEL (note, i), 0) = block_label (target); + LABEL_NUSES (XEXP (ASM_OPERANDS_LABEL (note, i), 0))++; + adjust_jump_target = true; + } if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target)) asm_goto_edge = true; } + if (adjust_jump_target) + { + rtx insn = BB_END (e->src), note; + rtx old_label = BB_HEAD (e->dest); + rtx new_label = BB_HEAD (target); + + if (JUMP_LABEL (insn) == old_label) + { + JUMP_LABEL (insn) = new_label; + note = find_reg_note (insn, REG_LABEL_TARGET, new_label); + if (note) + remove_note (insn, note); + } + else + { + note = find_reg_note (insn, REG_LABEL_TARGET, old_label); + if (note) + remove_note (insn, note); + if (JUMP_LABEL (insn) != new_label + && !find_reg_note (insn, REG_LABEL_TARGET, new_label)) + add_reg_note (insn, REG_LABEL_TARGET, new_label); + } + while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label)) + != NULL_RTX) + XEXP (note, 0) = new_label; + } } if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f236a2f4d1b..8a369247cb0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-11-13 Jakub Jelinek + + PR rtl-optimization/54127 + * gcc.dg/torture/pr54127.c: New test. + 2012-11-12 Steven Bosscher Jakub Jelinek diff --git a/gcc/testsuite/gcc.dg/torture/pr54127.c b/gcc/testsuite/gcc.dg/torture/pr54127.c new file mode 100644 index 00000000000..4f64998af0a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr54127.c @@ -0,0 +1,16 @@ +/* PR rtl-optimization/54127 */ +/* { dg-do compile } */ + +extern void foo (void) __attribute__ ((__noreturn__)); + +void +bar (int x) +{ + if (x < 0) + foo (); + if (x == 0) + return; + __asm goto ("# %l[lab] %l[lab2]" : : : : lab, lab2); +lab:; +lab2:; +}