From: Richard Ball <[email protected]>
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.
Co-authored-by: Yury Khrustalev <[email protected]>
---
gcc/doc/extend.texi | 10 ++++
.../gcc.target/aarch64/indirect_return-1.c | 53 +++++++++++++++++++
.../gcc.target/aarch64/indirect_return-2.c | 48 +++++++++++++++++
3 files changed, 111 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
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 5902e76f043..d3ce46e42e0 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4760,6 +4760,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 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..58da4a5c082
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/indirect_return-2.c
@@ -0,0 +1,48 @@
+/* { 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 "**" "" "" } } */
--
2.39.5