brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.0 KiB · 595dcd2 Raw
347 lines · cpp
1#include "AArch64SMEAttributes.h"2#include "llvm/AsmParser/Parser.h"3#include "llvm/IR/Function.h"4#include "llvm/IR/InstrTypes.h"5#include "llvm/IR/Module.h"6#include "llvm/Support/SourceMgr.h"7 8#include "gtest/gtest.h"9 10using namespace llvm;11using SA = SMEAttrs;12using CA = SMECallAttrs;13 14std::unique_ptr<Module> parseIR(const char *IR) {15  static LLVMContext C;16  SMDiagnostic Err;17  return parseAssemblyString(IR, Err, C);18}19 20TEST(SMEAttributes, Constructors) {21  LLVMContext Context;22 23  ASSERT_TRUE(SA(*parseIR("declare void @foo()")->getFunction("foo"))24                  .hasNonStreamingInterfaceAndBody());25 26  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")27                      ->getFunction("foo"))28                  .hasNonStreamingInterface());29 30  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_enabled\"")31                      ->getFunction("foo"))32                  .hasStreamingInterface());33 34  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")35                      ->getFunction("foo"))36                  .hasStreamingBody());37 38  ASSERT_TRUE(39      SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_compatible\"")40              ->getFunction("foo"))41          .hasStreamingCompatibleInterface());42 43  ASSERT_TRUE(44      SA(*parseIR("declare void @foo() \"aarch64_in_za\"")->getFunction("foo"))45          .isInZA());46  ASSERT_TRUE(47      SA(*parseIR("declare void @foo() \"aarch64_out_za\"")->getFunction("foo"))48          .isOutZA());49  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_inout_za\"")50                      ->getFunction("foo"))51                  .isInOutZA());52  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_preserves_za\"")53                      ->getFunction("foo"))54                  .isPreservesZA());55  ASSERT_TRUE(56      SA(*parseIR("declare void @foo() \"aarch64_new_za\"")->getFunction("foo"))57          .isNewZA());58 59  ASSERT_TRUE(60      SA(*parseIR("declare void @foo() \"aarch64_in_zt0\"")->getFunction("foo"))61          .isInZT0());62  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_out_zt0\"")63                      ->getFunction("foo"))64                  .isOutZT0());65  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_inout_zt0\"")66                      ->getFunction("foo"))67                  .isInOutZT0());68  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_preserves_zt0\"")69                      ->getFunction("foo"))70                  .isPreservesZT0());71  ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_new_zt0\"")72                      ->getFunction("foo"))73                  .isNewZT0());74 75  auto CallModule = parseIR("declare void @callee()\n"76                            "define void @foo() {"77                            "call void @callee() \"aarch64_zt0_undef\"\n"78                            "ret void\n}");79  CallBase &Call =80      cast<CallBase>((CallModule->getFunction("foo")->begin()->front()));81  ASSERT_TRUE(SMECallAttrs(Call, nullptr).callsite().hasUndefZT0());82 83  // Invalid combinations.84  EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled | SA::SM_Compatible),85                     "SM_Enabled and SM_Compatible are mutually exclusive");86 87  // Test that the set() methods equally check validity.88  EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled).set(SA::SM_Compatible),89                     "SM_Enabled and SM_Compatible are mutually exclusive");90  EXPECT_DEBUG_DEATH(SA(SA::SM_Compatible).set(SA::SM_Enabled),91                     "SM_Enabled and SM_Compatible are mutually exclusive");92}93 94TEST(SMEAttributes, Basics) {95  // Test PSTATE.SM interfaces.96  ASSERT_TRUE(SA(SA::Normal).hasNonStreamingInterfaceAndBody());97  ASSERT_TRUE(SA(SA::SM_Enabled).hasStreamingInterface());98  ASSERT_TRUE(SA(SA::SM_Body).hasStreamingBody());99  ASSERT_TRUE(SA(SA::SM_Body).hasNonStreamingInterface());100  ASSERT_FALSE(SA(SA::SM_Body).hasNonStreamingInterfaceAndBody());101  ASSERT_FALSE(SA(SA::SM_Body).hasStreamingInterface());102  ASSERT_TRUE(SA(SA::SM_Compatible).hasStreamingCompatibleInterface());103  ASSERT_TRUE(104      SA(SA::SM_Compatible | SA::SM_Body).hasStreamingCompatibleInterface());105  ASSERT_TRUE(SA(SA::SM_Compatible | SA::SM_Body).hasStreamingBody());106  ASSERT_FALSE(SA(SA::SM_Compatible | SA::SM_Body).hasNonStreamingInterface());107 108  // Test ZA State interfaces109  SA ZA_In = SA(SA::encodeZAState(SA::StateValue::In));110  ASSERT_TRUE(ZA_In.isInZA());111  ASSERT_FALSE(ZA_In.isOutZA());112  ASSERT_FALSE(ZA_In.isInOutZA());113  ASSERT_FALSE(ZA_In.isPreservesZA());114  ASSERT_FALSE(ZA_In.isNewZA());115  ASSERT_TRUE(ZA_In.sharesZA());116  ASSERT_TRUE(ZA_In.hasZAState());117  ASSERT_TRUE(ZA_In.hasSharedZAInterface());118  ASSERT_FALSE(ZA_In.hasPrivateZAInterface());119 120  SA ZA_Out = SA(SA::encodeZAState(SA::StateValue::Out));121  ASSERT_TRUE(ZA_Out.isOutZA());122  ASSERT_FALSE(ZA_Out.isInZA());123  ASSERT_FALSE(ZA_Out.isInOutZA());124  ASSERT_FALSE(ZA_Out.isPreservesZA());125  ASSERT_FALSE(ZA_Out.isNewZA());126  ASSERT_TRUE(ZA_Out.sharesZA());127  ASSERT_TRUE(ZA_Out.hasZAState());128  ASSERT_TRUE(ZA_Out.hasSharedZAInterface());129  ASSERT_FALSE(ZA_Out.hasPrivateZAInterface());130 131  SA ZA_InOut = SA(SA::encodeZAState(SA::StateValue::InOut));132  ASSERT_TRUE(ZA_InOut.isInOutZA());133  ASSERT_FALSE(ZA_InOut.isInZA());134  ASSERT_FALSE(ZA_InOut.isOutZA());135  ASSERT_FALSE(ZA_InOut.isPreservesZA());136  ASSERT_FALSE(ZA_InOut.isNewZA());137  ASSERT_TRUE(ZA_InOut.sharesZA());138  ASSERT_TRUE(ZA_InOut.hasZAState());139  ASSERT_TRUE(ZA_InOut.hasSharedZAInterface());140  ASSERT_FALSE(ZA_InOut.hasPrivateZAInterface());141 142  SA ZA_Preserved = SA(SA::encodeZAState(SA::StateValue::Preserved));143  ASSERT_TRUE(ZA_Preserved.isPreservesZA());144  ASSERT_FALSE(ZA_Preserved.isInZA());145  ASSERT_FALSE(ZA_Preserved.isOutZA());146  ASSERT_FALSE(ZA_Preserved.isInOutZA());147  ASSERT_FALSE(ZA_Preserved.isNewZA());148  ASSERT_TRUE(ZA_Preserved.sharesZA());149  ASSERT_TRUE(ZA_Preserved.hasZAState());150  ASSERT_TRUE(ZA_Preserved.hasSharedZAInterface());151  ASSERT_FALSE(ZA_Preserved.hasPrivateZAInterface());152 153  SA ZA_New = SA(SA::encodeZAState(SA::StateValue::New));154  ASSERT_TRUE(ZA_New.isNewZA());155  ASSERT_FALSE(ZA_New.isInZA());156  ASSERT_FALSE(ZA_New.isOutZA());157  ASSERT_FALSE(ZA_New.isInOutZA());158  ASSERT_FALSE(ZA_New.isPreservesZA());159  ASSERT_FALSE(ZA_New.sharesZA());160  ASSERT_TRUE(ZA_New.hasZAState());161  ASSERT_FALSE(ZA_New.hasSharedZAInterface());162  ASSERT_TRUE(ZA_New.hasPrivateZAInterface());163 164  ASSERT_FALSE(SA(SA::Normal).isInZA());165  ASSERT_FALSE(SA(SA::Normal).isOutZA());166  ASSERT_FALSE(SA(SA::Normal).isInOutZA());167  ASSERT_FALSE(SA(SA::Normal).isPreservesZA());168  ASSERT_FALSE(SA(SA::Normal).isNewZA());169  ASSERT_FALSE(SA(SA::Normal).sharesZA());170  ASSERT_FALSE(SA(SA::Normal).hasZAState());171 172  // Test ZT0 State interfaces173  SA ZT0_In = SA(SA::encodeZT0State(SA::StateValue::In));174  ASSERT_TRUE(ZT0_In.isInZT0());175  ASSERT_FALSE(ZT0_In.isOutZT0());176  ASSERT_FALSE(ZT0_In.isInOutZT0());177  ASSERT_FALSE(ZT0_In.isPreservesZT0());178  ASSERT_FALSE(ZT0_In.isNewZT0());179  ASSERT_TRUE(ZT0_In.sharesZT0());180  ASSERT_TRUE(ZT0_In.hasZT0State());181  ASSERT_TRUE(ZT0_In.hasSharedZAInterface());182  ASSERT_FALSE(ZT0_In.hasPrivateZAInterface());183 184  SA ZT0_Out = SA(SA::encodeZT0State(SA::StateValue::Out));185  ASSERT_TRUE(ZT0_Out.isOutZT0());186  ASSERT_FALSE(ZT0_Out.isInZT0());187  ASSERT_FALSE(ZT0_Out.isInOutZT0());188  ASSERT_FALSE(ZT0_Out.isPreservesZT0());189  ASSERT_FALSE(ZT0_Out.isNewZT0());190  ASSERT_TRUE(ZT0_Out.sharesZT0());191  ASSERT_TRUE(ZT0_Out.hasZT0State());192  ASSERT_TRUE(ZT0_Out.hasSharedZAInterface());193  ASSERT_FALSE(ZT0_Out.hasPrivateZAInterface());194 195  SA ZT0_InOut = SA(SA::encodeZT0State(SA::StateValue::InOut));196  ASSERT_TRUE(ZT0_InOut.isInOutZT0());197  ASSERT_FALSE(ZT0_InOut.isInZT0());198  ASSERT_FALSE(ZT0_InOut.isOutZT0());199  ASSERT_FALSE(ZT0_InOut.isPreservesZT0());200  ASSERT_FALSE(ZT0_InOut.isNewZT0());201  ASSERT_TRUE(ZT0_InOut.sharesZT0());202  ASSERT_TRUE(ZT0_InOut.hasZT0State());203  ASSERT_TRUE(ZT0_InOut.hasSharedZAInterface());204  ASSERT_FALSE(ZT0_InOut.hasPrivateZAInterface());205 206  SA ZT0_Preserved = SA(SA::encodeZT0State(SA::StateValue::Preserved));207  ASSERT_TRUE(ZT0_Preserved.isPreservesZT0());208  ASSERT_FALSE(ZT0_Preserved.isInZT0());209  ASSERT_FALSE(ZT0_Preserved.isOutZT0());210  ASSERT_FALSE(ZT0_Preserved.isInOutZT0());211  ASSERT_FALSE(ZT0_Preserved.isNewZT0());212  ASSERT_TRUE(ZT0_Preserved.sharesZT0());213  ASSERT_TRUE(ZT0_Preserved.hasZT0State());214  ASSERT_TRUE(ZT0_Preserved.hasSharedZAInterface());215  ASSERT_FALSE(ZT0_Preserved.hasPrivateZAInterface());216 217  SA ZT0_New = SA(SA::encodeZT0State(SA::StateValue::New));218  ASSERT_TRUE(ZT0_New.isNewZT0());219  ASSERT_FALSE(ZT0_New.isInZT0());220  ASSERT_FALSE(ZT0_New.isOutZT0());221  ASSERT_FALSE(ZT0_New.isInOutZT0());222  ASSERT_FALSE(ZT0_New.isPreservesZT0());223  ASSERT_FALSE(ZT0_New.sharesZT0());224  ASSERT_TRUE(ZT0_New.hasZT0State());225  ASSERT_FALSE(ZT0_New.hasSharedZAInterface());226  ASSERT_TRUE(ZT0_New.hasPrivateZAInterface());227 228  SA ZT0_Undef = SA(SA::ZT0_Undef | SA::encodeZT0State(SA::StateValue::New));229  ASSERT_TRUE(ZT0_Undef.isNewZT0());230  ASSERT_FALSE(ZT0_Undef.isInZT0());231  ASSERT_FALSE(ZT0_Undef.isOutZT0());232  ASSERT_FALSE(ZT0_Undef.isInOutZT0());233  ASSERT_FALSE(ZT0_Undef.isPreservesZT0());234  ASSERT_FALSE(ZT0_Undef.sharesZT0());235  ASSERT_TRUE(ZT0_Undef.hasZT0State());236  ASSERT_FALSE(ZT0_Undef.hasSharedZAInterface());237  ASSERT_TRUE(ZT0_Undef.hasPrivateZAInterface());238  ASSERT_TRUE(ZT0_Undef.hasUndefZT0());239 240  ASSERT_FALSE(SA(SA::Normal).isInZT0());241  ASSERT_FALSE(SA(SA::Normal).isOutZT0());242  ASSERT_FALSE(SA(SA::Normal).isInOutZT0());243  ASSERT_FALSE(SA(SA::Normal).isPreservesZT0());244  ASSERT_FALSE(SA(SA::Normal).isNewZT0());245  ASSERT_FALSE(SA(SA::Normal).sharesZT0());246  ASSERT_FALSE(SA(SA::Normal).hasZT0State());247}248 249TEST(SMEAttributes, Transitions) {250  // Normal -> Normal251  ASSERT_FALSE(CA(SA::Normal, SA::Normal).requiresSMChange());252  ASSERT_FALSE(CA(SA::Normal, SA::Normal).requiresPreservingZT0());253  ASSERT_FALSE(CA(SA::Normal, SA::Normal).requiresDisablingZABeforeCall());254  ASSERT_FALSE(CA(SA::Normal, SA::Normal).requiresEnablingZAAfterCall());255  // Normal -> Normal + LocallyStreaming256  ASSERT_FALSE(CA(SA::Normal, SA::Normal | SA::SM_Body).requiresSMChange());257 258  // Normal -> Streaming259  ASSERT_TRUE(CA(SA::Normal, SA::SM_Enabled).requiresSMChange());260  // Normal -> Streaming + LocallyStreaming261  ASSERT_TRUE(CA(SA::Normal, SA::SM_Enabled | SA::SM_Body).requiresSMChange());262 263  // Normal -> Streaming-compatible264  ASSERT_FALSE(CA(SA::Normal, SA::SM_Compatible).requiresSMChange());265  // Normal -> Streaming-compatible + LocallyStreaming266  ASSERT_FALSE(267      CA(SA::Normal, SA::SM_Compatible | SA::SM_Body).requiresSMChange());268 269  // Streaming -> Normal270  ASSERT_TRUE(CA(SA::SM_Enabled, SA::Normal).requiresSMChange());271  // Streaming -> Normal + LocallyStreaming272  ASSERT_TRUE(CA(SA::SM_Enabled, SA::Normal | SA::SM_Body).requiresSMChange());273 274  // Streaming -> Streaming275  ASSERT_FALSE(CA(SA::SM_Enabled, SA::SM_Enabled).requiresSMChange());276  // Streaming -> Streaming + LocallyStreaming277  ASSERT_FALSE(278      CA(SA::SM_Enabled, SA::SM_Enabled | SA::SM_Body).requiresSMChange());279 280  // Streaming -> Streaming-compatible281  ASSERT_FALSE(CA(SA::SM_Enabled, SA::SM_Compatible).requiresSMChange());282  // Streaming -> Streaming-compatible + LocallyStreaming283  ASSERT_FALSE(284      CA(SA::SM_Enabled, SA::SM_Compatible | SA::SM_Body).requiresSMChange());285 286  // Streaming-compatible -> Normal287  ASSERT_TRUE(CA(SA::SM_Compatible, SA::Normal).requiresSMChange());288  ASSERT_TRUE(289      CA(SA::SM_Compatible, SA::Normal | SA::SM_Body).requiresSMChange());290 291  // Streaming-compatible -> Streaming292  ASSERT_TRUE(CA(SA::SM_Compatible, SA::SM_Enabled).requiresSMChange());293  // Streaming-compatible -> Streaming + LocallyStreaming294  ASSERT_TRUE(295      CA(SA::SM_Compatible, SA::SM_Enabled | SA::SM_Body).requiresSMChange());296 297  // Streaming-compatible -> Streaming-compatible298  ASSERT_FALSE(CA(SA::SM_Compatible, SA::SM_Compatible).requiresSMChange());299  // Streaming-compatible -> Streaming-compatible + LocallyStreaming300  ASSERT_FALSE(CA(SA::SM_Compatible, SA::SM_Compatible | SA::SM_Body)301                   .requiresSMChange());302 303  SA Private_ZA = SA(SA::Normal);304  SA ZA_Shared = SA(SA::encodeZAState(SA::StateValue::In));305  SA ZT0_Shared = SA(SA::encodeZT0State(SA::StateValue::In));306  SA ZA_ZT0_Shared = SA(SA::encodeZAState(SA::StateValue::In) |307                        SA::encodeZT0State(SA::StateValue::In));308  SA Undef_ZT0 = SA(SA::ZT0_Undef);309 310  // Shared ZA -> Private ZA Interface311  ASSERT_FALSE(CA(ZA_Shared, Private_ZA).requiresDisablingZABeforeCall());312  ASSERT_FALSE(CA(ZA_Shared, Private_ZA).requiresEnablingZAAfterCall());313 314  // Shared ZT0 -> Private ZA Interface315  ASSERT_TRUE(CA(ZT0_Shared, Private_ZA).requiresDisablingZABeforeCall());316  ASSERT_TRUE(CA(ZT0_Shared, Private_ZA).requiresPreservingZT0());317  ASSERT_TRUE(CA(ZT0_Shared, Private_ZA).requiresEnablingZAAfterCall());318 319  // Shared Undef ZT0 -> Private ZA Interface320  // Note: "Undef ZT0" is a callsite attribute that means ZT0 is undefined at321  // point the of the call.322  ASSERT_TRUE(323      CA(ZT0_Shared, Private_ZA, Undef_ZT0).requiresDisablingZABeforeCall());324  ASSERT_FALSE(CA(ZT0_Shared, Private_ZA, Undef_ZT0).requiresPreservingZT0());325  ASSERT_TRUE(326      CA(ZT0_Shared, Private_ZA, Undef_ZT0).requiresEnablingZAAfterCall());327 328  // Shared ZA & ZT0 -> Private ZA Interface329  ASSERT_FALSE(CA(ZA_ZT0_Shared, Private_ZA).requiresDisablingZABeforeCall());330  ASSERT_TRUE(CA(ZA_ZT0_Shared, Private_ZA).requiresPreservingZT0());331  ASSERT_FALSE(CA(ZA_ZT0_Shared, Private_ZA).requiresEnablingZAAfterCall());332 333  // Shared ZA -> Shared ZA Interface334  ASSERT_FALSE(CA(ZA_Shared, ZT0_Shared).requiresDisablingZABeforeCall());335  ASSERT_FALSE(CA(ZA_Shared, ZT0_Shared).requiresEnablingZAAfterCall());336 337  // Shared ZT0 -> Shared ZA Interface338  ASSERT_FALSE(CA(ZT0_Shared, ZT0_Shared).requiresDisablingZABeforeCall());339  ASSERT_FALSE(CA(ZT0_Shared, ZT0_Shared).requiresPreservingZT0());340  ASSERT_FALSE(CA(ZT0_Shared, ZT0_Shared).requiresEnablingZAAfterCall());341 342  // Shared ZA & ZT0 -> Shared ZA Interface343  ASSERT_FALSE(CA(ZA_ZT0_Shared, ZT0_Shared).requiresDisablingZABeforeCall());344  ASSERT_FALSE(CA(ZA_ZT0_Shared, ZT0_Shared).requiresPreservingZT0());345  ASSERT_FALSE(CA(ZA_ZT0_Shared, ZT0_Shared).requiresEnablingZAAfterCall());346}347