aarch64_can_inline_p includes a check for whether the content of a
callee function is compatible with the caller's streaming state, even if
the callee's streaming state would otherwise be incompatible.  If the
caller is marked as always_inline, we should report the mismatch
consistently, so don't check AARCH64_IPA_SM_FIXED in this case.

gcc/ChangeLog:

        PR target/126133
        * config/aarch64/aarch64.cc (aarch64_can_inline_p): Only check
        AARCH64_IPA_SM_FIXED when always_inline is false.

gcc/testsuite/ChangeLog:

        PR target/126133
        * gcc.target/aarch64/sme/inlining_1.c: Add new expected errors.
        * gcc.target/aarch64/sme/inlining_2.c: Ditto.
        * gcc.target/aarch64/sme/inlining_3.c: Ditto.
        * gcc.target/aarch64/sme/inlining_4.c: Ditto.
        * gcc.target/aarch64/sme/inlining_5.c: Ditto.
        * gcc.target/aarch64/sme/inlining_10.c: Ditto.
        * gcc.target/aarch64/sme/inlining_11.c: Ditto.


diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 
8a788a5c7e41724d83d30d4bc289385037055ac6..7f4effc0901f86ca62908692a9ee35bf6a047fd4
 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -22357,15 +22357,22 @@ aarch64_can_inline_p (tree caller, tree callee)
       return true;
     };
 
+  bool always_inline = lookup_attribute ("always_inline",
+                                         DECL_ATTRIBUTES (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.  */
+     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.  */
+
   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
-      && callee_has_property (AARCH64_IPA_SM_FIXED))
+      && (always_inline || callee_has_property (AARCH64_IPA_SM_FIXED)))
     return false;
 
   /* aarch64_function_attribute_inlinable_p prevents new-ZA and new-ZT0
@@ -22396,9 +22403,6 @@ aarch64_can_inline_p (tree caller, tree callee)
           && TARGET_STRICT_ALIGN_P (caller_opts->x_target_flags)))
     return false;
 
-  bool always_inline = lookup_attribute ("always_inline",
-                                         DECL_ATTRIBUTES (callee));
-
   /* If the architectural features match up and the callee is always_inline
      then the other attributes don't matter.  */
   if (always_inline)
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_1.c 
b/gcc/testsuite/gcc.target/aarch64/sme/inlining_1.c
index 
24dc2b3418797d315b46f116d816478b69dfb0d2..7230ae2ed835b9783f3510f472007b99cdfccd58
 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/inlining_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_1.c
@@ -4,16 +4,16 @@ inline void __attribute__((always_inline))
 sc_callee () [[arm::streaming_compatible]] {}
 
 inline void __attribute__((always_inline))
-s_callee () [[arm::streaming]] {}
+s_callee () [[arm::streaming]] {} // { dg-error "inlining failed" }
 
 inline void __attribute__((always_inline))
-n_callee () {}
+n_callee () {} // { dg-error "inlining failed" }
 
 [[arm::locally_streaming]] inline void __attribute__((always_inline))
-sc_ls_callee () [[arm::streaming_compatible]] {}
+sc_ls_callee () [[arm::streaming_compatible]] {} // { dg-error "inlining 
failed" }
 
 [[arm::locally_streaming]] inline void __attribute__((always_inline))
-n_ls_callee () {}
+n_ls_callee () {} // { dg-error "inlining failed" }
 
 inline void __attribute__((always_inline))
 sc_asm_callee () [[arm::streaming_compatible]] { asm (""); }
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_10.c 
b/gcc/testsuite/gcc.target/aarch64/sme/inlining_10.c
index 
131fb7a66379e96a0448133635bf51d65bb64dbe..98b04e13e2a6f2e2320c9d9b633bf4f44b15e212
 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/inlining_10.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_10.c
@@ -9,10 +9,8 @@ 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 ()
+call_vadd () // { dg-error "inlining failed" }
 {
   neon[4] = vaddq_u8 (neon[5], neon[6]);
 }
@@ -24,7 +22,7 @@ call_vhadd () // { dg-error "inlining failed" }
 }
 
 inline void __attribute__((always_inline))
-call_svadd ()
+call_svadd () // { dg-error "inlining failed" }
 {
   *sve = svadd_x (svptrue_b8 (), *sve, 1);
 }
@@ -36,7 +34,7 @@ call_svld1_gather () // { dg-error "inlining failed" }
 }
 
 inline void __attribute__((always_inline))
-call_svzero () [[arm::inout("za")]]
+call_svzero () [[arm::inout("za")]] // { dg-error "inlining failed" }
 {
   svzero_za ();
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_11.c 
b/gcc/testsuite/gcc.target/aarch64/sme/inlining_11.c
index 
d500a62743d08a824347eb247521aec14e4e0e32..ff5acab847b1a1b0c92010921541d4bef9658e82
 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/inlining_11.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_11.c
@@ -12,7 +12,7 @@ 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 ()
+call_vadd () // { dg-error "inlining failed" }
 {
   neon[4] = vaddq_u8 (neon[5], neon[6]);
 }
@@ -24,7 +24,7 @@ call_vhadd () // { dg-error "inlining failed" }
 }
 
 inline void __attribute__((always_inline))
-call_svadd ()
+call_svadd () // { dg-error "inlining failed" }
 {
   *sve = svadd_x (svptrue_b8 (), *sve, 1);
 }
@@ -36,7 +36,7 @@ call_svld1_gather () // { dg-error "inlining failed" }
 }
 
 inline void __attribute__((always_inline))
-call_svzero () [[arm::inout("za")]]
+call_svzero () [[arm::inout("za")]] // { dg-error "inlining failed" }
 {
   svzero_za ();
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_2.c 
b/gcc/testsuite/gcc.target/aarch64/sme/inlining_2.c
index 
ea2a57049cd52b3ac2da574011b8eea796e14483..0d4e9e218979b4a163bc610dc0c4118189bdfbd4
 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/inlining_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_2.c
@@ -7,7 +7,7 @@ inline void __attribute__((always_inline))
 s_callee () [[arm::streaming]] {}
 
 inline void __attribute__((always_inline))
-n_callee () {}
+n_callee () {} // { dg-error "inlining failed" }
 
 [[arm::locally_streaming]] inline void __attribute__((always_inline))
 sc_ls_callee () [[arm::streaming_compatible]] {}
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_3.c 
b/gcc/testsuite/gcc.target/aarch64/sme/inlining_3.c
index 
d7ffb381985bac74fe9c3bd74df9b0549478093e..4164cbbe39d1d251edcaaf08034ffa870c8d431c
 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/inlining_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_3.c
@@ -4,16 +4,16 @@ inline void __attribute__((always_inline))
 sc_callee () [[arm::streaming_compatible]] {}
 
 inline void __attribute__((always_inline))
-s_callee () [[arm::streaming]] {}
+s_callee () [[arm::streaming]] {} // { dg-error "inlining failed" }
 
 inline void __attribute__((always_inline))
 n_callee () {}
 
 [[arm::locally_streaming]] inline void __attribute__((always_inline))
-sc_ls_callee () [[arm::streaming_compatible]] {}
+sc_ls_callee () [[arm::streaming_compatible]] {} // { dg-error "inlining 
failed" }
 
 [[arm::locally_streaming]] inline void __attribute__((always_inline))
-n_ls_callee () {}
+n_ls_callee () {} // { dg-error "inlining failed" }
 
 inline void __attribute__((always_inline))
 sc_asm_callee () [[arm::streaming_compatible]] { asm (""); }
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_4.c 
b/gcc/testsuite/gcc.target/aarch64/sme/inlining_4.c
index 
78920372500d263a71d299fd69628aa578d56456..2218432c0a7728dbe873b782e8a21efaf2e2087c
 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/inlining_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_4.c
@@ -7,7 +7,7 @@ inline void __attribute__((always_inline))
 s_callee () [[arm::streaming]] {}
 
 inline void __attribute__((always_inline))
-n_callee () {}
+n_callee () {} // { dg-error "inlining failed" }
 
 [[arm::locally_streaming]] inline void __attribute__((always_inline))
 sc_ls_callee () [[arm::streaming_compatible]] {}
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/inlining_5.c 
b/gcc/testsuite/gcc.target/aarch64/sme/inlining_5.c
index 
d19cdc450d32caaa577f3a38bf23d63eb3aba5d9..bc18218ad7f70a1b1e289253db2c5c8f88a020a3
 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/inlining_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/inlining_5.c
@@ -7,7 +7,7 @@ inline void __attribute__((always_inline))
 s_callee () [[arm::streaming]] {}
 
 inline void __attribute__((always_inline))
-n_callee () {}
+n_callee () {} // { dg-error "inlining failed" }
 
 [[arm::locally_streaming]] inline void __attribute__((always_inline))
 sc_ls_callee () [[arm::streaming_compatible]] {}

Reply via email to