Commit 8634629b by Roger Sayle Committed by Roger Sayle

builtins.c (expand_builtin_mathfn): Rearrange so that we only return 0 for invalid argument types.


	* builtins.c (expand_builtin_mathfn):  Rearrange so that we only
	return 0 for invalid argument types.  Instead drop through to a
	call of expand_call at the bottom of function.  If op is SQRT,
	try attaching a SQRT rtx as the REQ_EQUAL note of the libcall.

From-SVN: r70792
parent 0961802f
2003-08-25 Roger Sayle <roger@eyesopen.com>
* builtins.c (expand_builtin_mathfn): Rearrange so that we only
return 0 for invalid argument types. Instead drop through to a
call of expand_call at the bottom of function. If op is SQRT,
try attaching a SQRT rtx as the REQ_EQUAL note of the libcall.
2003-08-25 Richard Henderson <rth@redhat.com> 2003-08-25 Richard Henderson <rth@redhat.com>
* config/ia64/ia64.c (ia64_expand_tls_address): Properly truncate * config/ia64/ia64.c (ia64_expand_tls_address): Properly truncate
......
...@@ -1565,7 +1565,7 @@ static rtx ...@@ -1565,7 +1565,7 @@ static rtx
expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
{ {
optab builtin_optab; optab builtin_optab;
rtx op0, insns; rtx op0, insns, before_call;
tree fndecl = get_callee_fndecl (exp); tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1); tree arglist = TREE_OPERAND (exp, 1);
enum machine_mode mode; enum machine_mode mode;
...@@ -1636,14 +1636,14 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) ...@@ -1636,14 +1636,14 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
/* Make a suitable register to place result in. */ /* Make a suitable register to place result in. */
mode = TYPE_MODE (TREE_TYPE (exp)); mode = TYPE_MODE (TREE_TYPE (exp));
/* Before working hard, check whether the instruction is available. */
if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
return 0;
target = gen_reg_rtx (mode);
if (! flag_errno_math || ! HONOR_NANS (mode)) if (! flag_errno_math || ! HONOR_NANS (mode))
errno_set = false; errno_set = false;
/* Before working hard, check whether the instruction is available. */
if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
target = gen_reg_rtx (mode);
/* Wrap the computation of the argument in a SAVE_EXPR, as we may /* Wrap the computation of the argument in a SAVE_EXPR, as we may
need to expand the argument again. This way, we will not perform need to expand the argument again. This way, we will not perform
side-effects more the once. */ side-effects more the once. */
...@@ -1663,15 +1663,8 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) ...@@ -1663,15 +1663,8 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
Set TARGET to wherever the result comes back. */ Set TARGET to wherever the result comes back. */
target = expand_unop (mode, builtin_optab, op0, target, 0); target = expand_unop (mode, builtin_optab, op0, target, 0);
/* If we were unable to expand via the builtin, stop the sequence if (target != 0)
(without outputting the insns) and call to the library function
with the stabilized argument list. */
if (target == 0)
{ {
end_sequence ();
return expand_call (exp, target, target == const0_rtx);
}
if (errno_set) if (errno_set)
expand_errno_check (exp, target); expand_errno_check (exp, target);
...@@ -1679,6 +1672,57 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) ...@@ -1679,6 +1672,57 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
insns = get_insns (); insns = get_insns ();
end_sequence (); end_sequence ();
emit_insn (insns); emit_insn (insns);
return target;
}
/* If we were unable to expand via the builtin, stop the sequence
(without outputting the insns) and call to the library function
with the stabilized argument list. */
end_sequence ();
}
before_call = get_last_insn ();
target = expand_call (exp, target, target == const0_rtx);
/* If this is a sqrt operation and we don't care about errno, try to
attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
This allows the semantics of the libcall to be visible to the RTL
optimizers. */
if (builtin_optab == sqrt_optab && !errno_set)
{
/* Search backwards through the insns emitted by expand_call looking
for the instruction with the REG_RETVAL note. */
rtx last = get_last_insn ();
while (last != before_call)
{
if (find_reg_note (last, REG_RETVAL, NULL))
{
rtx note = find_reg_note (last, REG_EQUAL, NULL);
/* Check that the REQ_EQUAL note is an EXPR_LIST with
two elements, i.e. symbol_ref(sqrt) and the operand. */
if (note
&& GET_CODE (note) == EXPR_LIST
&& GET_CODE (XEXP (note, 0)) == EXPR_LIST
&& XEXP (XEXP (note, 0), 1) != NULL_RTX
&& XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
{
rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
/* Check operand is a register with expected mode. */
if (operand
&& GET_CODE (operand) == REG
&& GET_MODE (operand) == mode)
{
/* Replace the REG_EQUAL note with a SQRT rtx. */
rtx equiv = gen_rtx_SQRT (mode, operand);
set_unique_reg_note (last, REG_EQUAL, equiv);
}
}
break;
}
last = PREV_INSN (last);
}
}
return target; return target;
} }
......
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