llvm-project/llvm/unittests/Target/AArch64/SMEAttributesTest.cpp

188 lines
7.7 KiB
C++

#include "Utils/AArch64SMEAttributes.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
using namespace llvm;
using SA = SMEAttrs;
std::unique_ptr<Module> parseIR(const char *IR) {
static LLVMContext C;
SMDiagnostic Err;
return parseAssemblyString(IR, Err, C);
}
TEST(SMEAttributes, Constructors) {
LLVMContext Context;
ASSERT_TRUE(SA(*parseIR("declare void @foo()")->getFunction("foo"))
.hasNonStreamingInterfaceAndBody());
ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")
->getFunction("foo"))
.hasNonStreamingInterface());
ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_enabled\"")
->getFunction("foo"))
.hasStreamingInterface());
ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")
->getFunction("foo"))
.hasStreamingBody());
ASSERT_TRUE(
SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_compatible\"")
->getFunction("foo"))
.hasStreamingCompatibleInterface());
ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_shared\"")
->getFunction("foo"))
.hasSharedZAInterface());
ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_new\"")
->getFunction("foo"))
.hasNewZAInterface());
ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_preserved\"")
->getFunction("foo"))
.preservesZA());
// Invalid combinations.
EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled | SA::SM_Compatible),
"SM_Enabled and SM_Compatible are mutually exclusive");
EXPECT_DEBUG_DEATH(SA(SA::ZA_New | SA::ZA_Shared),
"ZA_New and ZA_Shared are mutually exclusive");
EXPECT_DEBUG_DEATH(SA(SA::ZA_New | SA::ZA_Preserved),
"ZA_New and ZA_Preserved are mutually exclusive");
// Test that the set() methods equally check validity.
EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled).set(SA::SM_Compatible),
"SM_Enabled and SM_Compatible are mutually exclusive");
EXPECT_DEBUG_DEATH(SA(SA::SM_Compatible).set(SA::SM_Enabled),
"SM_Enabled and SM_Compatible are mutually exclusive");
}
TEST(SMEAttributes, Basics) {
// Test PSTATE.SM interfaces.
ASSERT_TRUE(SA(SA::Normal).hasNonStreamingInterfaceAndBody());
ASSERT_TRUE(SA(SA::SM_Enabled).hasStreamingInterface());
ASSERT_TRUE(SA(SA::SM_Body).hasStreamingBody());
ASSERT_TRUE(SA(SA::SM_Body).hasNonStreamingInterface());
ASSERT_FALSE(SA(SA::SM_Body).hasNonStreamingInterfaceAndBody());
ASSERT_FALSE(SA(SA::SM_Body).hasStreamingInterface());
ASSERT_TRUE(SA(SA::SM_Compatible).hasStreamingCompatibleInterface());
ASSERT_TRUE(
SA(SA::SM_Compatible | SA::SM_Body).hasStreamingCompatibleInterface());
ASSERT_TRUE(SA(SA::SM_Compatible | SA::SM_Body).hasStreamingBody());
ASSERT_FALSE(SA(SA::SM_Compatible | SA::SM_Body).hasNonStreamingInterface());
// Test PSTATE.ZA interfaces.
ASSERT_FALSE(SA(SA::ZA_Shared).hasPrivateZAInterface());
ASSERT_TRUE(SA(SA::ZA_Shared).hasSharedZAInterface());
ASSERT_TRUE(SA(SA::ZA_Shared).hasZAState());
ASSERT_FALSE(SA(SA::ZA_Shared).preservesZA());
ASSERT_TRUE(SA(SA::ZA_Shared | SA::ZA_Preserved).preservesZA());
ASSERT_TRUE(SA(SA::ZA_New).hasPrivateZAInterface());
ASSERT_TRUE(SA(SA::ZA_New).hasNewZAInterface());
ASSERT_TRUE(SA(SA::ZA_New).hasZAState());
ASSERT_FALSE(SA(SA::ZA_New).preservesZA());
ASSERT_TRUE(SA(SA::Normal).hasPrivateZAInterface());
ASSERT_FALSE(SA(SA::Normal).hasNewZAInterface());
ASSERT_FALSE(SA(SA::Normal).hasZAState());
ASSERT_FALSE(SA(SA::Normal).preservesZA());
}
TEST(SMEAttributes, Transitions) {
// Normal -> Normal
ASSERT_FALSE(SA(SA::Normal).requiresSMChange(SA(SA::Normal)));
// Normal -> Normal + LocallyStreaming
ASSERT_FALSE(SA(SA::Normal).requiresSMChange(SA(SA::Normal | SA::SM_Body)));
ASSERT_EQ(*SA(SA::Normal)
.requiresSMChange(SA(SA::Normal | SA::SM_Body),
/*BodyOverridesInterface=*/true),
true);
// Normal -> Streaming
ASSERT_EQ(*SA(SA::Normal).requiresSMChange(SA(SA::SM_Enabled)), true);
// Normal -> Streaming + LocallyStreaming
ASSERT_EQ(*SA(SA::Normal).requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body)),
true);
ASSERT_EQ(*SA(SA::Normal)
.requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body),
/*BodyOverridesInterface=*/true),
true);
// Normal -> Streaming-compatible
ASSERT_FALSE(SA(SA::Normal).requiresSMChange(SA(SA::SM_Compatible)));
// Normal -> Streaming-compatible + LocallyStreaming
ASSERT_FALSE(
SA(SA::Normal).requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body)));
ASSERT_EQ(*SA(SA::Normal)
.requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body),
/*BodyOverridesInterface=*/true),
true);
// Streaming -> Normal
ASSERT_EQ(*SA(SA::SM_Enabled).requiresSMChange(SA(SA::Normal)), false);
// Streaming -> Normal + LocallyStreaming
ASSERT_EQ(*SA(SA::SM_Enabled).requiresSMChange(SA(SA::Normal | SA::SM_Body)),
false);
ASSERT_FALSE(SA(SA::SM_Enabled)
.requiresSMChange(SA(SA::Normal | SA::SM_Body),
/*BodyOverridesInterface=*/true));
// Streaming -> Streaming
ASSERT_FALSE(SA(SA::SM_Enabled).requiresSMChange(SA(SA::SM_Enabled)));
// Streaming -> Streaming + LocallyStreaming
ASSERT_FALSE(
SA(SA::SM_Enabled).requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body)));
ASSERT_FALSE(SA(SA::SM_Enabled)
.requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body),
/*BodyOverridesInterface=*/true));
// Streaming -> Streaming-compatible
ASSERT_FALSE(SA(SA::SM_Enabled).requiresSMChange(SA(SA::SM_Compatible)));
// Streaming -> Streaming-compatible + LocallyStreaming
ASSERT_FALSE(
SA(SA::SM_Enabled).requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body)));
ASSERT_FALSE(SA(SA::SM_Enabled)
.requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body),
/*BodyOverridesInterface=*/true));
// Streaming-compatible -> Normal
ASSERT_EQ(*SA(SA::SM_Compatible).requiresSMChange(SA(SA::Normal)), false);
ASSERT_EQ(
*SA(SA::SM_Compatible).requiresSMChange(SA(SA::Normal | SA::SM_Body)),
false);
ASSERT_EQ(*SA(SA::SM_Compatible)
.requiresSMChange(SA(SA::Normal | SA::SM_Body),
/*BodyOverridesInterface=*/true),
true);
// Streaming-compatible -> Streaming
ASSERT_EQ(*SA(SA::SM_Compatible).requiresSMChange(SA(SA::SM_Enabled)), true);
// Streaming-compatible -> Streaming + LocallyStreaming
ASSERT_EQ(
*SA(SA::SM_Compatible).requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body)),
true);
ASSERT_EQ(*SA(SA::SM_Compatible)
.requiresSMChange(SA(SA::SM_Enabled | SA::SM_Body),
/*BodyOverridesInterface=*/true),
true);
// Streaming-compatible -> Streaming-compatible
ASSERT_FALSE(SA(SA::SM_Compatible).requiresSMChange(SA(SA::SM_Compatible)));
// Streaming-compatible -> Streaming-compatible + LocallyStreaming
ASSERT_FALSE(SA(SA::SM_Compatible)
.requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body)));
ASSERT_EQ(*SA(SA::SM_Compatible)
.requiresSMChange(SA(SA::SM_Compatible | SA::SM_Body),
/*BodyOverridesInterface=*/true),
true);
}