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:
parent
5d723e5434
commit
51caaefe17
4 changed files with 87 additions and 11 deletions
|
@ -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
|
||||
|
|
45
gcc/calls.c
45
gcc/calls.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
42
gcc/testsuite/gcc.dg/nested-calls-1.c
Normal file
42
gcc/testsuite/gcc.dg/nested-calls-1.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue