914 lines
28 KiB
Diff
914 lines
28 KiB
Diff
|
|
From c4578108ab766178fe7ebd51421c1ac9f317b675 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Richard Sandiford <richard.sandiford@arm.com>
|
||
|
|
Date: Tue, 5 Dec 2023 10:11:30 +0000
|
||
|
|
Subject: [PATCH 115/157] [Backport][SME] aarch64: Enforce inlining
|
||
|
|
restrictions for SME
|
||
|
|
|
||
|
|
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0e9aa05df6c643610a3821af52eda642a525a886
|
||
|
|
|
||
|
|
A function that has local ZA state cannot be inlined into its caller,
|
||
|
|
since we only support managing ZA switches at function scope.
|
||
|
|
|
||
|
|
A function whose body directly clobbers ZA state cannot be inlined into
|
||
|
|
a function with ZA state.
|
||
|
|
|
||
|
|
A function whose body requires a particular PSTATE.SM setting can only
|
||
|
|
be inlined into a function body that guarantees that PSTATE.SM setting.
|
||
|
|
The callee's function type doesn't matter here: one locally-streaming
|
||
|
|
function can be inlined into another.
|
||
|
|
|
||
|
|
gcc/
|
||
|
|
* config/aarch64/aarch64.cc: Include symbol-summary.h, ipa-prop.h,
|
||
|
|
and ipa-fnsummary.h
|
||
|
|
(aarch64_function_attribute_inlinable_p): New function.
|
||
|
|
(AARCH64_IPA_SM_FIXED, AARCH64_IPA_CLOBBERS_ZA): New constants.
|
||
|
|
(aarch64_need_ipa_fn_target_info): New function.
|
||
|
|
(aarch64_update_ipa_fn_target_info): Likewise.
|
||
|
|
(aarch64_can_inline_p): Restrict the previous ISA flag checks
|
||
|
|
to non-modal features. Prevent callees that require a particular
|
||
|
|
PSTATE.SM state from being inlined into callers that can't guarantee
|
||
|
|
that state. Also prevent callees that have ZA state from being
|
||
|
|
inlined into callers that don't. Finally, prevent callees that
|
||
|
|
clobber ZA from being inlined into callers that have ZA state.
|
||
|
|
(TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P): Define.
|
||
|
|
(TARGET_NEED_IPA_FN_TARGET_INFO): Likewise.
|
||
|
|
(TARGET_UPDATE_IPA_FN_TARGET_INFO): Likewise.
|
||
|
|
|
||
|
|
gcc/testsuite/
|
||
|
|
* gcc.target/aarch64/sme/inlining_1.c: New test.
|
||
|
|
* gcc.target/aarch64/sme/inlining_2.c: Likewise.
|
||
|
|
* gcc.target/aarch64/sme/inlining_3.c: Likewise.
|
||
|
|
* gcc.target/aarch64/sme/inlining_4.c: Likewise.
|
||
|
|
* gcc.target/aarch64/sme/inlining_5.c: Likewise.
|
||
|
|
* gcc.target/aarch64/sme/inlining_6.c: Likewise.
|
||
|
|
* gcc.target/aarch64/sme/inlining_7.c: Likewise.
|
||
|
|
* gcc.target/aarch64/sme/inlining_8.c: Likewise.
|
||
|
|
---
|
||
|
|
gcc/config/aarch64/aarch64.cc | 132 +++++++++++++++++-
|
||
|
|
.../gcc.target/aarch64/sme/inlining_1.c | 47 +++++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_10.c | 57 ++++++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_11.c | 57 ++++++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_12.c | 15 ++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_13.c | 15 ++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_14.c | 15 ++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_15.c | 27 ++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_2.c | 47 +++++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_3.c | 47 +++++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_4.c | 47 +++++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_5.c | 47 +++++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_6.c | 31 ++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_7.c | 31 ++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_8.c | 31 ++++
|
||
|
|
.../gcc.target/aarch64/sme/inlining_9.c | 55 ++++++++
|
||
|
|
16 files changed, 696 insertions(+), 5 deletions(-)
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_1.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_10.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_11.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_12.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_13.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_14.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_15.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_2.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_3.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_4.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_5.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_6.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_7.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_8.c
|
||
|
|
create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/inlining_9.c
|
||
|
|
|
||
|
|
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
|
||
|
|
index effb567c2..eab94d5c2 100644
|
||
|
|
--- a/gcc/config/aarch64/aarch64.cc
|
||
|
|
+++ b/gcc/config/aarch64/aarch64.cc
|
||
|
|
@@ -85,6 +85,9 @@
|
||
|
|
#include "except.h"
|
||
|
|
#include "tree-pass.h"
|
||
|
|
#include "cfgbuild.h"
|
||
|
|
+#include "symbol-summary.h"
|
||
|
|
+#include "ipa-prop.h"
|
||
|
|
+#include "ipa-fnsummary.h"
|
||
|
|
|
||
|
|
/* This file should be included last. */
|
||
|
|
#include "target-def.h"
|
||
|
|
@@ -21351,6 +21354,17 @@ aarch64_option_valid_attribute_p (tree fndecl, tree, tree args, int)
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
+/* Implement TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P. Use an opt-out
|
||
|
|
+ rather than an opt-in list. */
|
||
|
|
+
|
||
|
|
+static bool
|
||
|
|
+aarch64_function_attribute_inlinable_p (const_tree fndecl)
|
||
|
|
+{
|
||
|
|
+ /* A function that has local ZA state cannot be inlined into its caller,
|
||
|
|
+ since we only support managing ZA switches at function scope. */
|
||
|
|
+ return !aarch64_fndecl_has_new_state (fndecl, "za");
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/* Helper for aarch64_can_inline_p. In the case where CALLER and CALLEE are
|
||
|
|
tri-bool options (yes, no, don't care) and the default value is
|
||
|
|
DEF, determine whether to reject inlining. */
|
||
|
|
@@ -21372,6 +21386,60 @@ aarch64_tribools_ok_for_inlining_p (int caller, int callee,
|
||
|
|
return (callee == caller || callee == def);
|
||
|
|
}
|
||
|
|
|
||
|
|
+/* Bit allocations for ipa_fn_summary::target_info. */
|
||
|
|
+
|
||
|
|
+/* Set if the function contains a stmt that relies on the function's
|
||
|
|
+ choice of PSTATE.SM setting (0 for non-streaming, 1 for streaming).
|
||
|
|
+ Not meaningful for streaming-compatible functions. */
|
||
|
|
+constexpr auto AARCH64_IPA_SM_FIXED = 1U << 0;
|
||
|
|
+
|
||
|
|
+/* Set if the function clobbers ZA. Not meaningful for functions that
|
||
|
|
+ have ZA state. */
|
||
|
|
+constexpr auto AARCH64_IPA_CLOBBERS_ZA = 1U << 1;
|
||
|
|
+
|
||
|
|
+/* Implement TARGET_NEED_IPA_FN_TARGET_INFO. */
|
||
|
|
+
|
||
|
|
+static bool
|
||
|
|
+aarch64_need_ipa_fn_target_info (const_tree, unsigned int &)
|
||
|
|
+{
|
||
|
|
+ /* We could in principle skip this for streaming-compatible functions
|
||
|
|
+ that have ZA state, but that's a rare combination. */
|
||
|
|
+ return true;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* Implement TARGET_UPDATE_IPA_FN_TARGET_INFO. */
|
||
|
|
+
|
||
|
|
+static bool
|
||
|
|
+aarch64_update_ipa_fn_target_info (unsigned int &info, const gimple *stmt)
|
||
|
|
+{
|
||
|
|
+ if (auto *ga = dyn_cast<const gasm *> (stmt))
|
||
|
|
+ {
|
||
|
|
+ /* We don't know what the asm does, so conservatively assume that
|
||
|
|
+ it requires the function's current SM mode. */
|
||
|
|
+ info |= AARCH64_IPA_SM_FIXED;
|
||
|
|
+ for (unsigned int i = 0; i < gimple_asm_nclobbers (ga); ++i)
|
||
|
|
+ {
|
||
|
|
+ tree op = gimple_asm_clobber_op (ga, i);
|
||
|
|
+ const char *clobber = TREE_STRING_POINTER (TREE_VALUE (op));
|
||
|
|
+ if (strcmp (clobber, "za") == 0)
|
||
|
|
+ info |= AARCH64_IPA_CLOBBERS_ZA;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ if (auto *call = dyn_cast<const gcall *> (stmt))
|
||
|
|
+ {
|
||
|
|
+ if (gimple_call_builtin_p (call, BUILT_IN_MD))
|
||
|
|
+ {
|
||
|
|
+ /* The attributes on AArch64 builtins are supposed to be accurate.
|
||
|
|
+ If the function isn't marked streaming-compatible then it
|
||
|
|
+ needs whichever SM mode it selects. */
|
||
|
|
+ tree decl = gimple_call_fndecl (call);
|
||
|
|
+ if (aarch64_fndecl_pstate_sm (decl) != 0)
|
||
|
|
+ info |= AARCH64_IPA_SM_FIXED;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ return true;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/* Implement TARGET_CAN_INLINE_P. Decide whether it is valid
|
||
|
|
to inline CALLEE into CALLER based on target-specific info.
|
||
|
|
Make sure that the caller and callee have compatible architectural
|
||
|
|
@@ -21394,12 +21462,56 @@ aarch64_can_inline_p (tree caller, tree callee)
|
||
|
|
: target_option_default_node);
|
||
|
|
|
||
|
|
/* Callee's ISA flags should be a subset of the caller's. */
|
||
|
|
- if ((caller_opts->x_aarch64_asm_isa_flags
|
||
|
|
- & callee_opts->x_aarch64_asm_isa_flags)
|
||
|
|
- != callee_opts->x_aarch64_asm_isa_flags)
|
||
|
|
+ auto caller_asm_isa = (caller_opts->x_aarch64_asm_isa_flags
|
||
|
|
+ & ~AARCH64_FL_ISA_MODES);
|
||
|
|
+ auto callee_asm_isa = (callee_opts->x_aarch64_asm_isa_flags
|
||
|
|
+ & ~AARCH64_FL_ISA_MODES);
|
||
|
|
+ if (callee_asm_isa & ~caller_asm_isa)
|
||
|
|
return false;
|
||
|
|
- if ((caller_opts->x_aarch64_isa_flags & callee_opts->x_aarch64_isa_flags)
|
||
|
|
- != callee_opts->x_aarch64_isa_flags)
|
||
|
|
+
|
||
|
|
+ auto caller_isa = (caller_opts->x_aarch64_isa_flags
|
||
|
|
+ & ~AARCH64_FL_ISA_MODES);
|
||
|
|
+ auto callee_isa = (callee_opts->x_aarch64_isa_flags
|
||
|
|
+ & ~AARCH64_FL_ISA_MODES);
|
||
|
|
+ if (callee_isa & ~caller_isa)
|
||
|
|
+ return false;
|
||
|
|
+
|
||
|
|
+ /* Return true if the callee might have target_info property PROPERTY.
|
||
|
|
+ The answer must be true unless we have positive proof to the contrary. */
|
||
|
|
+ auto callee_has_property = [&](unsigned int property)
|
||
|
|
+ {
|
||
|
|
+ if (ipa_fn_summaries)
|
||
|
|
+ if (auto *summary = ipa_fn_summaries->get (cgraph_node::get (callee)))
|
||
|
|
+ if (!(summary->target_info & property))
|
||
|
|
+ return false;
|
||
|
|
+ return true;
|
||
|
|
+ };
|
||
|
|
+
|
||
|
|
+ /* Streaming-compatible code can be inlined into functions with any
|
||
|
|
+ PSTATE.SM mode. Otherwise the caller and callee must agree on
|
||
|
|
+ PSTATE.SM mode, unless we can prove that the callee is naturally
|
||
|
|
+ streaming-compatible. */
|
||
|
|
+ auto caller_sm = (caller_opts->x_aarch64_isa_flags & AARCH64_FL_SM_STATE);
|
||
|
|
+ auto callee_sm = (callee_opts->x_aarch64_isa_flags & AARCH64_FL_SM_STATE);
|
||
|
|
+ if (callee_sm
|
||
|
|
+ && caller_sm != callee_sm
|
||
|
|
+ && callee_has_property (AARCH64_IPA_SM_FIXED))
|
||
|
|
+ return false;
|
||
|
|
+
|
||
|
|
+ /* aarch64_function_attribute_inlinable_p prevents new-ZA functions
|
||
|
|
+ from being inlined into others. We also need to prevent inlining
|
||
|
|
+ of shared-ZA functions into functions without ZA state, since this
|
||
|
|
+ is an error condition.
|
||
|
|
+
|
||
|
|
+ The only other problematic case for ZA is inlining a function that
|
||
|
|
+ directly clobbers ZA into a function that has ZA state. */
|
||
|
|
+ auto caller_za = (caller_opts->x_aarch64_isa_flags & AARCH64_FL_ZA_ON);
|
||
|
|
+ auto callee_za = (callee_opts->x_aarch64_isa_flags & AARCH64_FL_ZA_ON);
|
||
|
|
+ if (!caller_za && callee_za)
|
||
|
|
+ return false;
|
||
|
|
+ if (caller_za
|
||
|
|
+ && !callee_za
|
||
|
|
+ && callee_has_property (AARCH64_IPA_CLOBBERS_ZA))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
/* Allow non-strict aligned functions inlining into strict
|
||
|
|
@@ -30732,6 +30844,16 @@ aarch64_get_v16qi_mode ()
|
||
|
|
#undef TARGET_CAN_ELIMINATE
|
||
|
|
#define TARGET_CAN_ELIMINATE aarch64_can_eliminate
|
||
|
|
|
||
|
|
+#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
|
||
|
|
+#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P \
|
||
|
|
+ aarch64_function_attribute_inlinable_p
|
||
|
|
+
|
||
|
|
+#undef TARGET_NEED_IPA_FN_TARGET_INFO
|
||
|
|
+#define TARGET_NEED_IPA_FN_TARGET_INFO aarch64_need_ipa_fn_target_info
|
||
|
|
+
|
||
|
|
+#undef TARGET_UPDATE_IPA_FN_TARGET_INFO
|
||
|
|
+#define TARGET_UPDATE_IPA_FN_TARGET_INFO aarch64_update_ipa_fn_target_info
|
||
|
|
+
|
||
|
|
#undef TARGET_CAN_INLINE_P
|
||
|
|
#define TARGET_CAN_INLINE_P aarch64_can_inline_p
|
||
|
|
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_1.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_1.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..24dc2b341
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_1.c
|
||
|
|
@@ -0,0 +1,47 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_callee () [[arm::streaming]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_callee () {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_callee () {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_asm_callee () [[arm::streaming_compatible]] { asm (""); }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_asm_callee () [[arm::streaming]] { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_asm_callee () { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_asm_callee () [[arm::streaming_compatible]] { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_asm_callee () { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+sc_caller () [[arm::streaming_compatible]]
|
||
|
|
+{
|
||
|
|
+ sc_callee ();
|
||
|
|
+ s_callee ();
|
||
|
|
+ n_callee ();
|
||
|
|
+ sc_ls_callee ();
|
||
|
|
+ n_ls_callee ();
|
||
|
|
+
|
||
|
|
+ sc_asm_callee ();
|
||
|
|
+ s_asm_callee ();
|
||
|
|
+ n_asm_callee ();
|
||
|
|
+ sc_ls_asm_callee ();
|
||
|
|
+ n_ls_asm_callee ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_10.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_10.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..adfd45a87
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_10.c
|
||
|
|
@@ -0,0 +1,57 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+#include <arm_neon.h>
|
||
|
|
+#include <arm_sme.h>
|
||
|
|
+
|
||
|
|
+uint8x16_t *neon;
|
||
|
|
+svint64_t *sve;
|
||
|
|
+int64_t *ptr;
|
||
|
|
+
|
||
|
|
+// Gets expanded to addition early, so no error. An error would be
|
||
|
|
+// more correct though.
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_vadd ()
|
||
|
|
+{
|
||
|
|
+ neon[4] = vaddq_u8 (neon[5], neon[6]);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_vbsl () // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ neon[0] = vbslq_u8 (neon[1], neon[2], neon[3]);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svadd ()
|
||
|
|
+{
|
||
|
|
+ *sve = svadd_x (svptrue_b8 (), *sve, 1);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svld1_gather () // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ *sve = svld1_gather_offset (svptrue_b8 (), ptr, *sve);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svzero () [[arm::inout("za")]]
|
||
|
|
+{
|
||
|
|
+ svzero_za ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svst1_za () [[arm::streaming, arm::inout("za")]] // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ svst1_ver_za64 (0, 0, svptrue_b8 (), ptr);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+sc_caller () [[arm::inout("za"), arm::streaming_compatible]]
|
||
|
|
+{
|
||
|
|
+ call_vadd ();
|
||
|
|
+ call_vbsl ();
|
||
|
|
+ call_svadd ();
|
||
|
|
+ call_svld1_gather ();
|
||
|
|
+ call_svzero ();
|
||
|
|
+ call_svst1_za ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_11.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_11.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..d05a92c1c
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_11.c
|
||
|
|
@@ -0,0 +1,57 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+#include <arm_neon.h>
|
||
|
|
+#include <arm_sme.h>
|
||
|
|
+
|
||
|
|
+uint8x16_t *neon;
|
||
|
|
+svint64_t *sve;
|
||
|
|
+int64_t *ptr;
|
||
|
|
+
|
||
|
|
+// Gets expanded to addition early, so no error. An error would be
|
||
|
|
+// more correct though.
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_vadd ()
|
||
|
|
+{
|
||
|
|
+ neon[4] = vaddq_u8 (neon[5], neon[6]);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_vbsl () // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ neon[0] = vbslq_u8 (neon[1], neon[2], neon[3]);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svadd ()
|
||
|
|
+{
|
||
|
|
+ *sve = svadd_x (svptrue_b8 (), *sve, 1);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svld1_gather () // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ *sve = svld1_gather_offset (svptrue_b8 (), ptr, *sve);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svzero () [[arm::inout("za")]]
|
||
|
|
+{
|
||
|
|
+ svzero_za ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svst1_za () [[arm::streaming, arm::inout("za")]]
|
||
|
|
+{
|
||
|
|
+ svst1_ver_za64 (0, 0, svptrue_b8 (), ptr);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+sc_caller () [[arm::inout("za"), arm::streaming]]
|
||
|
|
+{
|
||
|
|
+ call_vadd ();
|
||
|
|
+ call_vbsl ();
|
||
|
|
+ call_svadd ();
|
||
|
|
+ call_svld1_gather ();
|
||
|
|
+ call_svzero ();
|
||
|
|
+ call_svst1_za ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_12.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_12.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..366f8b24a
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_12.c
|
||
|
|
@@ -0,0 +1,15 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+#include <arm_sme.h>
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svzero () [[arm::inout("za"), arm::streaming_compatible]] // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ svzero_za ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+n_caller ()
|
||
|
|
+{
|
||
|
|
+ call_svzero ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_13.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_13.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..bdbd7408c
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_13.c
|
||
|
|
@@ -0,0 +1,15 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+#include <arm_sme.h>
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svzero () [[arm::inout("za"), arm::streaming_compatible]] // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ svzero_za ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+s_caller ()
|
||
|
|
+{
|
||
|
|
+ call_svzero ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_14.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_14.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..0ce4384f6
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_14.c
|
||
|
|
@@ -0,0 +1,15 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+#include <arm_sme.h>
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svzero () [[arm::inout("za"), arm::streaming_compatible]] // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ svzero_za ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+sc_caller ()
|
||
|
|
+{
|
||
|
|
+ call_svzero ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_15.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_15.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..06fc5d7f5
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_15.c
|
||
|
|
@@ -0,0 +1,27 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+#include <arm_sme.h>
|
||
|
|
+
|
||
|
|
+inline void
|
||
|
|
+call_svzero () [[arm::inout("za"), arm::streaming_compatible]]
|
||
|
|
+{
|
||
|
|
+ svzero_za ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+n_caller ()
|
||
|
|
+{
|
||
|
|
+ call_svzero (); // { dg-error "call to a function that shares 'za' state from a function that has no 'za' state" }
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+s_caller ()
|
||
|
|
+{
|
||
|
|
+ call_svzero (); // { dg-error "call to a function that shares 'za' state from a function that has no 'za' state" }
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+sc_caller ()
|
||
|
|
+{
|
||
|
|
+ call_svzero (); // { dg-error "call to a function that shares 'za' state from a function that has no 'za' state" }
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_2.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_2.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..ea2a57049
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_2.c
|
||
|
|
@@ -0,0 +1,47 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_callee () [[arm::streaming]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_callee () {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_callee () {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_asm_callee () [[arm::streaming_compatible]] { asm (""); }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_asm_callee () [[arm::streaming]] { asm (""); }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_asm_callee () { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_asm_callee () [[arm::streaming_compatible]] { asm (""); }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_asm_callee () { asm (""); }
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+s_caller () [[arm::streaming]]
|
||
|
|
+{
|
||
|
|
+ sc_callee ();
|
||
|
|
+ s_callee ();
|
||
|
|
+ n_callee ();
|
||
|
|
+ sc_ls_callee ();
|
||
|
|
+ n_ls_callee ();
|
||
|
|
+
|
||
|
|
+ sc_asm_callee ();
|
||
|
|
+ s_asm_callee ();
|
||
|
|
+ n_asm_callee ();
|
||
|
|
+ sc_ls_asm_callee ();
|
||
|
|
+ n_ls_asm_callee ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_3.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_3.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..d7ffb3819
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_3.c
|
||
|
|
@@ -0,0 +1,47 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_callee () [[arm::streaming]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_callee () {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_callee () {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_asm_callee () [[arm::streaming_compatible]] { asm (""); }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_asm_callee () [[arm::streaming]] { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_asm_callee () { asm (""); }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_asm_callee () [[arm::streaming_compatible]] { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_asm_callee () { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+n_caller ()
|
||
|
|
+{
|
||
|
|
+ sc_callee ();
|
||
|
|
+ s_callee ();
|
||
|
|
+ n_callee ();
|
||
|
|
+ sc_ls_callee ();
|
||
|
|
+ n_ls_callee ();
|
||
|
|
+
|
||
|
|
+ sc_asm_callee ();
|
||
|
|
+ s_asm_callee ();
|
||
|
|
+ n_asm_callee ();
|
||
|
|
+ sc_ls_asm_callee ();
|
||
|
|
+ n_ls_asm_callee ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_4.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_4.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..789203725
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_4.c
|
||
|
|
@@ -0,0 +1,47 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_callee () [[arm::streaming]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_callee () {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_callee () {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_asm_callee () [[arm::streaming_compatible]] { asm (""); }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_asm_callee () [[arm::streaming]] { asm (""); }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_asm_callee () { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_asm_callee () [[arm::streaming_compatible]] { asm (""); }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_asm_callee () { asm (""); }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] void
|
||
|
|
+sc_ls_caller () [[arm::streaming_compatible]]
|
||
|
|
+{
|
||
|
|
+ sc_callee ();
|
||
|
|
+ s_callee ();
|
||
|
|
+ n_callee ();
|
||
|
|
+ sc_ls_callee ();
|
||
|
|
+ n_ls_callee ();
|
||
|
|
+
|
||
|
|
+ sc_asm_callee ();
|
||
|
|
+ s_asm_callee ();
|
||
|
|
+ n_asm_callee ();
|
||
|
|
+ sc_ls_asm_callee ();
|
||
|
|
+ n_ls_asm_callee ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_5.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_5.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..d19cdc450
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_5.c
|
||
|
|
@@ -0,0 +1,47 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_callee () [[arm::streaming]] {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_callee () {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_callee () [[arm::streaming_compatible]] {}
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_callee () {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+sc_asm_callee () [[arm::streaming_compatible]] { asm (""); }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+s_asm_callee () [[arm::streaming]] { asm (""); }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+n_asm_callee () { asm (""); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+sc_ls_asm_callee () [[arm::streaming_compatible]] { asm (""); }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] inline void __attribute__((always_inline))
|
||
|
|
+n_ls_asm_callee () { asm (""); }
|
||
|
|
+
|
||
|
|
+[[arm::locally_streaming]] void
|
||
|
|
+n_ls_caller ()
|
||
|
|
+{
|
||
|
|
+ sc_callee ();
|
||
|
|
+ s_callee ();
|
||
|
|
+ n_callee ();
|
||
|
|
+ sc_ls_callee ();
|
||
|
|
+ n_ls_callee ();
|
||
|
|
+
|
||
|
|
+ sc_asm_callee ();
|
||
|
|
+ s_asm_callee ();
|
||
|
|
+ n_asm_callee ();
|
||
|
|
+ sc_ls_asm_callee ();
|
||
|
|
+ n_ls_asm_callee ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_6.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_6.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..a5eb399f1
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_6.c
|
||
|
|
@@ -0,0 +1,31 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+shared_callee () [[arm::inout("za")]] {}
|
||
|
|
+
|
||
|
|
+[[arm::new("za")]] inline void __attribute__((always_inline))
|
||
|
|
+new_callee () {} // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+normal_callee () {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+shared_asm_callee () [[arm::inout("za")]] { asm volatile ("" ::: "za"); }
|
||
|
|
+
|
||
|
|
+[[arm::new("za")]] inline void __attribute__((always_inline))
|
||
|
|
+new_asm_callee () { asm volatile ("" ::: "za"); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+normal_asm_callee () { asm volatile ("" ::: "za"); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+shared_caller () [[arm::inout("za")]]
|
||
|
|
+{
|
||
|
|
+ shared_callee ();
|
||
|
|
+ new_callee ();
|
||
|
|
+ normal_callee ();
|
||
|
|
+
|
||
|
|
+ shared_asm_callee ();
|
||
|
|
+ new_asm_callee ();
|
||
|
|
+ normal_asm_callee ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_7.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_7.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..0f046283f
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_7.c
|
||
|
|
@@ -0,0 +1,31 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+shared_callee () [[arm::inout("za")]] {}
|
||
|
|
+
|
||
|
|
+[[arm::new("za")]] inline void __attribute__((always_inline))
|
||
|
|
+new_callee () {} // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+normal_callee () {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+shared_asm_callee () [[arm::inout("za")]] { asm volatile ("" ::: "za"); }
|
||
|
|
+
|
||
|
|
+[[arm::new("za")]] inline void __attribute__((always_inline))
|
||
|
|
+new_asm_callee () { asm volatile ("" ::: "za"); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+normal_asm_callee () { asm volatile ("" ::: "za"); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::new("za")]] void
|
||
|
|
+new_caller ()
|
||
|
|
+{
|
||
|
|
+ shared_callee ();
|
||
|
|
+ new_callee ();
|
||
|
|
+ normal_callee ();
|
||
|
|
+
|
||
|
|
+ shared_asm_callee ();
|
||
|
|
+ new_asm_callee ();
|
||
|
|
+ normal_asm_callee ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_8.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_8.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..fd8a3a61e
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_8.c
|
||
|
|
@@ -0,0 +1,31 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+shared_callee () [[arm::inout("za")]] {} // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::new("za")]] inline void __attribute__((always_inline))
|
||
|
|
+new_callee () {} // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+normal_callee () {}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+shared_asm_callee () [[arm::inout("za")]] { asm volatile ("" ::: "za"); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+[[arm::new("za")]] inline void __attribute__((always_inline))
|
||
|
|
+new_asm_callee () { asm volatile ("" ::: "za"); } // { dg-error "inlining failed" }
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+normal_asm_callee () { asm volatile ("" ::: "za"); }
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+normal_caller ()
|
||
|
|
+{
|
||
|
|
+ shared_callee ();
|
||
|
|
+ new_callee ();
|
||
|
|
+ normal_callee ();
|
||
|
|
+
|
||
|
|
+ shared_asm_callee ();
|
||
|
|
+ new_asm_callee ();
|
||
|
|
+ normal_asm_callee ();
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_9.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_9.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..91520e378
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_9.c
|
||
|
|
@@ -0,0 +1,55 @@
|
||
|
|
+/* { dg-options "" } */
|
||
|
|
+
|
||
|
|
+#include <arm_neon.h>
|
||
|
|
+#include <arm_sme.h>
|
||
|
|
+
|
||
|
|
+uint8x16_t *neon;
|
||
|
|
+svint64_t *sve;
|
||
|
|
+int64_t *ptr;
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_vadd ()
|
||
|
|
+{
|
||
|
|
+ neon[4] = vaddq_u8 (neon[5], neon[6]);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_vbsl ()
|
||
|
|
+{
|
||
|
|
+ neon[0] = vbslq_u8 (neon[1], neon[2], neon[3]);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svadd ()
|
||
|
|
+{
|
||
|
|
+ *sve = svadd_x (svptrue_b8 (), *sve, 1);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svld1_gather ()
|
||
|
|
+{
|
||
|
|
+ *sve = svld1_gather_offset (svptrue_b8 (), ptr, *sve);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svzero () [[arm::inout("za")]]
|
||
|
|
+{
|
||
|
|
+ svzero_za ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+inline void __attribute__((always_inline))
|
||
|
|
+call_svst1_za () [[arm::streaming, arm::inout("za")]] // { dg-error "inlining failed" }
|
||
|
|
+{
|
||
|
|
+ svst1_ver_za64 (0, 0, svptrue_b8 (), ptr);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void
|
||
|
|
+n_caller () [[arm::inout("za")]]
|
||
|
|
+{
|
||
|
|
+ call_vadd ();
|
||
|
|
+ call_vbsl ();
|
||
|
|
+ call_svadd ();
|
||
|
|
+ call_svld1_gather ();
|
||
|
|
+ call_svzero ();
|
||
|
|
+ call_svst1_za ();
|
||
|
|
+}
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|