[AArch64] Add SVE2.1 target feature for Armv9-A 2022 Architecture Extension
authorDavid Sherwood <david.sherwood@arm.com>
Tue, 18 Oct 2022 16:43:44 +0000 (16:43 +0000)
committerDavid Sherwood <david.sherwood@arm.com>
Fri, 21 Oct 2022 14:02:32 +0000 (14:02 +0000)
First patch in a series adding MC layer support for SVE2.1.

This patch adds the following feature:

sve2p1

Some of the existing SVE instructions added for SME are now
also available under the sve2p1 feature, which are now guarded
by the HasSVE2p1orSME predicate.

The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2022-09

Differential Revision: https://reviews.llvm.org/D136352

13 files changed:
llvm/include/llvm/Support/AArch64TargetParser.def
llvm/include/llvm/Support/AArch64TargetParser.h
llvm/lib/Target/AArch64/AArch64.td
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
llvm/test/MC/AArch64/SVE2p1/directive-arch-negative.s [new file with mode: 0644]
llvm/test/MC/AArch64/SVE2p1/directive-arch.s [new file with mode: 0644]
llvm/test/MC/AArch64/SVE2p1/directive-arch_extension-negative.s [new file with mode: 0644]
llvm/test/MC/AArch64/SVE2p1/directive-arch_extension.s [new file with mode: 0644]
llvm/test/MC/AArch64/SVE2p1/feature-sve2p1-implies-sve2.s [new file with mode: 0644]
llvm/unittests/Support/TargetParserTest.cpp

index e5cb9b8..49ed806 100644 (file)
@@ -128,6 +128,7 @@ AARCH64_ARCH_EXT_NAME("sve2-aes",     AArch64::AEK_SVE2AES,     "+sve2-aes",
 AARCH64_ARCH_EXT_NAME("sve2-sm4",     AArch64::AEK_SVE2SM4,     "+sve2-sm4",     "-sve2-sm4")
 AARCH64_ARCH_EXT_NAME("sve2-sha3",    AArch64::AEK_SVE2SHA3,    "+sve2-sha3",    "-sve2-sha3")
 AARCH64_ARCH_EXT_NAME("sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", "-sve2-bitperm")
+AARCH64_ARCH_EXT_NAME("sve2p1",       AArch64::AEK_SVE2p1,      "+sve2p1",       "-sve2p1")
 AARCH64_ARCH_EXT_NAME("rcpc",         AArch64::AEK_RCPC,        "+rcpc",         "-rcpc")
 AARCH64_ARCH_EXT_NAME("rng",          AArch64::AEK_RAND,        "+rand",         "-rand")
 AARCH64_ARCH_EXT_NAME("memtag",       AArch64::AEK_MTE,         "+mte",          "-mte")
index 8de7eb3..f4e157c 100644 (file)
@@ -73,6 +73,7 @@ enum ArchExtKind : uint64_t {
   AEK_MOPS =        1ULL << 41, // FEAT_MOPS
   AEK_PERFMON =     1ULL << 42, // FEAT_PMUv3
   AEK_SME2 =        1ULL << 43, // FEAT_SME2
+  AEK_SVE2p1 =      1ULL << 44, // FEAT_SVE2p1
 };
 
 enum class ArchKind {
index 80115aa..03759f5 100644 (file)
@@ -162,6 +162,9 @@ def FeatureSVE2SHA3 : SubtargetFeature<"sve2-sha3", "HasSVE2SHA3", "true",
 def FeatureSVE2BitPerm : SubtargetFeature<"sve2-bitperm", "HasSVE2BitPerm", "true",
   "Enable bit permutation SVE2 instructions (FEAT_SVE_BitPerm)", [FeatureSVE2]>;
 
+def FeatureSVE2p1: SubtargetFeature<"sve2p1", "HasSVE2p1", "true",
+  "Enable Scalable Vector Extension 2.1 instructions", [FeatureSVE2]>;
+
 def FeatureZCRegMove : SubtargetFeature<"zcm", "HasZeroCycleRegMove", "true",
                                         "Has zero-cycle register moves">;
 
@@ -645,7 +648,7 @@ def PAUnsupported : AArch64Unsupported {
 }
 
 def SMEUnsupported : AArch64Unsupported {
-  let F = [HasSME, HasSMEF64F64, HasSMEI16I64, HasSME2];
+  let F = [HasSME, HasSMEF64F64, HasSMEI16I64, HasSME2, HasSVE2p1_or_HasSME2];
 }
 
 include "AArch64SchedA53.td"
index 56c30f4..3d439a2 100644 (file)
@@ -128,6 +128,8 @@ def HasSVE           : Predicate<"Subtarget->hasSVE()">,
                                  AssemblerPredicateWithAll<(all_of FeatureSVE), "sve">;
 def HasSVE2          : Predicate<"Subtarget->hasSVE2()">,
                                  AssemblerPredicateWithAll<(all_of FeatureSVE2), "sve2">;
+def HasSVE2p1        : Predicate<"Subtarget->hasSVE2p1()">,
+                                 AssemblerPredicate<(any_of FeatureSVE2p1), "sve2p1">;
 def HasSVE2AES       : Predicate<"Subtarget->hasSVE2AES()">,
                                  AssemblerPredicateWithAll<(all_of FeatureSVE2AES), "sve2-aes">;
 def HasSVE2SM4       : Predicate<"Subtarget->hasSVE2SM4()">,
@@ -154,6 +156,12 @@ def HasSVE2orSME
     : Predicate<"Subtarget->hasSVE2() || Subtarget->hasSME()">,
                 AssemblerPredicateWithAll<(any_of FeatureSVE2, FeatureSME),
                 "sve2 or sme">;
+def HasSVE2p1_or_HasSME
+    : Predicate<"Subtarget->hasSVE2p1() || Subtarget->hasSME()">,
+                 AssemblerPredicate<(any_of FeatureSME, FeatureSVE2p1), "sme or sve2p1">;
+def HasSVE2p1_or_HasSME2
+    : Predicate<"Subtarget->hasSVE2p1() || Subtarget->hasSME2()">,
+                 AssemblerPredicate<(any_of FeatureSME2, FeatureSVE2p1), "sme2 or sve2p1">;
 // A subset of NEON instructions are legal in Streaming SVE execution mode,
 // they should be enabled if either has been specified.
 def HasNEONorSME
index 3dec59f..1272036 100644 (file)
@@ -229,18 +229,6 @@ def : Pat<(i64 (int_aarch64_sme_get_tpidr2)),
 def OBSCURE_COPY : Pseudo<(outs GPR64:$dst), (ins GPR64:$idx), []>, Sched<[]> { }
 def : Pat<(i64 (AArch64ObscureCopy (i64 GPR64:$idx))),
           (OBSCURE_COPY GPR64:$idx)>;
-
-//===----------------------------------------------------------------------===//
-// SVE2 instructions
-//===----------------------------------------------------------------------===//
-
-defm REVD_ZPmZ : sve2_int_perm_revd<"revd", AArch64revd_mt>;
-
-defm SCLAMP_ZZZ : sve2_clamp<"sclamp", 0b0, int_aarch64_sve_sclamp>;
-defm UCLAMP_ZZZ : sve2_clamp<"uclamp", 0b1, int_aarch64_sve_uclamp>;
-
-defm PSEL_PPPRI : sve2_int_perm_sel_p<"psel", int_aarch64_sve_psel>;
-
 } // End let Predicates = [HasSME]
 
 //===----------------------------------------------------------------------===//
index 98dc3a2..f9b4e5d 100644 (file)
@@ -3555,3 +3555,16 @@ let Predicates = [HasSVE2BitPerm] in {
   defm BDEP_ZZZ : sve2_misc_bitwise<0b1101, "bdep", int_aarch64_sve_bdep_x>;
   defm BGRP_ZZZ : sve2_misc_bitwise<0b1110, "bgrp", int_aarch64_sve_bgrp_x>;
 } // End HasSVE2BitPerm
+
+//===----------------------------------------------------------------------===//
+// SME or SVE2.1 instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasSVE2p1_or_HasSME] in {
+defm REVD_ZPmZ : sve2_int_perm_revd<"revd", AArch64revd_mt>;
+
+defm SCLAMP_ZZZ : sve2_clamp<"sclamp", 0b0, int_aarch64_sve_sclamp>;
+defm UCLAMP_ZZZ : sve2_clamp<"uclamp", 0b1, int_aarch64_sve_uclamp>;
+
+defm PSEL_PPPRI : sve2_int_perm_sel_p<"psel", int_aarch64_sve_psel>;
+} // End HasSVE2p1_or_HasSME
index 74c01c0..84f0f79 100644 (file)
@@ -3379,6 +3379,7 @@ static const struct Extension {
     {"sve2-sm4", {AArch64::FeatureSVE2SM4}},
     {"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
     {"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
+    {"sve2p1", {AArch64::FeatureSVE2p1}},
     {"ls64", {AArch64::FeatureLS64}},
     {"xs", {AArch64::FeatureXS}},
     {"pauth", {AArch64::FeaturePAuth}},
diff --git a/llvm/test/MC/AArch64/SVE2p1/directive-arch-negative.s b/llvm/test/MC/AArch64/SVE2p1/directive-arch-negative.s
new file mode 100644 (file)
index 0000000..7f1fa8f
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch armv9-a+sve2p1
+.arch armv9-a+nosve2p1
+sclamp z0.s, z1.s, z2.s
+// CHECK: error: instruction requires: sme or sve2p1
+// CHECK: sclamp z0.s, z1.s, z2.s
diff --git a/llvm/test/MC/AArch64/SVE2p1/directive-arch.s b/llvm/test/MC/AArch64/SVE2p1/directive-arch.s
new file mode 100644 (file)
index 0000000..c52f271
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch armv9-a+sve2p1
+sclamp z0.s, z1.s, z2.s
+// CHECK: sclamp z0.s, z1.s, z2.s
diff --git a/llvm/test/MC/AArch64/SVE2p1/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SVE2p1/directive-arch_extension-negative.s
new file mode 100644 (file)
index 0000000..29de56c
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch_extension sve2p1
+.arch_extension nosve2p1
+sclamp z0.s, z1.s, z2.s
+// CHECK: error: instruction requires: sme or sve2p1
+// CHECK: sclamp z0.s, z1.s, z2.s
diff --git a/llvm/test/MC/AArch64/SVE2p1/directive-arch_extension.s b/llvm/test/MC/AArch64/SVE2p1/directive-arch_extension.s
new file mode 100644 (file)
index 0000000..3eb39c0
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.arch_extension sve2p1
+sclamp z0.s, z1.s, z2.s
+// CHECK: sclamp z0.s, z1.s, z2.s
diff --git a/llvm/test/MC/AArch64/SVE2p1/feature-sve2p1-implies-sve2.s b/llvm/test/MC/AArch64/SVE2p1/feature-sve2p1-implies-sve2.s
new file mode 100644 (file)
index 0000000..96193f1
--- /dev/null
@@ -0,0 +1,7 @@
+// This test verifies SVE2p1 implies SVE2.
+
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1  2>&1 < %s \
+// RUN:        | FileCheck %s
+
+cmla   z0.b, z1.b, z2.b, #0
+// CHECK: cmla   z0.b, z1.b, z2.b, #0
index 16d9b5d..e93f169 100644 (file)
@@ -1505,7 +1505,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
       AArch64::AEK_BRBE,    AArch64::AEK_PAUTH,    AArch64::AEK_FLAGM,
       AArch64::AEK_SME,     AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64,
       AArch64::AEK_SME2,    AArch64::AEK_HBC,      AArch64::AEK_MOPS,
-      AArch64::AEK_PERFMON};
+      AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1};
 
   std::vector<StringRef> Features;
 
@@ -1544,6 +1544,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
   EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sm4"));
   EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sha3"));
   EXPECT_TRUE(llvm::is_contained(Features, "+sve2-bitperm"));
+  EXPECT_TRUE(llvm::is_contained(Features, "+sve2p1"));
   EXPECT_TRUE(llvm::is_contained(Features, "+rcpc"));
   EXPECT_TRUE(llvm::is_contained(Features, "+rand"));
   EXPECT_TRUE(llvm::is_contained(Features, "+mte"));
@@ -1625,6 +1626,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
       {"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"},
       {"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"},
       {"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"},
+      {"sve2p1", "nosve2p1", "+sve2p1", "-sve2p1"},
       {"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"},
       {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
       {"rcpc", "norcpc", "+rcpc", "-rcpc"},