[PATCH 2/2] aarch64: Remove streaming compatible mismatch override [PR124416]

Alice Carlotti <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
In theory, it is possible to inline a callee function into a caller
function with incompatible streaming state, if we can prove that the
body of the callee function will behave identically in both streaming
and non-streaming mode.  Unfortunately the existing checks are far too
lenient, so this can result in ICEs or incorrect codegen.

Fixing the checks is non-trivial, so remove them.

If this functionality is to be correctly implemented in future, it would
need to include at least the following incompatibility checks:
- Code in the callee that depends upon the vector length in any way.
- A streaming compatible function called by the callee, that would be
  run under a different mode after inlining.
- An always_inline function called by the callee, that can't be inlined
  into the new caller.
- Intrinsics that have different architecture requirements in streaming
  vs. non-streaming mode (for example, many AdvSIMD intrinsics might be
  unavailable in streaming mode).

gcc/ChangeLog:

	PR target/124416
	* config/aarch64/aarch64.cc (AARCH64_IPA_SM_FIXED): Delete.
	(aarch64_update_ipa_fn_target_info): Don't set
	AARCH64_IPA_SM_FIXED.
	(aarch64_can_inline_p): Remove AARCH64_IPA_SM_FIXED uses.

gcc/testsuite/ChangeLog:

	PR target/124416
	* gcc.target/aarch64/sme/inlining_16.c: New test.
	* gcc.target/aarch64/sme/inlining_17.c: New test.
	* gcc.target/aarch64/sme/inlining_18.c: New test.


diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 7f4effc0901f86ca62908692a9ee35bf6a047fd4..53830308de2fc566da80237f68423a7318db4668 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -22255,11 +22255,6 @@ aarch64_tribools_ok_for_inlining_p (int caller, int callee,
 
 /* 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 and ZT0.  Not meaningful for functions that
    have ZA state.  */
 constexpr auto AARCH64_IPA_CLOBBERS_ZA = 1U << 1;
@@ -22282,9 +22277,6 @@ 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);
@@ -22295,18 +22287,6 @@ aarch64_update_ipa_fn_target_info (unsigned int &info, const gimple *stmt)
 	    info |= AARCH64_IPA_CLOBBERS_ZT0;
 	}
     }
-  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;
 }
 
@@ -22362,17 +22342,11 @@ aarch64_can_inline_p (tree caller, tree callee)
 
   /* 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 with behaviour that is independent of streaming
-     state.  If the callee is marked as always inline, then this last
-     exception doesn't apply, to ensure that error reporting is unaffected
-     by differing optimisations.  */
+     PSTATE.SM mode.  */
 
   auto caller_sm = (aarch64_get_isa_flags (caller_opts) & AARCH64_FL_SM_STATE);
   auto callee_sm = (aarch64_get_isa_flags (callee_opts) & AARCH64_FL_SM_STATE);
-  if (callee_sm
-      && caller_sm != callee_sm
-      && (always_inline || callee_has_property (AARCH64_IPA_SM_FIXED)))
+  if (callee_sm && caller_sm != callee_sm)
     return false;
 
   /* aarch64_function_attribute_inlinable_p prevents new-ZA and new-ZT0
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_16.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_16.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f54683e4e796dc1fba1e7b2d343755fe9b64228
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_16.c
@@ -0,0 +1,51 @@
+/* { dg-options "-O3" } */
+#include <arm_sme.h>
+
+#pragma GCC target "+sve"
+
+static inline int callee_ns (void)
+{
+  return svcntw ();
+}
+
+int caller1_s(void) __arm_streaming
+{
+  return callee_ns () + svcntw ();
+}
+
+int caller1_sc(void) __arm_streaming_compatible
+{
+  return callee_ns () + svcntw ();
+}
+
+static inline int callee_s (void) __arm_streaming
+{
+  return svcntw ();
+}
+
+int caller2_ns(void)
+{
+  return callee_s () + svcntw ();
+}
+
+int caller2_sc(void) __arm_streaming_compatible
+{
+  return callee_s () + svcntw ();
+}
+
+static inline int callee_ls (void) __arm_streaming
+{
+  return svcntw ();
+}
+
+int caller3_ns(void)
+{
+  return callee_ls () + svcntw ();
+}
+
+int caller3_sc(void) __arm_streaming_compatible
+{
+  return callee_ls () + svcntw ();
+}
+
+/* { dg-final { scan-assembler-not {cnth} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_17.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_17.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f132798c44015a318b83a8fe375aa9f17c7b2eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_17.c
@@ -0,0 +1,91 @@
+/* { dg-options "-O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sme.h>
+
+#pragma GCC target "+sve"
+
+int child_sc (void) __arm_streaming_compatible;
+
+
+static inline int callee_ns (void)
+{
+  return child_sc ();
+}
+
+/*
+** caller1_s:
+**	...
+**	bl	callee_ns
+**	...
+*/
+int caller1_s(void) __arm_streaming
+{
+  return callee_ns ();
+}
+
+/*
+** caller1_sc:
+**	...
+**	bl	callee_ns
+**	...
+*/
+int caller1_sc(void) __arm_streaming_compatible
+{
+  return callee_ns ();
+}
+
+static inline int callee_s (void) __arm_streaming
+{
+  return child_sc ();
+}
+
+/*
+** caller2_ns:
+**	...
+**	bl	callee_s
+**	...
+*/
+int caller2_ns(void)
+{
+  return callee_s ();
+}
+
+/*
+** caller2_sc:
+**	...
+**	bl	callee_s
+**	...
+*/
+int caller2_sc(void) __arm_streaming_compatible
+{
+  return callee_s ();
+}
+
+__arm_locally_streaming
+static inline int callee_ls (void)
+{
+  return child_sc ();
+}
+
+/*
+** caller3_ns:
+**	...
+**	b	callee_ls
+**	...
+*/
+int caller3_ns(void)
+{
+  return callee_ls ();
+}
+
+/*
+** caller3_sc:
+**	...
+**	bl	callee_ls
+**	...
+*/
+int caller3_sc(void) __arm_streaming_compatible
+{
+  return callee_ls ();
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_18.c b/gcc/testsuite/gcc.target/aarch64/sme/inlining_18.c
new file mode 100644
index 0000000000000000000000000000000000000000..d967d037740f2fc989471dce99d0cbe609aaed21
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_18.c
@@ -0,0 +1,100 @@
+/* { dg-options "-O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sme.h>
+
+#pragma GCC target "+sve"
+
+__attribute__((always_inline))
+static inline int child_ns (void)
+{
+  return svcntw ();
+}
+
+__attribute__((always_inline))
+static inline int child_s (void) __arm_streaming
+{
+  return svcntw ();
+}
+
+static inline int callee_ns (void)
+{
+  return child_ns ();
+}
+
+/*
+** caller1_s:
+**	...
+**	bl	callee_ns
+**	...
+*/
+int caller1_s(void) __arm_streaming
+{
+  return callee_ns ();
+}
+
+/*
+** caller1_sc:
+**	...
+**	bl	callee_ns
+**	...
+*/
+int caller1_sc(void) __arm_streaming_compatible
+{
+  return callee_ns ();
+}
+
+static inline int callee_s (void) __arm_streaming
+{
+  return child_s ();
+}
+
+/*
+** caller2_ns:
+**	...
+**	bl	callee_s
+**	...
+*/
+int caller2_ns(void)
+{
+  return callee_s ();
+}
+
+/*
+** caller2_sc:
+**	...
+**	bl	callee_s
+**	...
+*/
+int caller2_sc(void) __arm_streaming_compatible
+{
+  return callee_s ();
+}
+
+__arm_locally_streaming
+static inline int callee_ls (void)
+{
+  return child_s ();
+}
+
+/*
+** caller3_ns:
+**	...
+**	b	callee_ls
+**	...
+*/
+int caller3_ns(void)
+{
+  return callee_ls ();
+}
+
+/*
+** caller3_sc:
+**	...
+**	bl	callee_ls
+**	...
+*/
+int caller3_sc(void) __arm_streaming_compatible
+{
+  return callee_ls ();
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.