xref: /llvm-project/llvm/unittests/Target/AArch64/SMEAttributesTest.cpp (revision d313614b60ff1194f48e5f0b1bb8d63d2b7eb52d)
1 #include "Utils/AArch64SMEAttributes.h"
2 #include "llvm/AsmParser/Parser.h"
3 #include "llvm/IR/Function.h"
4 #include "llvm/IR/Module.h"
5 #include "llvm/Support/SourceMgr.h"
6 
7 #include "gtest/gtest.h"
8 
9 using namespace llvm;
10 using SA = SMEAttrs;
11 
parseIR(const char * IR)12 std::unique_ptr<Module> parseIR(const char *IR) {
13   static LLVMContext C;
14   SMDiagnostic Err;
15   return parseAssemblyString(IR, Err, C);
16 }
17 
TEST(SMEAttributes,Constructors)18 TEST(SMEAttributes, Constructors) {
19   LLVMContext Context;
20 
21   ASSERT_TRUE(SA(*parseIR("declare void @foo()")->getFunction("foo"))
22                   .hasNonStreamingInterfaceAndBody());
23 
24   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")
25                       ->getFunction("foo"))
26                   .hasNonStreamingInterface());
27 
28   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_enabled\"")
29                       ->getFunction("foo"))
30                   .hasStreamingInterface());
31 
32   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")
33                       ->getFunction("foo"))
34                   .hasStreamingBody());
35 
36   ASSERT_TRUE(
37       SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_compatible\"")
38               ->getFunction("foo"))
39           .hasStreamingCompatibleInterface());
40 
41   ASSERT_TRUE(
42       SA(*parseIR("declare void @foo() \"aarch64_in_za\"")->getFunction("foo"))
43           .isInZA());
44   ASSERT_TRUE(
45       SA(*parseIR("declare void @foo() \"aarch64_out_za\"")->getFunction("foo"))
46           .isOutZA());
47   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_inout_za\"")
48                       ->getFunction("foo"))
49                   .isInOutZA());
50   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_preserves_za\"")
51                       ->getFunction("foo"))
52                   .isPreservesZA());
53   ASSERT_TRUE(
54       SA(*parseIR("declare void @foo() \"aarch64_new_za\"")->getFunction("foo"))
55           .isNewZA());
56 
57   ASSERT_TRUE(
58       SA(*parseIR("declare void @foo() \"aarch64_in_zt0\"")->getFunction("foo"))
59           .isInZT0());
60   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_out_zt0\"")
61                       ->getFunction("foo"))
62                   .isOutZT0());
63   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_inout_zt0\"")
64                       ->getFunction("foo"))
65                   .isInOutZT0());
66   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_preserves_zt0\"")
67                       ->getFunction("foo"))
68                   .isPreservesZT0());
69   ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_new_zt0\"")
70                       ->getFunction("foo"))
71                   .isNewZT0());
72 
73   // Invalid combinations.
74   EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled | SA::SM_Compatible),
75                      "SM_Enabled and SM_Compatible are mutually exclusive");
76 
77   // Test that the set() methods equally check validity.
78   EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled).set(SA::SM_Compatible),
79                      "SM_Enabled and SM_Compatible are mutually exclusive");
80   EXPECT_DEBUG_DEATH(SA(SA::SM_Compatible).set(SA::SM_Enabled),
81                      "SM_Enabled and SM_Compatible are mutually exclusive");
82 }
83 
TEST(SMEAttributes,Basics)84 TEST(SMEAttributes, Basics) {
85   // Test PSTATE.SM interfaces.
86   ASSERT_TRUE(SA(SA::Normal).hasNonStreamingInterfaceAndBody());
87   ASSERT_TRUE(SA(SA::SM_Enabled).hasStreamingInterface());
88   ASSERT_TRUE(SA(SA::SM_Body).hasStreamingBody());
89   ASSERT_TRUE(SA(SA::SM_Body).hasNonStreamingInterface());
90   ASSERT_FALSE(SA(SA::SM_Body).hasNonStreamingInterfaceAndBody());
91   ASSERT_FALSE(SA(SA::SM_Body).hasStreamingInterface());
92   ASSERT_TRUE(SA(SA::SM_Compatible).hasStreamingCompatibleInterface());
93   ASSERT_TRUE(
94       SA(SA::SM_Compatible | SA::SM_Body).hasStreamingCompatibleInterface());
95   ASSERT_TRUE(SA(SA::SM_Compatible | SA::SM_Body).hasStreamingBody());
96   ASSERT_FALSE(SA(SA::SM_Compatible | SA::SM_Body).hasNonStreamingInterface());
97 
98   // Test ZA State interfaces
99   SA ZA_In = SA(SA::encodeZAState(SA::StateValue::In));
100   ASSERT_TRUE(ZA_In.isInZA());
101   ASSERT_FALSE(ZA_In.isOutZA());
102   ASSERT_FALSE(ZA_In.isInOutZA());
103   ASSERT_FALSE(ZA_In.isPreservesZA());
104   ASSERT_FALSE(ZA_In.isNewZA());
105   ASSERT_TRUE(ZA_In.sharesZA());
106   ASSERT_TRUE(ZA_In.hasZAState());
107   ASSERT_TRUE(ZA_In.hasSharedZAInterface());
108   ASSERT_FALSE(ZA_In.hasPrivateZAInterface());
109 
110   SA ZA_Out = SA(SA::encodeZAState(SA::StateValue::Out));
111   ASSERT_TRUE(ZA_Out.isOutZA());
112   ASSERT_FALSE(ZA_Out.isInZA());
113   ASSERT_FALSE(ZA_Out.isInOutZA());
114   ASSERT_FALSE(ZA_Out.isPreservesZA());
115   ASSERT_FALSE(ZA_Out.isNewZA());
116   ASSERT_TRUE(ZA_Out.sharesZA());
117   ASSERT_TRUE(ZA_Out.hasZAState());
118   ASSERT_TRUE(ZA_Out.hasSharedZAInterface());
119   ASSERT_FALSE(ZA_Out.hasPrivateZAInterface());
120 
121   SA ZA_InOut = SA(SA::encodeZAState(SA::StateValue::InOut));
122   ASSERT_TRUE(ZA_InOut.isInOutZA());
123   ASSERT_FALSE(ZA_InOut.isInZA());
124   ASSERT_FALSE(ZA_InOut.isOutZA());
125   ASSERT_FALSE(ZA_InOut.isPreservesZA());
126   ASSERT_FALSE(ZA_InOut.isNewZA());
127   ASSERT_TRUE(ZA_InOut.sharesZA());
128   ASSERT_TRUE(ZA_InOut.hasZAState());
129   ASSERT_TRUE(ZA_InOut.hasSharedZAInterface());
130   ASSERT_FALSE(ZA_InOut.hasPrivateZAInterface());
131 
132   SA ZA_Preserved = SA(SA::encodeZAState(SA::StateValue::Preserved));
133   ASSERT_TRUE(ZA_Preserved.isPreservesZA());
134   ASSERT_FALSE(ZA_Preserved.isInZA());
135   ASSERT_FALSE(ZA_Preserved.isOutZA());
136   ASSERT_FALSE(ZA_Preserved.isInOutZA());
137   ASSERT_FALSE(ZA_Preserved.isNewZA());
138   ASSERT_TRUE(ZA_Preserved.sharesZA());
139   ASSERT_TRUE(ZA_Preserved.hasZAState());
140   ASSERT_TRUE(ZA_Preserved.hasSharedZAInterface());
141   ASSERT_FALSE(ZA_Preserved.hasPrivateZAInterface());
142 
143   SA ZA_New = SA(SA::encodeZAState(SA::StateValue::New));
144   ASSERT_TRUE(ZA_New.isNewZA());
145   ASSERT_FALSE(ZA_New.isInZA());
146   ASSERT_FALSE(ZA_New.isOutZA());
147   ASSERT_FALSE(ZA_New.isInOutZA());
148   ASSERT_FALSE(ZA_New.isPreservesZA());
149   ASSERT_FALSE(ZA_New.sharesZA());
150   ASSERT_TRUE(ZA_New.hasZAState());
151   ASSERT_FALSE(ZA_New.hasSharedZAInterface());
152   ASSERT_TRUE(ZA_New.hasPrivateZAInterface());
153 
154   ASSERT_FALSE(SA(SA::Normal).isInZA());
155   ASSERT_FALSE(SA(SA::Normal).isOutZA());
156   ASSERT_FALSE(SA(SA::Normal).isInOutZA());
157   ASSERT_FALSE(SA(SA::Normal).isPreservesZA());
158   ASSERT_FALSE(SA(SA::Normal).isNewZA());
159   ASSERT_FALSE(SA(SA::Normal).sharesZA());
160   ASSERT_FALSE(SA(SA::Normal).hasZAState());
161 
162   // Test ZT0 State interfaces
163   SA ZT0_In = SA(SA::encodeZT0State(SA::StateValue::In));
164   ASSERT_TRUE(ZT0_In.isInZT0());
165   ASSERT_FALSE(ZT0_In.isOutZT0());
166   ASSERT_FALSE(ZT0_In.isInOutZT0());
167   ASSERT_FALSE(ZT0_In.isPreservesZT0());
168   ASSERT_FALSE(ZT0_In.isNewZT0());
169   ASSERT_TRUE(ZT0_In.sharesZT0());
170   ASSERT_TRUE(ZT0_In.hasZT0State());
171   ASSERT_TRUE(ZT0_In.hasSharedZAInterface());
172   ASSERT_FALSE(ZT0_In.hasPrivateZAInterface());
173 
174   SA ZT0_Out = SA(SA::encodeZT0State(SA::StateValue::Out));
175   ASSERT_TRUE(ZT0_Out.isOutZT0());
176   ASSERT_FALSE(ZT0_Out.isInZT0());
177   ASSERT_FALSE(ZT0_Out.isInOutZT0());
178   ASSERT_FALSE(ZT0_Out.isPreservesZT0());
179   ASSERT_FALSE(ZT0_Out.isNewZT0());
180   ASSERT_TRUE(ZT0_Out.sharesZT0());
181   ASSERT_TRUE(ZT0_Out.hasZT0State());
182   ASSERT_TRUE(ZT0_Out.hasSharedZAInterface());
183   ASSERT_FALSE(ZT0_Out.hasPrivateZAInterface());
184 
185   SA ZT0_InOut = SA(SA::encodeZT0State(SA::StateValue::InOut));
186   ASSERT_TRUE(ZT0_InOut.isInOutZT0());
187   ASSERT_FALSE(ZT0_InOut.isInZT0());
188   ASSERT_FALSE(ZT0_InOut.isOutZT0());
189   ASSERT_FALSE(ZT0_InOut.isPreservesZT0());
190   ASSERT_FALSE(ZT0_InOut.isNewZT0());
191   ASSERT_TRUE(ZT0_InOut.sharesZT0());
192   ASSERT_TRUE(ZT0_InOut.hasZT0State());
193   ASSERT_TRUE(ZT0_InOut.hasSharedZAInterface());
194   ASSERT_FALSE(ZT0_InOut.hasPrivateZAInterface());
195 
196   SA ZT0_Preserved = SA(SA::encodeZT0State(SA::StateValue::Preserved));
197   ASSERT_TRUE(ZT0_Preserved.isPreservesZT0());
198   ASSERT_FALSE(ZT0_Preserved.isInZT0());
199   ASSERT_FALSE(ZT0_Preserved.isOutZT0());
200   ASSERT_FALSE(ZT0_Preserved.isInOutZT0());
201   ASSERT_FALSE(ZT0_Preserved.isNewZT0());
202   ASSERT_TRUE(ZT0_Preserved.sharesZT0());
203   ASSERT_TRUE(ZT0_Preserved.hasZT0State());
204   ASSERT_TRUE(ZT0_Preserved.hasSharedZAInterface());
205   ASSERT_FALSE(ZT0_Preserved.hasPrivateZAInterface());
206 
207   SA ZT0_New = SA(SA::encodeZT0State(SA::StateValue::New));
208   ASSERT_TRUE(ZT0_New.isNewZT0());
209   ASSERT_FALSE(ZT0_New.isInZT0());
210   ASSERT_FALSE(ZT0_New.isOutZT0());
211   ASSERT_FALSE(ZT0_New.isInOutZT0());
212   ASSERT_FALSE(ZT0_New.isPreservesZT0());
213   ASSERT_FALSE(ZT0_New.sharesZT0());
214   ASSERT_TRUE(ZT0_New.hasZT0State());
215   ASSERT_FALSE(ZT0_New.hasSharedZAInterface());
216   ASSERT_TRUE(ZT0_New.hasPrivateZAInterface());
217 
218   ASSERT_FALSE(SA(SA::Normal).isInZT0());
219   ASSERT_FALSE(SA(SA::Normal).isOutZT0());
220   ASSERT_FALSE(SA(SA::Normal).isInOutZT0());
221   ASSERT_FALSE(SA(SA::Normal).isPreservesZT0());
222   ASSERT_FALSE(SA(SA::Normal).isNewZT0());
223   ASSERT_FALSE(SA(SA::Normal).sharesZT0());
224   ASSERT_FALSE(SA(SA::Normal).hasZT0State());
225 }
226 
TEST(SMEAttributes,Transitions)227 TEST(SMEAttributes, Transitions) {
228   // Normal -> Normal
229   ASSERT_FALSE(SA(SA::Normal).requiresSMChange(SA(SA::Normal)));
230   ASSERT_FALSE(SA(SA::Normal).requiresPreservingZT0(SA(SA::Normal)));
231   ASSERT_FALSE(SA(SA::Normal).requiresDisablingZABeforeCall(SA(SA::Normal)));
232   ASSERT_FALSE(SA(SA::Normal).requiresEnablingZAAfterCall(SA(SA::Normal)));
233   // Normal -> Normal + LocallyStreaming
234   ASSERT_FALSE(SA(SA::Normal).requiresSMChange(SA(SA::Normal | SA::SM_Body)));
235 
236   // Normal -> Streaming
237   ASSERT_TRUE(SA(SA::Normal).requiresSMChange(SA(SA::SM_Enabled)));
238   // Normal -> Streaming + LocallyStreaming
239   ASSERT_TRUE(
240       SA(SA::Normal).requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body)));
241 
242   // Normal -> Streaming-compatible
243   ASSERT_FALSE(SA(SA::Normal).requiresSMChange(SA(SA::SM_Compatible)));
244   // Normal -> Streaming-compatible + LocallyStreaming
245   ASSERT_FALSE(
246       SA(SA::Normal).requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body)));
247 
248   // Streaming -> Normal
249   ASSERT_TRUE(SA(SA::SM_Enabled).requiresSMChange(SA(SA::Normal)));
250   // Streaming -> Normal + LocallyStreaming
251   ASSERT_TRUE(
252       SA(SA::SM_Enabled).requiresSMChange(SA(SA::Normal | SA::SM_Body)));
253 
254   // Streaming -> Streaming
255   ASSERT_FALSE(SA(SA::SM_Enabled).requiresSMChange(SA(SA::SM_Enabled)));
256   // Streaming -> Streaming + LocallyStreaming
257   ASSERT_FALSE(
258       SA(SA::SM_Enabled).requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body)));
259 
260   // Streaming -> Streaming-compatible
261   ASSERT_FALSE(SA(SA::SM_Enabled).requiresSMChange(SA(SA::SM_Compatible)));
262   // Streaming -> Streaming-compatible + LocallyStreaming
263   ASSERT_FALSE(
264       SA(SA::SM_Enabled).requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body)));
265 
266   // Streaming-compatible -> Normal
267   ASSERT_TRUE(SA(SA::SM_Compatible).requiresSMChange(SA(SA::Normal)));
268   ASSERT_TRUE(
269       SA(SA::SM_Compatible).requiresSMChange(SA(SA::Normal | SA::SM_Body)));
270 
271   // Streaming-compatible -> Streaming
272   ASSERT_TRUE(SA(SA::SM_Compatible).requiresSMChange(SA(SA::SM_Enabled)));
273   // Streaming-compatible -> Streaming + LocallyStreaming
274   ASSERT_TRUE(
275       SA(SA::SM_Compatible).requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body)));
276 
277   // Streaming-compatible -> Streaming-compatible
278   ASSERT_FALSE(SA(SA::SM_Compatible).requiresSMChange(SA(SA::SM_Compatible)));
279   // Streaming-compatible -> Streaming-compatible + LocallyStreaming
280   ASSERT_FALSE(SA(SA::SM_Compatible)
281                    .requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body)));
282 
283   SA Private_ZA = SA(SA::Normal);
284   SA ZA_Shared = SA(SA::encodeZAState(SA::StateValue::In));
285   SA ZT0_Shared = SA(SA::encodeZT0State(SA::StateValue::In));
286   SA ZA_ZT0_Shared = SA(SA::encodeZAState(SA::StateValue::In) |
287                         SA::encodeZT0State(SA::StateValue::In));
288 
289   // Shared ZA -> Private ZA Interface
290   ASSERT_FALSE(ZA_Shared.requiresDisablingZABeforeCall(Private_ZA));
291   ASSERT_TRUE(ZA_Shared.requiresEnablingZAAfterCall(Private_ZA));
292 
293   // Shared ZT0 -> Private ZA Interface
294   ASSERT_TRUE(ZT0_Shared.requiresDisablingZABeforeCall(Private_ZA));
295   ASSERT_TRUE(ZT0_Shared.requiresPreservingZT0(Private_ZA));
296   ASSERT_TRUE(ZT0_Shared.requiresEnablingZAAfterCall(Private_ZA));
297 
298   // Shared ZA & ZT0 -> Private ZA Interface
299   ASSERT_FALSE(ZA_ZT0_Shared.requiresDisablingZABeforeCall(Private_ZA));
300   ASSERT_TRUE(ZA_ZT0_Shared.requiresPreservingZT0(Private_ZA));
301   ASSERT_TRUE(ZA_ZT0_Shared.requiresEnablingZAAfterCall(Private_ZA));
302 
303   // Shared ZA -> Shared ZA Interface
304   ASSERT_FALSE(ZA_Shared.requiresDisablingZABeforeCall(ZT0_Shared));
305   ASSERT_FALSE(ZA_Shared.requiresEnablingZAAfterCall(ZT0_Shared));
306 
307   // Shared ZT0 -> Shared ZA Interface
308   ASSERT_FALSE(ZT0_Shared.requiresDisablingZABeforeCall(ZT0_Shared));
309   ASSERT_FALSE(ZT0_Shared.requiresPreservingZT0(ZT0_Shared));
310   ASSERT_FALSE(ZT0_Shared.requiresEnablingZAAfterCall(ZT0_Shared));
311 
312   // Shared ZA & ZT0 -> Shared ZA Interface
313   ASSERT_FALSE(ZA_ZT0_Shared.requiresDisablingZABeforeCall(ZT0_Shared));
314   ASSERT_FALSE(ZA_ZT0_Shared.requiresPreservingZT0(ZT0_Shared));
315   ASSERT_FALSE(ZA_ZT0_Shared.requiresEnablingZAAfterCall(ZT0_Shared));
316 }
317