re PR rtl-optimization/51767 (ICE with degenerated asm goto)

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: r182922
This commit is contained in:
Jakub Jelinek 2012-01-05 21:20:57 +01:00 committed by Jakub Jelinek
parent 36363ebb88
commit a3e6a37b65
4 changed files with 71 additions and 6 deletions

View File

@ -1,5 +1,9 @@
2012-01-05 Jakub Jelinek <jakub@redhat.com>
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.

View File

@ -1,7 +1,7 @@
/* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011, 2012 Free Software Foundation, Inc.
This file is part of GCC.
@ -1129,6 +1129,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
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
@ -1208,8 +1209,28 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
}
}
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
@ -1220,7 +1241,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
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;
@ -1236,13 +1257,27 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
/* 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

View File

@ -1,5 +1,8 @@
2012-01-05 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/51767
* gcc.c-torture/compile/pr51767.c: New test.
PR middle-end/51768
* c-c++-common/pr51768.c: New test.

View File

@ -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);
}