From: Jakub Jelinek Date: Thu, 9 Feb 2012 21:36:54 +0000 (+0100) Subject: backport: re PR rtl-optimization/51767 (ICE with degenerated asm goto) X-Git-Tag: releases/gcc-4.5.4~229 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=15e45b414da575096214b01fbf30f0011f88397a;p=thirdparty%2Fgcc.git backport: re PR rtl-optimization/51767 (ICE with degenerated asm goto) Backported from mainline 2012-01-05 Jakub Jelinek PR rtl-optimization/51767 * cfgrtl.c (force_nonfallthru_and_redirect): Force addition of jump_block and add an extra edge for degenerated asm gotos. * gcc.c-torture/compile/pr51767.c: New test. From-SVN: r184072 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b71e79facaf3..fe4c69ef8ae9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -3,6 +3,10 @@ Backported from mainline 2012-01-05 Jakub Jelinek + PR rtl-optimization/51767 + * cfgrtl.c (force_nonfallthru_and_redirect): Force addition + of jump_block and add an extra edge for degenerated asm gotos. + PR middle-end/51768 * stmt.c (check_unique_operand_names): Don't ICE during error reporting if i is from labels chain. diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index db2c56e7ae61..814ad7846f42 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1116,6 +1116,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target) rtx note; edge new_edge; int abnormal_edge_flags = 0; + bool asm_goto_edge = false; int loc; /* In the case the last instruction is conditional jump to the next @@ -1195,8 +1196,28 @@ force_nonfallthru_and_redirect (edge e, basic_block target) } } - if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags) + /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs + don't point to target label. */ + if (JUMP_P (BB_END (e->src)) + && target != EXIT_BLOCK_PTR + && e->dest == target + && (e->flags & EDGE_FALLTHRU) + && (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 (target)) + { + asm_goto_edge = true; + break; + } + } + + if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge) + { + gcov_type count = e->count; + int probability = e->probability; /* Create the new structures. */ /* If the old block ended with a tablejump, skip its table @@ -1207,7 +1228,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target) note = NEXT_INSN (note); jump_block = create_basic_block (note, NULL, e->src); - jump_block->count = e->count; + jump_block->count = count; jump_block->frequency = EDGE_FREQUENCY (e); jump_block->loop_depth = target->loop_depth; @@ -1223,13 +1244,27 @@ force_nonfallthru_and_redirect (edge e, basic_block target) /* Wire edge in. */ new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU); - new_edge->probability = e->probability; - new_edge->count = e->count; + new_edge->probability = probability; + new_edge->count = count; /* Redirect old edge. */ redirect_edge_pred (e, jump_block); e->probability = REG_BR_PROB_BASE; + /* If asm goto has any label refs to target's label, + add also edge from asm goto bb to target. */ + if (asm_goto_edge) + { + new_edge->probability /= 2; + new_edge->count /= 2; + jump_block->count /= 2; + jump_block->frequency /= 2; + new_edge = make_edge (new_edge->src, target, + e->flags & ~EDGE_FALLTHRU); + new_edge->probability = probability - probability / 2; + new_edge->count = count - count / 2; + } + new_bb = jump_block; } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f0b74bd6883..1c950d84b858 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,9 @@ Backported from mainline 2012-01-05 Jakub Jelinek + PR rtl-optimization/51767 + * gcc.c-torture/compile/pr51767.c: New test. + PR middle-end/51768 * c-c++-common/pr51768.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/compile/pr51767.c b/gcc/testsuite/gcc.c-torture/compile/pr51767.c new file mode 100644 index 000000000000..62a192d660d8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr51767.c @@ -0,0 +1,23 @@ +/* PR rtl-optimization/51767 */ + +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); +}