re PR middle-end/17075 (miscompilation with tail calls in cfgexpand)

PR 17075
        * cfgexpand.c (expand_gimple_tailcall): Detect when we can both
        create new blocks and fall through.
        (expand_gimple_basic_block): Update to match.

From-SVN: r86389
This commit is contained in:
Richard Henderson 2004-08-22 17:02:55 -07:00 committed by Richard Henderson
parent 0b540f12b0
commit cea4955090
2 changed files with 38 additions and 9 deletions

View File

@ -1,3 +1,10 @@
2004-08-22 Richard Henderson <rth@redhat.com>
PR 17075
* cfgexpand.c (expand_gimple_tailcall): Detect when we can both
create new blocks and fall through.
(expand_gimple_basic_block): Update to match.
2004-08-22 Ulrich Weigand <uweigand@de.ibm.com>
* reload.c (find_reloads_address): Make return value tri-state.

View File

@ -129,10 +129,15 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
/* A subroutine of expand_gimple_basic_block. Expand one CALL_EXPR
that has CALL_EXPR_TAILCALL set. Returns non-null if we actually
generated a tail call (something that might be denied by the ABI
rules governing the call; see calls.c). */
rules governing the call; see calls.c).
Sets CAN_FALLTHRU if we generated a *conditional* tail call, and
can still reach the rest of BB. The case here is __builtin_sqrt,
where the NaN result goes through the external function (with a
tailcall) and the normal result happens via a sqrt instruction. */
static basic_block
expand_gimple_tailcall (basic_block bb, tree stmt)
expand_gimple_tailcall (basic_block bb, tree stmt, bool *can_fallthru)
{
rtx last = get_last_insn ();
edge e;
@ -145,6 +150,7 @@ expand_gimple_tailcall (basic_block bb, tree stmt)
if (CALL_P (last) && SIBLING_CALL_P (last))
goto found;
*can_fallthru = true;
return NULL;
found:
@ -191,12 +197,17 @@ expand_gimple_tailcall (basic_block bb, tree stmt)
last = NEXT_INSN (last);
if (!BARRIER_P (last))
abort ();
*can_fallthru = false;
while (NEXT_INSN (last))
{
/* For instance an sqrt builtin expander expands if with
sibcall in the then and label for `else`. */
if (LABEL_P (NEXT_INSN (last)))
break;
{
*can_fallthru = true;
break;
}
delete_insn (NEXT_INSN (last));
}
@ -277,7 +288,7 @@ expand_gimple_basic_block (basic_block bb, FILE * dump_file)
for (; !bsi_end_p (bsi); bsi_next (&bsi))
{
tree stmt = bsi_stmt (bsi);
basic_block new_bb = NULL;
basic_block new_bb;
if (!stmt)
continue;
@ -285,18 +296,29 @@ expand_gimple_basic_block (basic_block bb, FILE * dump_file)
/* Expand this statement, then evaluate the resulting RTL and
fixup the CFG accordingly. */
if (TREE_CODE (stmt) == COND_EXPR)
new_bb = expand_gimple_cond_expr (bb, stmt);
{
new_bb = expand_gimple_cond_expr (bb, stmt);
if (new_bb)
return new_bb;
}
else
{
tree call = get_call_expr_in (stmt);
if (call && CALL_EXPR_TAILCALL (call))
new_bb = expand_gimple_tailcall (bb, stmt);
{
bool can_fallthru;
new_bb = expand_gimple_tailcall (bb, stmt, &can_fallthru);
if (new_bb)
{
if (can_fallthru)
bb = new_bb;
else
return new_bb;
}
}
else
expand_expr_stmt (stmt);
}
if (new_bb)
return new_bb;
}
do_pending_stack_adjust ();