Commit 51caaefe by Eric Botcazou Committed by Eric Botcazou

re PR middle-end/24003 (17 ACATS regressions (fixed point or decimal artihmetic))

	PR middle-end/24003
	* calls.c (expand_call): If TARGET is a MEM and some part of the
	argument area has been saved, force TARGET to a register.


Co-Authored-By: Ian Lance Taylor <ian@airs.com>

From-SVN: r106860
parent 5d723e54
2005-11-13 Eric Botcazou <ebotcazou@adacore.com>
Ian Lance Taylor <ian@airs.com>
PR middle-end/24003
* calls.c (expand_call): If TARGET is a MEM and some part of the
argument area has been saved, force TARGET to a register.
2005-11-13 Razya Ladelsky <razya@il.ibm.com> 2005-11-13 Razya Ladelsky <razya@il.ibm.com>
* ipa-prop.c (ipa_callsite_compute_param ): Removed obsolete type * ipa-prop.c (ipa_callsite_compute_param ): Removed obsolete type
......
...@@ -2857,6 +2857,8 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2857,6 +2857,8 @@ expand_call (tree exp, rtx target, int ignore)
&& GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp)) && GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp))
&& GET_MODE (target) == GET_MODE (valreg)) && GET_MODE (target) == GET_MODE (valreg))
{ {
bool may_overlap = false;
/* We have to copy a return value in a CLASS_LIKELY_SPILLED hard /* We have to copy a return value in a CLASS_LIKELY_SPILLED hard
reg to a plain register. */ reg to a plain register. */
if (REG_P (valreg) if (REG_P (valreg)
...@@ -2865,19 +2867,40 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2865,19 +2867,40 @@ expand_call (tree exp, rtx target, int ignore)
&& !(REG_P (target) && !HARD_REGISTER_P (target))) && !(REG_P (target) && !HARD_REGISTER_P (target)))
valreg = copy_to_reg (valreg); valreg = copy_to_reg (valreg);
/* TARGET and VALREG cannot be equal at this point because the /* If TARGET is a MEM in the argument area, and we have
latter would not have REG_FUNCTION_VALUE_P true, while the saved part of the argument area, then we can't store
former would if it were referring to the same register. directly into TARGET as it may get overwritten when we
restore the argument save area below. Don't work too
If they refer to the same register, this move will be a no-op, hard though and simply force TARGET to a register if it
except when function inlining is being done. */ is a MEM; the optimizer is quite likely to sort it out. */
emit_move_insn (target, valreg); if (ACCUMULATE_OUTGOING_ARGS && pass && MEM_P (target))
for (i = 0; i < num_actuals; i++)
if (args[i].save_area)
{
may_overlap = true;
break;
}
/* If we are setting a MEM, this code must be executed. Since it is if (may_overlap)
emitted after the call insn, sibcall optimization cannot be target = copy_to_reg (valreg);
performed in that case. */ else
if (MEM_P (target)) {
sibcall_failure = 1; /* TARGET and VALREG cannot be equal at this point
because the latter would not have
REG_FUNCTION_VALUE_P true, while the former would if
it were referring to the same register.
If they refer to the same register, this move will be
a no-op, except when function inlining is being
done. */
emit_move_insn (target, valreg);
/* If we are setting a MEM, this code must be executed.
Since it is emitted after the call insn, sibcall
optimization cannot be performed in that case. */
if (MEM_P (target))
sibcall_failure = 1;
}
} }
else if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode) else if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
{ {
......
2005-11-13 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/nested-calls-1.c: New test.
2005-11-13 Francois-Xavier Coudert <coudert@clipper.ens.fr> 2005-11-13 Francois-Xavier Coudert <coudert@clipper.ens.fr>
* gfortran.dg/complex_intrinsic_1.f90: New test. * gfortran.dg/complex_intrinsic_1.f90: New test.
/* PR middle-end/24003 */
/* Contributed by Eric Botcazou <ebotcazou@adacore.com> */
/* { dg-do run } */
/* { dg-options "-std=c99 -O -fno-inline" } */
/* { dg-options "-std=c99 -O -fno-inline -mtune=i686" { target { i?86-*-* && ilp32 } } } */
#include <limits.h>
typedef unsigned long uns32_t;
typedef unsigned long long uns64_t;
extern void abort(void);
uns32_t lo (uns64_t p)
{
return (uns32_t)p;
}
uns64_t concat (uns32_t p1, uns32_t p2)
{
#if LLONG_MAX > 2147483647L
return ((uns64_t)p1 << 32) | p2;
#else
return 0;
#endif
}
uns64_t lshift32 (uns64_t p1, uns32_t p2)
{
return concat (lo (p1), p2);
}
int main(void)
{
#if LLONG_MAX > 2147483647L
if (lshift32 (0xFFFFFFFF12345678ULL, 0x90ABCDEFUL) != 0x1234567890ABCDEFULL)
abort ();
#endif
return 0;
}
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