Hi,

As reported in PR78255 there is currently an issue with indirect sibling
calls in ARM when the address of the sibling call is loaded into 'r3'
and that same register is chosen to align the stack.  See the report for
further information.

As I mentioned in the bugzilla ticket I am not sure this is the right
approach, though it works... Bootstrapped on ARM and no regressions.

Do you think this is OK? Another solution would be to make sure that
'arm_get_frame_offsets' recalculates offsets after we know that the call
is going to be indirect, i.e. after we know the address is going to be
loaded into a register, but I do not know what a sane way would be to
ensure this.

Regards,
Andre

gcc/ChangeLog
2016-11-10  Andre Vieira  <andre.simoesdiasvie...@arm.com>

        * config/arm/arm.md (sibcall_internal): Add 'use' to pattern.
        (sibcall_value_internal): Likewise.
        (sibcall_insn): Likewise.
        (sibcall_value_insn): Likewise.


gcc/testsuite/ChangeLog
2016-11-10  Andre Vieira  <andre.simoesdiasvie...@arm.com>

        * gcc.target/arm/pr78255.c: New.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 
8393f65bcf4c9c3e61b91e5adcd5f59ff7c6ec3f..ab28b15f3e4ebbaca2b8ec0523493b54cce8c306
 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8192,7 +8192,8 @@
   [(parallel [(call (match_operand 0 "memory_operand" "")
                    (match_operand 1 "general_operand" ""))
              (return)
-             (use (match_operand 2 "" ""))])])
+             (use (match_operand 2 "" ""))
+             (use (match_dup 0))])])
 
 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
 (define_expand "sibcall"
@@ -8225,7 +8226,8 @@
                   (call (match_operand 1 "memory_operand" "")
                         (match_operand 2 "general_operand" "")))
              (return)
-             (use (match_operand 3 "" ""))])])
+             (use (match_operand 3 "" ""))
+             (use (match_dup 1))])])
 
 (define_expand "sibcall_value"
   [(parallel [(set (match_operand 0 "" "")
@@ -8258,7 +8260,8 @@
  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
        (match_operand 1 "" ""))
   (return)
-  (use (match_operand 2 "" ""))]
+  (use (match_operand 2 "" ""))
+  (use (match_operand 3 "" ""))]
   "TARGET_32BIT && SIBLING_CALL_P (insn)"
   "*
   if (which_alternative == 1)
@@ -8279,7 +8282,8 @@
        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
             (match_operand 2 "" "")))
   (return)
-  (use (match_operand 3 "" ""))]
+  (use (match_operand 3 "" ""))
+  (use (match_operand 4 "" ""))]
   "TARGET_32BIT && SIBLING_CALL_P (insn)"
   "*
   if (which_alternative == 1)
diff --git a/gcc/testsuite/gcc.target/arm/pr78255.c 
b/gcc/testsuite/gcc.target/arm/pr78255.c
new file mode 100644
index 
0000000000000000000000000000000000000000..4901acea51466c0bac92d9cb90e52b00b450d88a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr78255.c
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+/* { dg-options "-O2" }  */
+
+#include <string.h>
+
+struct table_s
+    {
+    void (*fun0)
+        ( void );
+    void (*fun1)
+        ( void );
+    void (*fun2)
+        ( void );
+    void (*fun3)
+        ( void );
+    void (*fun4)
+        ( void );
+    void (*fun5)
+        ( void );
+    void (*fun6)
+        ( void );
+    void (*fun7)
+        ( void );
+    } table;
+
+void callback0(){__asm("mov r0, r0 \n\t");}
+void callback1(){__asm("mov r0, r0 \n\t");}
+void callback2(){__asm("mov r0, r0 \n\t");}
+void callback3(){__asm("mov r0, r0 \n\t");}
+void callback4(){__asm("mov r0, r0 \n\t");}
+
+void test (void) {
+    memset(&table, 0, sizeof table);
+
+    asm volatile ("" : : : "r3");
+
+    table.fun0 = callback0;
+    table.fun1 = callback1;
+    table.fun2 = callback2;
+    table.fun3 = callback3;
+    table.fun4 = callback4;
+    table.fun0();
+}
+
+void foo (void)
+{
+  __builtin_abort ();
+}
+
+int main (void)
+{
+  unsigned long p = (unsigned long) &foo;
+  asm volatile ("mov r3, %0" : : "r" (p));
+  test ();
+
+  return 0;
+}

Reply via email to