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
This commit is contained in:
Eric Botcazou 2005-11-13 09:55:11 +00:00 committed by Eric Botcazou
parent 5d723e5434
commit 51caaefe17
4 changed files with 87 additions and 11 deletions

View file

@ -1,3 +1,10 @@
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>
* ipa-prop.c (ipa_callsite_compute_param ): Removed obsolete type

View file

@ -2857,6 +2857,8 @@ expand_call (tree exp, rtx target, int ignore)
&& GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp))
&& GET_MODE (target) == GET_MODE (valreg))
{
bool may_overlap = false;
/* We have to copy a return value in a CLASS_LIKELY_SPILLED hard
reg to a plain register. */
if (REG_P (valreg)
@ -2865,19 +2867,40 @@ expand_call (tree exp, rtx target, int ignore)
&& !(REG_P (target) && !HARD_REGISTER_P (target)))
valreg = copy_to_reg (valreg);
/* 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 TARGET is a MEM in the argument area, and we have
saved part of the argument area, then we can't store
directly into TARGET as it may get overwritten when we
restore the argument save area below. Don't work too
hard though and simply force TARGET to a register if it
is a MEM; the optimizer is quite likely to sort it out. */
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 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 (may_overlap)
target = copy_to_reg (valreg);
else
{
/* 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 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;
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)
{

View file

@ -1,3 +1,7 @@
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>
* gfortran.dg/complex_intrinsic_1.f90: New test.

View file

@ -0,0 +1,42 @@
/* 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;
}