Commit a3e6a37b by Jakub Jelinek Committed by Jakub Jelinek

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
parent 36363ebb
2012-01-05 Jakub Jelinek <jakub@redhat.com> 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 PR middle-end/51768
* stmt.c (check_unique_operand_names): Don't ICE during error * stmt.c (check_unique_operand_names): Don't ICE during error
reporting if i is from labels chain. reporting if i is from labels chain.
/* Control flow graph manipulation code for GNU compiler. /* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
Free Software Foundation, Inc. 2011, 2012 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -1129,6 +1129,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) ...@@ -1129,6 +1129,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
rtx note; rtx note;
edge new_edge; edge new_edge;
int abnormal_edge_flags = 0; int abnormal_edge_flags = 0;
bool asm_goto_edge = false;
int loc; int loc;
/* In the case the last instruction is conditional jump to the next /* 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) ...@@ -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. */ /* Create the new structures. */
/* If the old block ended with a tablejump, skip its table /* 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) ...@@ -1220,7 +1241,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
note = NEXT_INSN (note); note = NEXT_INSN (note);
jump_block = create_basic_block (note, NULL, e->src); 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->frequency = EDGE_FREQUENCY (e);
jump_block->loop_depth = target->loop_depth; jump_block->loop_depth = target->loop_depth;
...@@ -1236,13 +1257,27 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) ...@@ -1236,13 +1257,27 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
/* Wire edge in. */ /* Wire edge in. */
new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU); new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
new_edge->probability = e->probability; new_edge->probability = probability;
new_edge->count = e->count; new_edge->count = count;
/* Redirect old edge. */ /* Redirect old edge. */
redirect_edge_pred (e, jump_block); redirect_edge_pred (e, jump_block);
e->probability = REG_BR_PROB_BASE; 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; new_bb = jump_block;
} }
else else
......
2012-01-05 Jakub Jelinek <jakub@redhat.com> 2012-01-05 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/51767
* gcc.c-torture/compile/pr51767.c: New test.
PR middle-end/51768 PR middle-end/51768
* c-c++-common/pr51768.c: New test. * c-c++-common/pr51768.c: New test.
......
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment