re PR target/77439 (wrong code for sibcall with longcall, APCS frame and VFP)
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 24 Jan 2017 17:15:02 +0000 (17:15 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 24 Jan 2017 17:15:02 +0000 (17:15 +0000)
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

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/vfp-longcall-apcs.c [new file with mode: 0644]

index 22eeef5b2a43b88baabc307c3a792e50a1d6deb1..c2962bb248f5c31b3a5ec1f6b0af295d1103e538 100644 (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.
index 934f5d141f720d1c6c0a86c12eed1c62e8cbb983..944445fc86ae848b36c8a90db4b3760476c8b467 100644 (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).  */
index 02118907eccf4c44dd4f612fb4838ac1f0cdbcd2..e70200bac577e34e9b8323e601c379520cc210bf 100644 (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.
diff --git a/gcc/testsuite/gcc.target/arm/vfp-longcall-apcs.c b/gcc/testsuite/gcc.target/arm/vfp-longcall-apcs.c
new file mode 100644 (file)
index 0000000..fa22b4d
--- /dev/null
@@ -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;
+}