From: Richard Ball <richard.b...@arm.com>

This patch adds a new testcase and docs for indirect_return
attribute.

gcc/ChangeLog:

        * doc/extend.texi: Add AArch64 docs for indirect_return
        attribute.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/indirect_return-1.c: New test.
        * gcc.target/aarch64/indirect_return-2.c: New test.
        * gcc.target/aarch64/indirect_return-3.c: New test.

Co-authored-by: Yury Khrustalev <yury.khrusta...@arm.com>
---
 gcc/doc/extend.texi                           | 10 ++++
 .../gcc.target/aarch64/indirect_return-1.c    | 53 +++++++++++++++++++
 .../gcc.target/aarch64/indirect_return-2.c    | 49 +++++++++++++++++
 .../gcc.target/aarch64/indirect_return-3.c    |  9 ++++
 4 files changed, 121 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/indirect_return-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/indirect_return-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/indirect_return-3.c

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c566474074d..59644606261 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4761,6 +4761,16 @@ Enable or disable calls to out-of-line helpers to 
implement atomic operations.
 This corresponds to the behavior of the command-line options
 @option{-moutline-atomics} and @option{-mno-outline-atomics}.
 
+@cindex @code{indirect_return} function attribute, AArch64
+@item indirect_return
+The @code{indirect_return} attribute can be applied to a function type
+to indicate that the function may return via an indirect branch instead
+of via a normal return instruction.  For example, this can be true of
+functions that implement manual context switching between user space
+threads, such as the POSIX @code{swapcontext} function.  This attribute
+adds a @code{BTI J} instruction when BTI is enabled e.g. via
+@option{-mbranch-protection}.
+
 @end table
 
 The above target attributes can be specified as follows:
diff --git a/gcc/testsuite/gcc.target/aarch64/indirect_return-1.c 
b/gcc/testsuite/gcc.target/aarch64/indirect_return-1.c
new file mode 100644
index 00000000000..9ab133ffb7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/indirect_return-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mbranch-protection=bti" } */
+
+int
+__attribute((indirect_return,weak))
+foo (int a)
+{
+  return a;
+}
+
+/*
+**func1:
+**     hint    34 // bti c
+**     ...
+**     bl      foo
+**     hint    36 // bti j
+**     ...
+**     ret
+*/
+int
+func1 (int a, int b)
+{
+  return foo (a + b);
+}
+
+/*
+**func2:
+**     hint    34 // bti c
+**     ...
+**     b       foo
+*/
+int __attribute((indirect_return,weak))
+func2 (int a, int b)
+{
+  return foo (a - b);
+}
+
+/*
+**func3:
+**     hint    34 // bti c
+**     ...
+**     bl      func2
+**     hint    36 // bti j
+**     ...
+**     ret
+*/
+int
+func3 (int x, int y)
+{
+  return func2 (x, y);
+}
+
+/* { dg-final { check-function-bodies "**" "" "" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/indirect_return-2.c 
b/gcc/testsuite/gcc.target/aarch64/indirect_return-2.c
new file mode 100644
index 00000000000..4759ed77776
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/indirect_return-2.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mbranch-protection=none" } */
+
+int
+__attribute((indirect_return,weak))
+foo (int a)
+{
+  return a;
+}
+
+/*
+**func1:
+**     ...
+**     bl      foo
+**     ...
+**     ret
+*/
+int
+func1 (int a, int b)
+{
+  return foo (a + b);
+}
+
+/*
+**func2:
+**     ...
+**     b       foo
+*/
+int __attribute((indirect_return,weak))
+func2 (int a, int b)
+{
+  return foo (a - b);
+}
+
+/*
+**func3:
+**     ...
+**     bl      func2
+**     ...
+**     ret
+*/
+int
+func3 (int x, int y)
+{
+  return func2 (x, y);
+}
+
+/* { dg-final { check-function-bodies "**" "" "" } } */
+/* { dg-final { scan-assembler-not {\thint\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/indirect_return-3.c 
b/gcc/testsuite/gcc.target/aarch64/indirect_return-3.c
new file mode 100644
index 00000000000..382138c5e25
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/indirect_return-3.c
@@ -0,0 +1,9 @@
+/* Check that mismatching attribute on function pointers is an error.  */
+/* { dg-do compile } */
+
+void f(void);
+void (*f_ptr)(void) __attribute__((indirect_return)) = f; /* { dg-error 
{incompatible pointer type} } */
+
+void g(void) __attribute__((indirect_return));
+void (*g_ptr1)(void) = g; /* { dg-error {incompatible pointer type} } */
+void (*g_ptr2)(void) __attribute__((indirect_return)) = g;
-- 
2.39.5

Reply via email to