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"
7 #include "gtest/gtest.h"
12 std::unique_ptr
<Module
> parseIR(const char *IR
) {
15 return parseAssemblyString(IR
, Err
, C
);
18 TEST(SMEAttributes
, Constructors
) {
21 ASSERT_TRUE(SA(*parseIR("declare void @foo()")->getFunction("foo"))
22 .hasNonStreamingInterfaceAndBody());
24 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")
26 .hasNonStreamingInterface());
28 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_enabled\"")
30 .hasStreamingInterface());
32 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")
37 SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_compatible\"")
39 .hasStreamingCompatibleInterface());
41 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_shared\"")
43 .hasSharedZAInterface());
45 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_new\"")
49 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_preserved\"")
53 // Invalid combinations.
54 EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled
| SA::SM_Compatible
),
55 "SM_Enabled and SM_Compatible are mutually exclusive");
56 EXPECT_DEBUG_DEATH(SA(SA::ZA_New
| SA::ZA_Shared
),
57 "ZA_New and ZA_Shared are mutually exclusive");
58 EXPECT_DEBUG_DEATH(SA(SA::ZA_New
| SA::ZA_Preserved
),
59 "ZA_New and ZA_Preserved are mutually exclusive");
61 // Test that the set() methods equally check validity.
62 EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled
).set(SA::SM_Compatible
),
63 "SM_Enabled and SM_Compatible are mutually exclusive");
64 EXPECT_DEBUG_DEATH(SA(SA::SM_Compatible
).set(SA::SM_Enabled
),
65 "SM_Enabled and SM_Compatible are mutually exclusive");
68 TEST(SMEAttributes
, Basics
) {
69 // Test PSTATE.SM interfaces.
70 ASSERT_TRUE(SA(SA::Normal
).hasNonStreamingInterfaceAndBody());
71 ASSERT_TRUE(SA(SA::SM_Enabled
).hasStreamingInterface());
72 ASSERT_TRUE(SA(SA::SM_Body
).hasStreamingBody());
73 ASSERT_TRUE(SA(SA::SM_Body
).hasNonStreamingInterface());
74 ASSERT_FALSE(SA(SA::SM_Body
).hasNonStreamingInterfaceAndBody());
75 ASSERT_FALSE(SA(SA::SM_Body
).hasStreamingInterface());
76 ASSERT_TRUE(SA(SA::SM_Compatible
).hasStreamingCompatibleInterface());
78 SA(SA::SM_Compatible
| SA::SM_Body
).hasStreamingCompatibleInterface());
79 ASSERT_TRUE(SA(SA::SM_Compatible
| SA::SM_Body
).hasStreamingBody());
80 ASSERT_FALSE(SA(SA::SM_Compatible
| SA::SM_Body
).hasNonStreamingInterface());
82 // Test PSTATE.ZA interfaces.
83 ASSERT_FALSE(SA(SA::ZA_Shared
).hasPrivateZAInterface());
84 ASSERT_TRUE(SA(SA::ZA_Shared
).hasSharedZAInterface());
85 ASSERT_TRUE(SA(SA::ZA_Shared
).hasZAState());
86 ASSERT_FALSE(SA(SA::ZA_Shared
).preservesZA());
87 ASSERT_TRUE(SA(SA::ZA_Shared
| SA::ZA_Preserved
).preservesZA());
89 ASSERT_TRUE(SA(SA::ZA_New
).hasPrivateZAInterface());
90 ASSERT_TRUE(SA(SA::ZA_New
).hasNewZABody());
91 ASSERT_TRUE(SA(SA::ZA_New
).hasZAState());
92 ASSERT_FALSE(SA(SA::ZA_New
).preservesZA());
94 ASSERT_TRUE(SA(SA::Normal
).hasPrivateZAInterface());
95 ASSERT_FALSE(SA(SA::Normal
).hasNewZABody());
96 ASSERT_FALSE(SA(SA::Normal
).hasZAState());
97 ASSERT_FALSE(SA(SA::Normal
).preservesZA());
100 TEST(SMEAttributes
, Transitions
) {
102 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::Normal
)));
103 // Normal -> Normal + LocallyStreaming
104 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)));
105 ASSERT_EQ(*SA(SA::Normal
)
106 .requiresSMChange(SA(SA::Normal
| SA::SM_Body
),
107 /*BodyOverridesInterface=*/true),
110 // Normal -> Streaming
111 ASSERT_EQ(*SA(SA::Normal
).requiresSMChange(SA(SA::SM_Enabled
)), true);
112 // Normal -> Streaming + LocallyStreaming
113 ASSERT_EQ(*SA(SA::Normal
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)),
115 ASSERT_EQ(*SA(SA::Normal
)
116 .requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
),
117 /*BodyOverridesInterface=*/true),
120 // Normal -> Streaming-compatible
121 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::SM_Compatible
)));
122 // Normal -> Streaming-compatible + LocallyStreaming
124 SA(SA::Normal
).requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
125 ASSERT_EQ(*SA(SA::Normal
)
126 .requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
),
127 /*BodyOverridesInterface=*/true),
130 // Streaming -> Normal
131 ASSERT_EQ(*SA(SA::SM_Enabled
).requiresSMChange(SA(SA::Normal
)), false);
132 // Streaming -> Normal + LocallyStreaming
133 ASSERT_EQ(*SA(SA::SM_Enabled
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)),
135 ASSERT_FALSE(SA(SA::SM_Enabled
)
136 .requiresSMChange(SA(SA::Normal
| SA::SM_Body
),
137 /*BodyOverridesInterface=*/true));
139 // Streaming -> Streaming
140 ASSERT_FALSE(SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Enabled
)));
141 // Streaming -> Streaming + LocallyStreaming
143 SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)));
144 ASSERT_FALSE(SA(SA::SM_Enabled
)
145 .requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
),
146 /*BodyOverridesInterface=*/true));
148 // Streaming -> Streaming-compatible
149 ASSERT_FALSE(SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Compatible
)));
150 // Streaming -> Streaming-compatible + LocallyStreaming
152 SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
153 ASSERT_FALSE(SA(SA::SM_Enabled
)
154 .requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
),
155 /*BodyOverridesInterface=*/true));
157 // Streaming-compatible -> Normal
158 ASSERT_EQ(*SA(SA::SM_Compatible
).requiresSMChange(SA(SA::Normal
)), false);
160 *SA(SA::SM_Compatible
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)),
162 ASSERT_EQ(*SA(SA::SM_Compatible
)
163 .requiresSMChange(SA(SA::Normal
| SA::SM_Body
),
164 /*BodyOverridesInterface=*/true),
167 // Streaming-compatible -> Streaming
168 ASSERT_EQ(*SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Enabled
)), true);
169 // Streaming-compatible -> Streaming + LocallyStreaming
171 *SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)),
173 ASSERT_EQ(*SA(SA::SM_Compatible
)
174 .requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
),
175 /*BodyOverridesInterface=*/true),
178 // Streaming-compatible -> Streaming-compatible
179 ASSERT_FALSE(SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Compatible
)));
180 // Streaming-compatible -> Streaming-compatible + LocallyStreaming
181 ASSERT_FALSE(SA(SA::SM_Compatible
)
182 .requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
183 ASSERT_EQ(*SA(SA::SM_Compatible
)
184 .requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
),
185 /*BodyOverridesInterface=*/true),