[libc] Switch to using the generic `<gpuintrin.h>` implementations (#121810)
[llvm-project.git] / clang / test / Sema / aarch64-sme-func-attrs.c
blob0c263eb2610cfbc65e7c36437bffe9db0351037b
1 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sme -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sme -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify=expected-cpp -x c++ %s
4 // Valid attributes
6 void sme_arm_streaming(void) __arm_streaming;
7 void sme_arm_streaming_compatible(void) __arm_streaming_compatible;
9 __arm_new("za") void sme_arm_new_za(void) {}
10 void sme_arm_shared_za(void) __arm_inout("za");
11 void sme_arm_preserves_za(void) __arm_preserves("za");
13 __arm_new("za") void sme_arm_streaming_new_za(void) __arm_streaming {}
14 void sme_arm_streaming_shared_za(void) __arm_streaming __arm_inout("za");
15 void sme_arm_streaming_preserves_za(void) __arm_streaming __arm_preserves("za");
17 __arm_new("za") void sme_arm_sc_new_za(void) __arm_streaming_compatible {}
18 void sme_arm_sc_shared_za(void) __arm_streaming_compatible __arm_inout("za");
19 void sme_arm_sc_preserves_za(void) __arm_streaming_compatible __arm_preserves("za");
21 __arm_locally_streaming void sme_arm_locally_streaming(void) { }
22 __arm_locally_streaming void sme_arm_streaming_and_locally_streaming(void) __arm_streaming { }
23 __arm_locally_streaming void sme_arm_streaming_and_streaming_compatible(void) __arm_streaming_compatible { }
25 __arm_locally_streaming __arm_new("za") void sme_arm_ls_new_za(void) { }
26 __arm_locally_streaming void sme_arm_ls_shared_za(void) __arm_inout("za") { }
27 __arm_locally_streaming void sme_arm_ls_preserves_za(void) __arm_preserves("za") { }
29 // Valid attributes on function pointers
31 void streaming_ptr(void) __arm_streaming;
32 typedef void (*fptrty1) (void) __arm_streaming;
33 fptrty1 call_streaming_func() { return streaming_ptr; }
35 void streaming_compatible_ptr(void) __arm_streaming_compatible;
36 typedef void (*fptrty2) (void) __arm_streaming_compatible;
37 fptrty2 call_sc_func() { return streaming_compatible_ptr; }
39 void shared_za_ptr(void) __arm_inout("za");
40 typedef void (*fptrty3) (void) __arm_inout("za");
41 fptrty3 call_shared_za_func() { return shared_za_ptr; }
43 void preserves_za_ptr(void) __arm_preserves("za");
44 typedef void (*fptrty4) (void) __arm_preserves("za");
45 fptrty4 call_preserve_za_func() { return preserves_za_ptr; }
47 typedef void (*fptrty6) (void);
48 fptrty6 cast_nza_func_to_normal() { return sme_arm_new_za; }
49 fptrty6 cast_ls_func_to_normal() { return sme_arm_locally_streaming; }
51 // Invalid attributes
53 // expected-cpp-error@+4 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}}
54 // expected-cpp-note@+3 {{conflicting attribute is here}}
55 // expected-error@+2 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}}
56 // expected-note@+1 {{conflicting attribute is here}}
57 void streaming_mode(void) __arm_streaming __arm_streaming_compatible;
59 // expected-cpp-error@+4 {{'__arm_streaming' and '__arm_streaming_compatible' are not compatible}}
60 // expected-cpp-note@+3 {{conflicting attribute is here}}
61 // expected-error@+2 {{'__arm_streaming' and '__arm_streaming_compatible' are not compatible}}
62 // expected-note@+1 {{conflicting attribute is here}}
63 void streaming_compatible(void) __arm_streaming_compatible __arm_streaming;
65 // expected-cpp-error@+2 {{'__arm_new("za")' and '__arm_inout("za")' are not compatible}}
66 // expected-error@+1 {{'__arm_new("za")' and '__arm_inout("za")' are not compatible}}
67 __arm_new("za") void new_shared_za(void) __arm_inout("za") {}
69 // expected-cpp-error@+2 {{'__arm_new("za")' and '__arm_preserves("za")' are not compatible}}
70 // expected-error@+1 {{'__arm_new("za")' and '__arm_preserves("za")' are not compatible}}
71 __arm_new("za") void new_preserves_za(void) __arm_preserves("za") {}
73 // Invalid attributes on function pointers
75 // expected-cpp-error@+4 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}}
76 // expected-cpp-note@+3 {{conflicting attribute is here}}
77 // expected-error@+2 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}}
78 // expected-note@+1 {{conflicting attribute is here}}
79 void streaming_ptr_invalid(void) __arm_streaming __arm_streaming_compatible;
80 // expected-cpp-error@+4 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}}
81 // expected-cpp-note@+3 {{conflicting attribute is here}}
82 // expected-error@+2 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}}
83 // expected-note@+1 {{conflicting attribute is here}}
84 typedef void (*fptrty7) (void) __arm_streaming __arm_streaming_compatible;
85 fptrty7 invalid_streaming_func() { return streaming_ptr_invalid; }
87 // expected-warning@+2 {{'__arm_streaming' only applies to non-K&R-style functions}}
88 // expected-error@+1 {{'__arm_streaming' only applies to function types; type here is 'void ()'}}
89 void function_no_prototype() __arm_streaming;
92 // Check for incorrect conversions of function pointers with the attributes
95 typedef void (*n_ptrty) (void);
96 typedef void (*s_ptrty) (void) __arm_streaming;
97 s_ptrty return_valid_streaming_fptr(s_ptrty f) { return f; }
99 // expected-cpp-error@+2 {{cannot initialize return object of type 's_ptrty' (aka 'void (*)() __arm_streaming') with an lvalue of type 'n_ptrty' (aka 'void (*)()')}}
100 // expected-error@+1 {{incompatible function pointer types returning 'n_ptrty' (aka 'void (*)(void)') from a function with result type 's_ptrty' (aka 'void (*)(void) __arm_streaming')}}
101 s_ptrty return_invalid_fptr_streaming_normal(n_ptrty f) { return f; }
102 // expected-cpp-error@+2 {{cannot initialize return object of type 'n_ptrty' (aka 'void (*)()') with an lvalue of type 's_ptrty' (aka 'void (*)() __arm_streaming')}}
103 // expected-error@+1 {{incompatible function pointer types returning 's_ptrty' (aka 'void (*)(void) __arm_streaming') from a function with result type 'n_ptrty' (aka 'void (*)(void)')}}
104 n_ptrty return_invalid_fptr_normal_streaming(s_ptrty f) { return f; }
106 // Test an instance where the result type is not a prototyped function, such that we still get a diagnostic.
107 typedef void (*nonproto_n_ptrty) ();
108 // expected-cpp-error@+2 {{cannot initialize return object of type 'nonproto_n_ptrty' (aka 'void (*)()') with an lvalue of type 's_ptrty' (aka 'void (*)() __arm_streaming')}}
109 // expected-error@+1 {{incompatible function pointer types returning 's_ptrty' (aka 'void (*)(void) __arm_streaming') from a function with result type 'nonproto_n_ptrty' (aka 'void (*)()')}}
110 nonproto_n_ptrty return_invalid_fptr_streaming_nonprotonormal(s_ptrty f) { return f; }
112 typedef void (*sc_ptrty) (void) __arm_streaming_compatible;
113 sc_ptrty return_valid_streaming_compatible_fptr(sc_ptrty f) { return f; }
115 // expected-cpp-error@+2 {{cannot initialize return object of type 'sc_ptrty' (aka 'void (*)() __arm_streaming_compatible') with an lvalue of type 'n_ptrty' (aka 'void (*)()')}}
116 // expected-error@+1 {{incompatible function pointer types returning 'n_ptrty' (aka 'void (*)(void)') from a function with result type 'sc_ptrty' (aka 'void (*)(void) __arm_streaming_compatible')}}
117 sc_ptrty return_invalid_fptr_streaming_compatible_normal(n_ptrty f) { return f; }
118 // expected-cpp-error@+2 {{cannot initialize return object of type 'n_ptrty' (aka 'void (*)()') with an lvalue of type 'sc_ptrty' (aka 'void (*)() __arm_streaming_compatible')}}
119 // expected-error@+1 {{incompatible function pointer types returning 'sc_ptrty' (aka 'void (*)(void) __arm_streaming_compatible') from a function with result type 'n_ptrty' (aka 'void (*)(void)')}}
120 n_ptrty return_invalid_fptr_normal_streaming_compatible(sc_ptrty f) { return f; }
122 typedef void (*sz_ptrty) (void) __arm_inout("za");
123 sz_ptrty return_valid_shared_za_fptr(sz_ptrty f) { return f; }
126 // expected-cpp-error@+2 {{cannot initialize return object of type 'sz_ptrty' (aka 'void (*)() __arm_inout("za")') with an lvalue of type 'n_ptrty' (aka 'void (*)()')}}
127 // expected-error@+1 {{incompatible function pointer types returning 'n_ptrty' (aka 'void (*)(void)') from a function with result type 'sz_ptrty' (aka 'void (*)(void) __arm_inout("za")')}}
128 sz_ptrty return_invalid_fptr_shared_za_normal(n_ptrty f) { return f; }
129 // expected-cpp-error@+2 {{cannot initialize return object of type 'n_ptrty' (aka 'void (*)()') with an lvalue of type 'sz_ptrty' (aka 'void (*)() __arm_inout("za")')}}
130 // expected-error@+1 {{incompatible function pointer types returning 'sz_ptrty' (aka 'void (*)(void) __arm_inout("za")') from a function with result type 'n_ptrty' (aka 'void (*)(void)')}}
131 n_ptrty return_invalid_fptr_normal_shared_za(sz_ptrty f) { return f; }
133 typedef void (*pz_ptrty) (void) __arm_preserves("za");
134 pz_ptrty return_valid_preserves_za_fptr(pz_ptrty f) { return f; }
136 // expected-cpp-error@+2 {{cannot initialize return object of type 'pz_ptrty' (aka 'void (*)() __arm_preserves("za")') with an lvalue of type 'n_ptrty' (aka 'void (*)()')}}
137 // expected-error@+1 {{incompatible function pointer types returning 'n_ptrty' (aka 'void (*)(void)') from a function with result type 'pz_ptrty' (aka 'void (*)(void) __arm_preserves("za")')}}
138 pz_ptrty return_invalid_fptr_preserves_za_normal(n_ptrty f) { return f; }
139 // expected-cpp-error@+2 {{cannot initialize return object of type 'n_ptrty' (aka 'void (*)()') with an lvalue of type 'pz_ptrty' (aka 'void (*)() __arm_preserves("za")')}}
140 // expected-error@+1 {{incompatible function pointer types returning 'pz_ptrty' (aka 'void (*)(void) __arm_preserves("za")') from a function with result type 'n_ptrty' (aka 'void (*)(void)')}}
141 n_ptrty return_invalid_fptr_normal_preserves_za(pz_ptrty f) { return f; }
143 // Test template instantiations
144 #ifdef __cplusplus
145 template <typename T> T templated(T x) __arm_streaming { return x; }
146 template <> int templated<int>(int x) __arm_streaming { return x + 1; }
147 template <> float templated<float>(float x) __arm_streaming { return x + 2; }
148 // expected-cpp-error@+2 {{explicit instantiation of 'templated' does not refer to a function template, variable template, member function, member class, or static data member}}
149 // expected-cpp-note@-4 {{candidate template ignored: could not match 'short (short) __arm_streaming' against 'short (short)'}}
150 template short templated<short>(short);
151 #endif
153 // Conflicting attributes on redeclarations
155 // expected-error@+5 {{function declared 'void (void) __arm_streaming_compatible' was previously declared 'void (void) __arm_streaming', which has different SME function attributes}}
156 // expected-note@+3 {{previous declaration is here}}
157 // expected-cpp-error@+3 {{function declared 'void () __arm_streaming_compatible' was previously declared 'void () __arm_streaming', which has different SME function attributes}}
158 // expected-cpp-note@+1 {{previous declaration is here}}
159 void redecl(void) __arm_streaming;
160 void redecl(void) __arm_streaming_compatible { }
162 // expected-error@+5 {{function declared 'void (void)' was previously declared 'void (void) __arm_preserves("za")', which has different SME function attributes}}
163 // expected-note@+3 {{previous declaration is here}}
164 // expected-cpp-error@+3 {{function declared 'void ()' was previously declared 'void () __arm_preserves("za")', which has different SME function attributes}}
165 // expected-cpp-note@+1 {{previous declaration is here}}
166 void redecl_preserve_za(void) __arm_preserves("za");;
167 void redecl_preserve_za(void) {}
169 // expected-error@+5 {{function declared 'void (void) __arm_preserves("za")' was previously declared 'void (void)', which has different SME function attributes}}
170 // expected-note@+3 {{previous declaration is here}}
171 // expected-cpp-error@+3 {{function declared 'void () __arm_preserves("za")' was previously declared 'void ()', which has different SME function attributes}}
172 // expected-cpp-note@+1 {{previous declaration is here}}
173 void redecl_nopreserve_za(void);
174 void redecl_nopreserve_za(void) __arm_preserves("za") {}
176 void non_za_definition(void (*shared_za_fn_ptr)(void) __arm_inout("za"), void (*preserves_za_fn_ptr)(void) __arm_preserves("za")) {
177 sme_arm_new_za(); // OK
178 // expected-error@+2 {{call to a shared ZA function requires the caller to have ZA state}}
179 // expected-cpp-error@+1 {{call to a shared ZA function requires the caller to have ZA state}}
180 sme_arm_shared_za();
181 // expected-error@+2 {{call to a shared ZA function requires the caller to have ZA state}}
182 // expected-cpp-error@+1 {{call to a shared ZA function requires the caller to have ZA state}}
183 shared_za_fn_ptr();
184 // expected-error@+2 {{call to a shared ZA function requires the caller to have ZA state}}
185 // expected-cpp-error@+1 {{call to a shared ZA function requires the caller to have ZA state}}
186 preserves_za_fn_ptr();
189 void shared_za_definition(void (*shared_za_fn_ptr)(void) __arm_inout("za")) __arm_inout("za") {
190 sme_arm_shared_za(); // OK
191 shared_za_fn_ptr(); // OK
194 __arm_new("za") void new_za_definition(void (*shared_za_fn_ptr)(void) __arm_inout("za")) {
195 sme_arm_shared_za(); // OK
196 shared_za_fn_ptr(); // OK
199 #ifdef __cplusplus
200 int shared_za_initializer(void) __arm_inout("za");
201 // expected-cpp-error@+1 {{call to a shared ZA function requires the caller to have ZA state}}
202 int global = shared_za_initializer();
204 struct S {
205 virtual void shared_za_memberfn(void) __arm_inout("za");
208 struct S2 : public S {
209 // expected-cpp-error@+2 {{virtual function 'shared_za_memberfn' has different attributes ('void ()') than the function it overrides (which has 'void () __arm_inout("za")')}}
210 // expected-cpp-note@-5 {{overridden virtual function is here}}
211 __arm_new("za") void shared_za_memberfn(void) override {}
214 // The '__arm_preserves("za")' property cannot be dropped when overriding a virtual
215 // function. It is however fine for the overriding function to be '__arm_preserves("za")'
216 // even though the function that it overrides is not.
218 struct S_PreservesZA {
219 virtual void memberfn(void) __arm_preserves("za");
222 struct S_Drop_PreservesZA : S_PreservesZA {
223 // expected-cpp-error@+2 {{virtual function 'memberfn' has different attributes ('void ()') than the function it overrides (which has 'void () __arm_preserves("za")')}}
224 // expected-cpp-note@-5 {{overridden virtual function is here}}
225 void memberfn(void) override {}
228 struct S_NoPreservesZA {
229 virtual void memberfn(void);
232 struct S_AddPreservesZA : S_NoPreservesZA {
233 // expected-cpp-error@+2 {{virtual function 'memberfn' has different attributes ('void () __arm_preserves("za")') than the function it overrides (which has 'void ()')}}
234 // expected-cpp-note@-5 {{overridden virtual function is here}}
235 void memberfn(void) __arm_preserves("za") override {}
239 // Check that the attribute propagates through template instantiations.
240 template <typename Ty>
241 struct S3 {
242 static constexpr int value = 0;
245 template <>
246 struct S3<void (*)()> {
247 static constexpr int value = 1;
250 template <>
251 struct S3<void (* __arm_streaming)()> {
252 static constexpr int value = 2;
255 template <>
256 struct S3<void (* __arm_streaming_compatible)()> {
257 static constexpr int value = 4;
260 template <>
261 struct S3<void (* __arm_inout("za"))()> {
262 static constexpr int value = 8;
265 template <>
266 struct S3<void (* __arm_preserves("za"))()> {
267 static constexpr int value = 16;
270 void normal_func(void) {}
271 void streaming_func(void) __arm_streaming {}
272 void streaming_compatible_func(void) __arm_streaming_compatible {}
273 void shared_za_func(void) __arm_inout("za") {}
274 void preserves_za_func(void) __arm_preserves("za") {}
276 static_assert(S3<decltype(+normal_func)>::value == 1, "why are we picking the wrong specialization?");
277 static_assert(S3<decltype(+streaming_func)>::value == 2, "why are we picking the wrong specialization?");
278 static_assert(S3<decltype(+streaming_compatible_func)>::value == 4, "why are we picking the wrong specialization?");
279 static_assert(S3<decltype(+shared_za_func)>::value == 8, "why are we picking the wrong specialization?");
280 static_assert(S3<decltype(+preserves_za_func)>::value == 16, "why are we picking the wrong specialization?");
282 // Also test the attribute is propagated with variadic templates
283 constexpr int eval_variadic_template() { return 0; }
284 template <typename T, typename... Other>
285 constexpr int eval_variadic_template(T f, Other... other) {
286 return S3<decltype(f)>::value + eval_variadic_template(other...);
288 static_assert(eval_variadic_template(normal_func, streaming_func,
289 streaming_compatible_func,
290 shared_za_func, preserves_za_func) == 31,
291 "attributes not propagated properly in variadic template");
293 // Test that the attribute is propagated with template specialization.
294 template<typename T> int test_templated_f(T);
295 template<> constexpr int test_templated_f<void(*)(void)>(void(*)(void)) { return 1; }
296 template<> constexpr int test_templated_f<void(*)(void)__arm_streaming>(void(*)(void)__arm_streaming) { return 2; }
297 template<> constexpr int test_templated_f<void(*)(void)__arm_streaming_compatible>(void(*)(void)__arm_streaming_compatible) { return 4; }
298 template<> constexpr int test_templated_f<void(*)(void)__arm_inout("za")>(void(*)(void)__arm_inout("za")) { return 8; }
299 template<> constexpr int test_templated_f<void(*)(void)__arm_preserves("za")>(void(*)(void)__arm_preserves("za")) { return 16; }
301 static_assert(test_templated_f(&normal_func) == 1, "Instantiated to wrong function");
302 static_assert(test_templated_f(&streaming_func) == 2, "Instantiated to wrong function");
303 static_assert(test_templated_f(&streaming_compatible_func) == 4, "Instantiated to wrong function");
304 static_assert(test_templated_f(&shared_za_func) == 8, "Instantiated to wrong function");
305 static_assert(test_templated_f(&preserves_za_func) == 16, "Instantiated to wrong function");
307 // expected-cpp-error@+2 {{'__arm_streaming' only applies to function types; type here is 'int'}}
308 // expected-error@+1 {{'__arm_streaming' only applies to function types; type here is 'int'}}
309 int invalid_type_for_attribute __arm_streaming;
311 // Test overloads
312 constexpr int overload(void f(void)) { return 1; }
313 constexpr int overload(void f(void) __arm_streaming) { return 2; }
314 constexpr int overload(void f(void) __arm_streaming_compatible) { return 4; }
315 constexpr int overload(void f(void) __arm_inout("za")) { return 8; }
316 constexpr int overload(void f(void) __arm_preserves("za")) { return 16; }
317 static_assert(overload(&normal_func) == 1, "Overloaded to wrong function");
318 static_assert(overload(&streaming_func) == 2, "Overloaded to wrong function");
319 static_assert(overload(&streaming_compatible_func) == 4, "Overloaded to wrong function");
320 static_assert(overload(&shared_za_func) == 8, "Overloaded to wrong function");
321 static_assert(overload(&preserves_za_func) == 16, "Overloaded to wrong function");
323 // Test implicit instantiation
324 template <typename T> struct X {
325 static void foo(T) __arm_streaming { }
327 constexpr int overload_int(void f(int)) { return 1; }
328 constexpr int overload_int(void f(int) __arm_streaming) { return 2; }
329 constexpr X<int> *ptr = 0;
330 static_assert(overload_int(ptr->foo) == 2, "Overloaded to the wrong function after implicit instantiation");
332 #endif // ifdef __cplusplus
334 // expected-cpp-error@+2 {{unknown state ''}}
335 // expected-error@+1 {{unknown state ''}}
336 __arm_new("") void invalid_arm_new_empty_string(void);
337 // expected-cpp-error@+2 {{expected string literal as argument of '__arm_new' attribute}}
338 // expected-error@+1 {{expected string literal as argument of '__arm_new' attribute}}
339 __arm_new(0) void invalid_arm_new_non_literal_string(void);
340 // expected-cpp-error@+2 {{unknown state 'unknownstate'}}
341 // expected-error@+1 {{unknown state 'unknownstate'}}
342 __arm_new("unknownstate") void invalid_arm_new_unknown_state(void);
344 // expected-cpp-error@+2 {{unknown state ''}}
345 // expected-error@+1 {{unknown state ''}}
346 void invalid_arm_in_empty_string(void) __arm_in("");
347 // expected-cpp-error@+2 {{expected string literal as argument of '__arm_in' attribute}}
348 // expected-error@+1 {{expected string literal as argument of '__arm_in' attribute}}
349 void invalid_arm_in_non_literal_string(void) __arm_in(0);
350 // expected-cpp-error@+2 {{unknown state 'unknownstate'}}
351 // expected-error@+1 {{unknown state 'unknownstate'}}
352 void invalid_arm_in_unknown_state(void) __arm_in("unknownstate");
354 void valid_state_attrs_in_in1(void) __arm_in("za");
355 void valid_state_attrs_in_in2(void) __arm_in("za", "za");
356 void valid_state_attrs_in_in3(void) __arm_in("zt0");
357 void valid_state_attrs_in_in4(void) __arm_in("zt0", "zt0");
358 void valid_state_attrs_in_in5(void) __arm_in("za", "zt0");
359 __arm_new("za") void valid_state_attrs_in_in6(void) __arm_in("zt0");
360 __arm_new("zt0") void valid_state_attrs_in_in7(void) __arm_in("za");
362 // expected-cpp-error@+2 {{missing state for '__arm_in'}}
363 // expected-error@+1 {{missing state for '__arm_in'}}
364 void invalid_state_attrs_no_arg1(void) __arm_in();
365 // expected-cpp-error@+2 {{missing state for '__arm_new'}}
366 // expected-error@+1 {{missing state for '__arm_new'}}
367 __arm_new() void invalid_state_attrs_no_arg2(void);
369 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
370 // expected-error@+1 {{conflicting attributes for state 'za'}}
371 void conflicting_state_attrs_in_out(void) __arm_in("za") __arm_out("za");
372 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
373 // expected-error@+1 {{conflicting attributes for state 'za'}}
374 void conflicting_state_attrs_in_inout(void) __arm_in("za") __arm_inout("za");
375 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
376 // expected-error@+1 {{conflicting attributes for state 'za'}}
377 void conflicting_state_attrs_in_preserves(void) __arm_in("za") __arm_preserves("za");
379 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
380 // expected-error@+1 {{conflicting attributes for state 'za'}}
381 void conflicting_state_attrs_out_in(void) __arm_out("za") __arm_in("za");
382 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
383 // expected-error@+1 {{conflicting attributes for state 'za'}}
384 void conflicting_state_attrs_out_inout(void) __arm_out("za") __arm_inout("za");
385 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
386 // expected-error@+1 {{conflicting attributes for state 'za'}}
387 void conflicting_state_attrs_out_preserves(void) __arm_out("za") __arm_preserves("za");
389 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
390 // expected-error@+1 {{conflicting attributes for state 'za'}}
391 void conflicting_state_attrs_inout_in(void) __arm_inout("za") __arm_in("za");
392 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
393 // expected-error@+1 {{conflicting attributes for state 'za'}}
394 void conflicting_state_attrs_inout_out(void) __arm_inout("za") __arm_out("za");
395 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
396 // expected-error@+1 {{conflicting attributes for state 'za'}}
397 void conflicting_state_attrs_inout_preserves(void) __arm_inout("za") __arm_preserves("za");
399 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
400 // expected-error@+1 {{conflicting attributes for state 'za'}}
401 void conflicting_state_attrs_preserves_in(void) __arm_preserves("za") __arm_in("za");
402 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
403 // expected-error@+1 {{conflicting attributes for state 'za'}}
404 void conflicting_state_attrs_preserves_out(void) __arm_preserves("za") __arm_out("za");
405 // expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
406 // expected-error@+1 {{conflicting attributes for state 'za'}}
407 void conflicting_state_attrs_preserves_inout(void) __arm_preserves("za") __arm_inout("za");
409 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
410 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
411 void conflicting_state_attrs_in_out_zt0(void) __arm_in("zt0") __arm_out("zt0");
412 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
413 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
414 void conflicting_state_attrs_in_inout_zt0(void) __arm_in("zt0") __arm_inout("zt0");
415 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
416 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
417 void conflicting_state_attrs_in_preserves_zt0(void) __arm_in("zt0") __arm_preserves("zt0");
419 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
420 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
421 void conflicting_state_attrs_out_in_zt0(void) __arm_out("zt0") __arm_in("zt0");
422 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
423 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
424 void conflicting_state_attrs_out_inout_zt0(void) __arm_out("zt0") __arm_inout("zt0");
425 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
426 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
427 void conflicting_state_attrs_out_preserves_zt0(void) __arm_out("zt0") __arm_preserves("zt0");
429 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
430 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
431 void conflicting_state_attrs_inout_in_zt0(void) __arm_inout("zt0") __arm_in("zt0");
432 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
433 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
434 void conflicting_state_attrs_inout_out_zt0(void) __arm_inout("zt0") __arm_out("zt0");
435 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
436 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
437 void conflicting_state_attrs_inout_preserves_zt0(void) __arm_inout("zt0") __arm_preserves("zt0");
439 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
440 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
441 void conflicting_state_attrs_preserves_in_zt0(void) __arm_preserves("zt0") __arm_in("zt0");
442 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
443 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
444 void conflicting_state_attrs_preserves_out_zt0(void) __arm_preserves("zt0") __arm_out("zt0");
445 // expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
446 // expected-error@+1 {{conflicting attributes for state 'zt0'}}
447 void conflicting_state_attrs_preserves_inout_zt0(void) __arm_preserves("zt0") __arm_inout("zt0");
449 // Test that we get a diagnostic for unimplemented case.
450 void unimplemented_spill_fill_za(void (*share_zt0_only)(void) __arm_inout("zt0")) __arm_inout("za", "zt0") {
451 // expected-cpp-error@+4 {{call to a function that shares state other than 'za' from a function that has live 'za' state requires a spill/fill of ZA, which is not yet implemented}}
452 // expected-cpp-note@+3 {{add '__arm_preserves("za")' to the callee if it preserves ZA}}
453 // expected-error@+2 {{call to a function that shares state other than 'za' from a function that has live 'za' state requires a spill/fill of ZA, which is not yet implemented}}
454 // expected-note@+1 {{add '__arm_preserves("za")' to the callee if it preserves ZA}}
455 share_zt0_only();
458 void sme_streaming_with_vl_arg(__SVInt8_t a) __arm_streaming { }
460 __SVInt8_t sme_streaming_returns_vl(void) __arm_streaming { __SVInt8_t r; return r; }
462 void sme_streaming_compatible_with_vl_arg(__SVInt8_t a) __arm_streaming_compatible { }
464 __SVInt8_t sme_streaming_compatible_returns_vl(void) __arm_streaming_compatible { __SVInt8_t r; return r; }
466 void sme_no_streaming_with_vl_arg(__SVInt8_t a) { }
468 __SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; }
470 // expected-warning@+2 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
471 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
472 __arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
474 // expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
475 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
476 __arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; }
478 void sme_no_streaming_calling_streaming_with_vl_args() {
479 __SVInt8_t a;
480 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
481 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
482 sme_streaming_with_vl_arg(a);
485 void sme_no_streaming_calling_streaming_with_return_vl() {
486 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
487 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
488 __SVInt8_t r = sme_streaming_returns_vl();
491 void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming {
492 __SVInt8_t a;
493 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
494 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
495 sme_no_streaming_with_vl_arg(a);
498 void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming {
499 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
500 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
501 __SVInt8_t r = sme_no_streaming_returns_vl();
504 void sme_no_streaming_calling_streaming_with_vl_args_param(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) {
505 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
506 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
507 sc(arg);
510 __SVInt8_t sme_no_streaming_calling_streaming_return_vl_param(__SVInt8_t (*s)(void) __arm_streaming) {
511 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
512 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
513 return s();
516 void sme_streaming_compatible_calling_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible {
517 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
518 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
519 sme_streaming_with_vl_arg(arg);
522 void sme_streaming_compatible_calling_sme_streaming_return_vl(void) __arm_streaming_compatible {
523 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
524 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
525 __SVInt8_t r = sme_streaming_returns_vl();
528 void sme_streaming_compatible_calling_no_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible {
529 // expected-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
530 // expected-cpp-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
531 sme_no_streaming_with_vl_arg(arg);
534 void sme_streaming_compatible_calling_no_sme_streaming_return_vl(void) __arm_streaming_compatible {
535 // expected-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
536 // expected-cpp-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
537 __SVInt8_t r = sme_no_streaming_returns_vl();
540 void sme_streaming_calling_streaming(__SVInt8_t arg, void (*s)( __SVInt8_t arg) __arm_streaming) __arm_streaming {
541 s(arg);
544 __SVInt8_t sme_streaming_calling_streaming_return_vl(__SVInt8_t (*s)(void) __arm_streaming) __arm_streaming {
545 return s();
548 void sme_streaming_calling_streaming_with_vl_args(__SVInt8_t a) __arm_streaming {
549 sme_streaming_with_vl_arg(a);
552 void sme_streaming_calling_streaming_with_return_vl(void) __arm_streaming {
553 __SVInt8_t r = sme_streaming_returns_vl();
556 void sme_streaming_calling_streaming_compatible_with_vl_args(__SVInt8_t a) __arm_streaming {
557 sme_streaming_compatible_with_vl_arg(a);
560 void sme_streaming_calling_streaming_compatible_with_return_vl(void) __arm_streaming {
561 __SVInt8_t r = sme_streaming_compatible_returns_vl();
564 void sme_no_streaming_calling_streaming_compatible_with_vl_args() {
565 __SVInt8_t a;
566 sme_streaming_compatible_with_vl_arg(a);
569 void sme_no_streaming_calling_streaming_compatible_with_return_vl() {
570 __SVInt8_t r = sme_streaming_compatible_returns_vl();
573 void sme_no_streaming_calling_non_streaming_compatible_with_vl_args() {
574 __SVInt8_t a;
575 sme_no_streaming_with_vl_arg(a);
578 void sme_no_streaming_calling_non_streaming_compatible_with_return_vl() {
579 __SVInt8_t r = sme_no_streaming_returns_vl();
582 void sme_streaming_compatible_calling_streaming_compatible_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible {
583 sme_streaming_compatible_with_vl_arg(arg);
586 void sme_streaming_compatible_calling_streaming_compatible_with_return_vl(void) __arm_streaming_compatible {
587 __SVInt8_t r = sme_streaming_compatible_returns_vl();