re PR target/77439 (wrong code for sibcall with longcall, APCS frame and VFP)

PR target/77439
	* config/arm/arm.c (arm_function_ok_for_sibcall): Add back restriction
	for long calls with APCS frame and VFP.

From-SVN: r244879
This commit is contained in:
Eric Botcazou 2017-01-24 17:15:02 +00:00 committed by Eric Botcazou
parent c2e8432763
commit b20ba138ef
4 changed files with 50 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2017-01-24 Eric Botcazou <ebotcazou@adacore.com>
PR target/77439
* config/arm/arm.c (arm_function_ok_for_sibcall): Add back restriction
for long calls with APCS frame and VFP.
2017-01-24 David Malcolm <dmalcolm@redhat.com>
* cfg.c (original_copy_tables_initialized_p): New function.

View File

@ -7105,6 +7105,14 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
if (TARGET_VXWORKS_RTP && flag_pic && decl && !targetm.binds_local_p (decl))
return false;
/* ??? Cannot tail-call to long calls with APCS frame and VFP, because IP
may be used both as target of the call and base register for restoring
the VFP registers */
if (TARGET_APCS_FRAME && TARGET_ARM
&& TARGET_HARD_FLOAT
&& decl && arm_is_long_call_p (decl))
return false;
/* If we are interworking and the function is not declared static
then we can't tail-call it unless we know that it exists in this
compilation unit (since it might be a Thumb routine). */

View File

@ -1,3 +1,7 @@
2017-01-24 Eric Botcazou <ebotcazou@adacore.com>
* gcc.target/arm/vfp-longcall-apcs.c: New test.
2017-01-24 David Malcolm <dmalcolm@redhat.com>
* gcc.dg/rtl/aarch64/asr_div1.c: New test case.

View File

@ -0,0 +1,32 @@
/* { dg-do run } */
/* { dg-options "-mapcs-frame -O -foptimize-sibling-calls -ffunction-sections" } */
extern void abort (void);
static __attribute__((noclone, noinline, long_call))
int foo (int a, int b, int c, int d, double i)
{
return a;
}
static __attribute__((noclone, noinline))
double baz (double i)
{
return i;
}
static __attribute__((noclone, noinline))
int bar (int a, int b, int c, int d, double i, double j)
{
double l = baz (i) * j;
return foo (a, b, c, d, l);
}
int
main (void)
{
if (bar (0, 0, 0, 0, 0.0, 0.0) != 0)
abort ();
return 0;
}