> Hi Ramana,
> 
> Thanks for the review. I have opened a gcc bug-report for this. I tested
> the attached patch for  arm-none-linux-gnueabihf and
> arm-none-linux-gnueabi with no new regressions. Is this OK?
> 
> 
> Thanks,
> Kugan
> 
> gcc/ChangeLog:
> 
> 2015-11-18  Kugan Vivekanandarajah  <kug...@linaro.org>
> 
>       PR target/68390
>       * config/arm/arm.c (arm_function_ok_for_sibcall): Get function type
>       for indirect function call.
> 
> gcc/testsuite/ChangeLog:
> 
> 2015-11-18  Kugan Vivekanandarajah  <kug...@linaro.org>
> 
>       PR target/68390
>       * gcc.target/arm/PR68390.c: New test.
> 
> 
Hi Ramana,

With further testing on bare-metal, I found that for the following decl
has to be null for indirect functions.

  if (TARGET_AAPCS_BASED
      && arm_abi == ARM_ABI_AAPCS
      && decl
      && DECL_WEAK (decl))
    return false;

Here is the updated patch and ChangeLog. Sorry for the noise.

Thanks,
Kugan


gcc/ChangeLog:

2015-11-18  Kugan Vivekanandarajah  <kug...@linaro.org>

        PR target/68390
        * config/arm/arm.c (arm_function_ok_for_sibcall): Get function type
        for indirect function call.

gcc/testsuite/ChangeLog:

2015-11-18  Kugan Vivekanandarajah  <kug...@linaro.org>

        PR target/68390
        * gcc.target/arm/PR68390.c: New test.



diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a379121..0dae7da 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6680,8 +6680,13 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
         a VFP register but then need to transfer it to a core
         register.  */
       rtx a, b;
+      tree fn_decl = decl;
 
-      a = arm_function_value (TREE_TYPE (exp), decl, false);
+      /* If it is an indirect function pointer, get the function type.  */
+      if (!decl)
+       fn_decl = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
+
+      a = arm_function_value (TREE_TYPE (exp), fn_decl, false);
       b = arm_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
                              cfun->decl, false);
       if (!rtx_equal_p (a, b))
diff --git a/gcc/testsuite/gcc.target/arm/PR68390.c 
b/gcc/testsuite/gcc.target/arm/PR68390.c
index e69de29..86f07fe 100644
--- a/gcc/testsuite/gcc.target/arm/PR68390.c
+++ b/gcc/testsuite/gcc.target/arm/PR68390.c
@@ -0,0 +1,27 @@
+/* { dg-do run }  */
+/* { dg-options "-O2" } */
+
+__attribute__ ((noinline))
+double direct(int x, ...)
+{
+  return x*x;
+}
+
+__attribute__ ((noinline))
+double broken(double (*indirect)(int x, ...), int v)
+{
+  return indirect(v);
+}
+
+int main ()
+{
+  double d1, d2;
+  int i = 2;
+  d1 = broken (direct, i);
+  if (d1 != i*i)
+    {
+      __builtin_abort ();
+    }
+  return 0;
+}
+

Reply via email to