Commit cea49550 by Richard Henderson Committed by Richard Henderson

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
parent 0b540f12
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> 2004-08-22 Ulrich Weigand <uweigand@de.ibm.com>
* reload.c (find_reloads_address): Make return value tri-state. * reload.c (find_reloads_address): Make return value tri-state.
......
...@@ -129,10 +129,15 @@ expand_gimple_cond_expr (basic_block bb, tree stmt) ...@@ -129,10 +129,15 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
/* A subroutine of expand_gimple_basic_block. Expand one CALL_EXPR /* A subroutine of expand_gimple_basic_block. Expand one CALL_EXPR
that has CALL_EXPR_TAILCALL set. Returns non-null if we actually that has CALL_EXPR_TAILCALL set. Returns non-null if we actually
generated a tail call (something that might be denied by the ABI 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 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 (); rtx last = get_last_insn ();
edge e; edge e;
...@@ -145,6 +150,7 @@ expand_gimple_tailcall (basic_block bb, tree stmt) ...@@ -145,6 +150,7 @@ expand_gimple_tailcall (basic_block bb, tree stmt)
if (CALL_P (last) && SIBLING_CALL_P (last)) if (CALL_P (last) && SIBLING_CALL_P (last))
goto found; goto found;
*can_fallthru = true;
return NULL; return NULL;
found: found:
...@@ -191,12 +197,17 @@ expand_gimple_tailcall (basic_block bb, tree stmt) ...@@ -191,12 +197,17 @@ expand_gimple_tailcall (basic_block bb, tree stmt)
last = NEXT_INSN (last); last = NEXT_INSN (last);
if (!BARRIER_P (last)) if (!BARRIER_P (last))
abort (); abort ();
*can_fallthru = false;
while (NEXT_INSN (last)) while (NEXT_INSN (last))
{ {
/* For instance an sqrt builtin expander expands if with /* For instance an sqrt builtin expander expands if with
sibcall in the then and label for `else`. */ sibcall in the then and label for `else`. */
if (LABEL_P (NEXT_INSN (last))) if (LABEL_P (NEXT_INSN (last)))
{
*can_fallthru = true;
break; break;
}
delete_insn (NEXT_INSN (last)); delete_insn (NEXT_INSN (last));
} }
...@@ -277,7 +288,7 @@ expand_gimple_basic_block (basic_block bb, FILE * dump_file) ...@@ -277,7 +288,7 @@ expand_gimple_basic_block (basic_block bb, FILE * dump_file)
for (; !bsi_end_p (bsi); bsi_next (&bsi)) for (; !bsi_end_p (bsi); bsi_next (&bsi))
{ {
tree stmt = bsi_stmt (bsi); tree stmt = bsi_stmt (bsi);
basic_block new_bb = NULL; basic_block new_bb;
if (!stmt) if (!stmt)
continue; continue;
...@@ -285,18 +296,29 @@ expand_gimple_basic_block (basic_block bb, FILE * dump_file) ...@@ -285,18 +296,29 @@ expand_gimple_basic_block (basic_block bb, FILE * dump_file)
/* Expand this statement, then evaluate the resulting RTL and /* Expand this statement, then evaluate the resulting RTL and
fixup the CFG accordingly. */ fixup the CFG accordingly. */
if (TREE_CODE (stmt) == COND_EXPR) 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 else
{ {
tree call = get_call_expr_in (stmt); tree call = get_call_expr_in (stmt);
if (call && CALL_EXPR_TAILCALL (call)) 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 else
expand_expr_stmt (stmt); expand_expr_stmt (stmt);
} }
if (new_bb)
return new_bb;
} }
do_pending_stack_adjust (); do_pending_stack_adjust ();
......
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