[llvm-branch-commits] [clang] [llvm] [AArch64][llvm] Armv9.8-A: Add support for FEAT_SVE_PERM256 (PR #231433)
Martin Wehking via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Oct 14 02:20:25 PDT 2026
https://github.com/MartinWehking updated https://github.com/llvm/llvm-project/pull/231433
>From 80d2b0a3101be05e8b65857eb9b7bdda9920d7bf Mon Sep 17 00:00:00 2001
From: Martin Wehking <martin.wehking at arm.com>
Date: Tue, 15 Sep 2026 10:17:29 +0000
Subject: [PATCH 1/2] [AArch64][llvm] Armv9.8-A: Add support for
FEAT_SVE_PERM256
Add support for FEAT_SVE_PERM256 (SVE 128-bit element permute
instructions), which enables already existing instructions,
independently of FEAT_F64MM
---
clang/test/Driver/aarch64-v98a.c | 4 ++
.../print-supported-extensions-aarch64.c | 1 +
llvm/lib/Target/AArch64/AArch64.td | 1 +
llvm/lib/Target/AArch64/AArch64Features.td | 7 +-
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 7 ++
.../lib/Target/AArch64/AArch64SVEInstrInfo.td | 4 +-
.../AArch64/AsmParser/AArch64AsmParser.cpp | 1 +
.../MC/AArch64/SVE/matrix-multiply-fp64.s | 48 --------------
llvm/test/MC/AArch64/SVE/permute.s | 66 +++++++++++++++++++
.../MC/AArch64/SVE2/directive-arch-negative.s | 5 ++
llvm/test/MC/AArch64/SVE2/directive-arch.s | 4 ++
.../SVE2/directive-arch_extension-negative.s | 6 ++
.../AArch64/SVE2/directive-arch_extension.s | 4 ++
.../TargetParser/TargetParserTest.cpp | 5 +-
14 files changed, 110 insertions(+), 53 deletions(-)
create mode 100644 llvm/test/MC/AArch64/SVE/permute.s
diff --git a/clang/test/Driver/aarch64-v98a.c b/clang/test/Driver/aarch64-v98a.c
index 1a41a97610e59..af37e6f8b77ad 100644
--- a/clang/test/Driver/aarch64-v98a.c
+++ b/clang/test/Driver/aarch64-v98a.c
@@ -29,3 +29,7 @@
// RUN: %clang -target aarch64 -march=armv9.8a+sve-rcpc -### -c %s 2>&1 | FileCheck -check-prefix=V98A-SVE-RCPC %s
// RUN: %clang -target aarch64 -march=armv9.8-a+sve-rcpc -### -c %s 2>&1 | FileCheck -check-prefix=V98A-SVE-RCPC %s
// V98A-SVE-RCPC: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.8a"{{.*}} "-target-feature" "+sve-rcpc"
+//
+// RUN: %clang -target aarch64 -march=armv9.8a+sve-perm256 -### -c %s 2>&1 | FileCheck -check-prefix=V98A-SVE-PERM256 %s
+// RUN: %clang -target aarch64 -march=armv9.8-a+sve-perm256 -### -c %s 2>&1 | FileCheck -check-prefix=V98A-SVE-PERM256 %s
+// V98A-SVE-PERM256: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.8a"{{.*}} "-target-feature" "+sve-perm256"
diff --git a/clang/test/Driver/print-supported-extensions-aarch64.c b/clang/test/Driver/print-supported-extensions-aarch64.c
index e334d2e8dcee0..4ee6e1d7d80cb 100644
--- a/clang/test/Driver/print-supported-extensions-aarch64.c
+++ b/clang/test/Driver/print-supported-extensions-aarch64.c
@@ -106,6 +106,7 @@
// CHECK-NEXT: sve-bitperm FEAT_SVE_BitPerm Enable bit permutation SVE2 instructions
// CHECK-NEXT: sve-f16f32mm FEAT_SVE_F16F32MM Enable Armv9.6-A FP16 to FP32 Matrix Multiply
// CHECK-NEXT: sve-rcpc FEAT_SVE_LRCPC Enable Armv9.8-A SVE weaker Release Consistency processor consistent (RCpc) model
+// CHECK-NEXT: sve-perm256 FEAT_SVE_PERM256 Enable Armv9.8-A SVE 128-bit element permute instructions
// CHECK-NEXT: sve-sha3 FEAT_SVE_SHA3 Enable SVE SHA3 instructions
// CHECK-NEXT: sve-sm4 FEAT_SVE_SM4 Enable SVE SM4 instructions
// CHECK-NEXT: sve2 FEAT_SVE2 Enable Scalable Vector Extension 2 (SVE2) instructions
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 9750fa837c180..d3cbf32413c0b 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -111,6 +111,7 @@ def SME2Unsupported : AArch64Unsupported {
def SMEUnsupported : AArch64Unsupported {
let F = !listconcat([HasSME, HasSMEI16I64, HasSMEF16F16, HasSMEF64F64, HasSMEFA64,
+ HasMatMulFP64_or_SVE_PERM256,
HasSMEandIsNonStreamingSafe],
SME2Unsupported.F);
}
diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td
index 0434ec5d26ee8..3410d2eb3d42f 100644
--- a/llvm/lib/Target/AArch64/AArch64Features.td
+++ b/llvm/lib/Target/AArch64/AArch64Features.td
@@ -631,6 +631,9 @@ def FeatureSVE_RCPC: ExtensionWithMArch<"sve-rcpc", "SVE_RCPC", "FEAT_SVE_LRCPC"
"Enable Armv9.8-A SVE weaker Release Consistency processor consistent (RCpc) model",
[FeatureSVE2, FeatureRCPC3]>;
+def FeatureSVE_PERM256: ExtensionWithMArch<"sve-perm256", "SVE_PERM256", "FEAT_SVE_PERM256",
+ "Enable Armv9.8-A SVE 128-bit element permute instructions">;
+
//===----------------------------------------------------------------------===//
// Future Architecture Technologies
//===----------------------------------------------------------------------===//
@@ -1136,8 +1139,8 @@ def HasV9_7aOps : Architecture64<9, 7, "a", "v9.7a",
!listconcat(HasV9_6aOps.DefaultExts, [FeatureSVE2p3, FeatureFPRCVT,
FeatureF16F32DOT])>;
def HasV9_8aOps : Architecture64<9, 8, "a", "v9.8a",
- [HasV9_7aOps],
- HasV9_7aOps.DefaultExts>;
+ [HasV9_7aOps, FeatureSVE_PERM256],
+ !listconcat(HasV9_7aOps.DefaultExts, [FeatureSVE_PERM256])>;
def HasV8_0rOps : Architecture64<8, 0, "r", "v8r",
[ //v8.1
FeatureCRC, FeaturePAN, FeatureLSE, FeatureCONTEXTIDREL2,
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 07d8d79555b84..9fc0a7fe5a70d 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -243,6 +243,8 @@ def HasLSC64B : Predicate<"Subtarget->hasLSC64B()">,
AssemblerPredicateWithAll<(all_of FeatureLSC64B), "lsc64b">;
def HasSVE_RCPC : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasSVE_RCPC()">,
AssemblerPredicateWithAll<(all_of FeatureSVE_RCPC), "sve-rcpc">;
+def HasSVE_PERM256 : Predicate<"Subtarget->hasSVE_PERM256()">,
+ AssemblerPredicateWithAll<(all_of FeatureSVE_PERM256), "sve-perm256">;
// A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified.
@@ -322,6 +324,11 @@ def HasNonStreamingSVE2p2_or_SME2p2
AssemblerPredicateWithAll<(any_of FeatureSVE2p2, FeatureSME2p2),
"sme2p2 or sve2p2">;
+def HasMatMulFP64_or_SVE_PERM256
+ : Predicate<"Subtarget->hasSVE_PERM256() || (Subtarget->isSVEAvailable() && Subtarget->hasMatMulFP64())">,
+ AssemblerPredicateWithAll<(any_of FeatureMatMulFP64, FeatureSVE_PERM256),
+ "f64mm or sve-perm256">;
+
def HasSMEF16F16_or_SMEF8F16
: Predicate<"Subtarget->isStreaming() && (Subtarget->hasSMEF16F16() || Subtarget->hasSMEF8F16())">,
AssemblerPredicateWithAll<(any_of FeatureSMEF16F16, FeatureSMEF8F16),
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 9662d7a0cb9f9..e5332dab0080e 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -3957,14 +3957,14 @@ let Predicates = [HasSVE, HasMatMulFP64] in {
defm LD1RO_D : sve_mem_ldor_ss<0b11, "ld1rod", Z_d, ZPR64, GPR64NoXZRshifted64, nxv2i64, nxv2i1, AArch64ld1ro_z, am_sve_regreg_lsl3>;
} // End HasSVE, HasMatMulFP64
-let Predicates = [HasSVE_or_SME, HasMatMulFP64] in {
+let Predicates = [HasSVE_or_SME, HasMatMulFP64_or_SVE_PERM256] in {
defm ZIP1_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b00, 0, "zip1", int_aarch64_sve_zip1q>;
defm ZIP2_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b00, 1, "zip2", int_aarch64_sve_zip2q>;
defm UZP1_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b01, 0, "uzp1", int_aarch64_sve_uzp1q>;
defm UZP2_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b01, 1, "uzp2", int_aarch64_sve_uzp2q>;
defm TRN1_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b11, 0, "trn1", int_aarch64_sve_trn1q>;
defm TRN2_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b11, 1, "trn2", int_aarch64_sve_trn2q>;
-} // End HasSVE_or_SME, HasMatMulFP64
+} // End HasSVE_or_SME, HasMatMulFP64_or_SVE_PERM256
let Predicates = [HasSVE2_or_SME] in {
// SVE2 integer multiply-add (indexed)
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index ce50ff30f14cb..0807906fe4510 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -3765,6 +3765,7 @@ constexpr EnumStringDef<FeatureBitset> ExtensionDefs[] = {
{{"cflt"}, {AArch64::FeatureCFLT}},
{{"lsc64b"}, {AArch64::FeatureLSC64B}},
{{"sve-rcpc"}, {AArch64::FeatureSVE_RCPC}},
+ {{"sve-perm256"}, {AArch64::FeatureSVE_PERM256}},
};
constexpr auto ExtensionMap = BUILD_ENUM_STRINGS(ExtensionDefs);
diff --git a/llvm/test/MC/AArch64/SVE/matrix-multiply-fp64.s b/llvm/test/MC/AArch64/SVE/matrix-multiply-fp64.s
index 14637da848558..c9871c34254c4 100644
--- a/llvm/test/MC/AArch64/SVE/matrix-multiply-fp64.s
+++ b/llvm/test/MC/AArch64/SVE/matrix-multiply-fp64.s
@@ -231,51 +231,3 @@ ld1rod z0.d, p1/z, [x2, x3, lsl #3]
// CHECK-ENCODING: [0x40,0x04,0xa3,0xa5]
// CHECK-ERROR: instruction requires: f64mm sve
// CHECK-UNKNOWN: a5a30440 <unknown>
-
-
-// --------------------------------------------------------------------------//
-// ZIP1, ZIP2 (SVE, 128-bit element)
-
-zip1 z0.q, z1.q, z2.q
-// CHECK-INST: zip1 z0.q, z1.q, z2.q
-// CHECK-ENCODING: [0x20,0x00,0xa2,0x05]
-// CHECK-ERROR: instruction requires: f64mm sve or sme
-// CHECK-UNKNOWN: 05a20020 <unknown>
-
-zip2 z0.q, z1.q, z2.q
-// CHECK-INST: zip2 z0.q, z1.q, z2.q
-// CHECK-ENCODING: [0x20,0x04,0xa2,0x05]
-// CHECK-ERROR: instruction requires: f64mm sve or sme
-// CHECK-UNKNOWN: 05a20420 <unknown>
-
-
-// --------------------------------------------------------------------------//
-// UZP1, UZP2 (SVE, 128-bit element)
-
-uzp1 z0.q, z1.q, z2.q
-// CHECK-INST: uzp1 z0.q, z1.q, z2.q
-// CHECK-ENCODING: [0x20,0x08,0xa2,0x05]
-// CHECK-ERROR: instruction requires: f64mm sve or sme
-// CHECK-UNKNOWN: 05a20820 <unknown>
-
-uzp2 z0.q, z1.q, z2.q
-// CHECK-INST: uzp2 z0.q, z1.q, z2.q
-// CHECK-ENCODING: [0x20,0x0c,0xa2,0x05]
-// CHECK-ERROR: instruction requires: f64mm sve or sme
-// CHECK-UNKNOWN: 05a20c20 <unknown>
-
-
-// --------------------------------------------------------------------------//
-// TRN1, TRN2 (SVE, 128-bit element)
-
-trn1 z0.q, z1.q, z2.q
-// CHECK-INST: trn1 z0.q, z1.q, z2.q
-// CHECK-ENCODING: [0x20,0x18,0xa2,0x05]
-// CHECK-ERROR: instruction requires: f64mm sve or sme
-// CHECK-UNKNOWN: 05a21820 <unknown>
-
-trn2 z0.q, z1.q, z2.q
-// CHECK-INST: trn2 z0.q, z1.q, z2.q
-// CHECK-ENCODING: [0x20,0x1c,0xa2,0x05]
-// CHECK-ERROR: instruction requires: f64mm sve or sme
-// CHECK-UNKNOWN: 05a21c20 <unknown>
diff --git a/llvm/test/MC/AArch64/SVE/permute.s b/llvm/test/MC/AArch64/SVE/permute.s
new file mode 100644
index 0000000000000..5dd3c94258bcc
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/permute.s
@@ -0,0 +1,66 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+f64mm < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+sve-perm256 < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve,+sve-perm256 < %s \
+// RUN: | llvm-objdump --no-print-imm-hex -d --mattr=+sve,+sve-perm256 - \
+// RUN: | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve,+sve-perm256 < %s \
+// RUN: | llvm-objdump --no-print-imm-hex -d --mattr=+sve,-sve-perm256,-f64mm - \
+// RUN: | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+sve-perm256 < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+sve,+sve-perm256 -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+v9.8a < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+v9.8a -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// --------------------------------------------------------------------------//
+// ZIP1, ZIP2
+
+zip1 z0.q, z1.q, z2.q
+// CHECK-INST: zip1 z0.q, z1.q, z2.q
+// CHECK-ENCODING: [0x20,0x00,0xa2,0x05]
+// CHECK-ERROR: instruction requires: f64mm or sve-perm256
+// CHECK-UNKNOWN: 05a20020 <unknown>
+
+zip2 z0.q, z1.q, z2.q
+// CHECK-INST: zip2 z0.q, z1.q, z2.q
+// CHECK-ENCODING: [0x20,0x04,0xa2,0x05]
+// CHECK-ERROR: instruction requires: f64mm or sve-perm256
+// CHECK-UNKNOWN: 05a20420 <unknown>
+
+// --------------------------------------------------------------------------//
+// UZP1, UZP2
+
+uzp1 z0.q, z1.q, z2.q
+// CHECK-INST: uzp1 z0.q, z1.q, z2.q
+// CHECK-ENCODING: [0x20,0x08,0xa2,0x05]
+// CHECK-ERROR: instruction requires: f64mm or sve-perm256
+// CHECK-UNKNOWN: 05a20820 <unknown>
+
+uzp2 z0.q, z1.q, z2.q
+// CHECK-INST: uzp2 z0.q, z1.q, z2.q
+// CHECK-ENCODING: [0x20,0x0c,0xa2,0x05]
+// CHECK-ERROR: instruction requires: f64mm or sve-perm256
+// CHECK-UNKNOWN: 05a20c20 <unknown>
+
+// --------------------------------------------------------------------------//
+// TRN1, TRN2
+
+trn1 z0.q, z1.q, z2.q
+// CHECK-INST: trn1 z0.q, z1.q, z2.q
+// CHECK-ENCODING: [0x20,0x18,0xa2,0x05]
+// CHECK-ERROR: instruction requires: f64mm or sve-perm256
+// CHECK-UNKNOWN: 05a21820 <unknown>
+
+trn2 z0.q, z1.q, z2.q
+// CHECK-INST: trn2 z0.q, z1.q, z2.q
+// CHECK-ENCODING: [0x20,0x1c,0xa2,0x05]
+// CHECK-ERROR: instruction requires: f64mm or sve-perm256
+// CHECK-UNKNOWN: 05a21c20 <unknown>
diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s b/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s
index f0d47664f08a7..7f8f2186fbcc1 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s
@@ -70,3 +70,8 @@ bfscale z0.h, p0/m, z0.h, z0.h
ldapro z0, [x0]
// CHECK: error: instruction requires: sve-rcpc
// CHECK-NEXT: ldapro z0, [x0]
+
+.arch armv9.8-a+nosve-perm256
+uzp1 z0.q, z1.q, z2.q
+# CHECK: error: instruction requires: f64mm or sve-perm256
+# CHECK-NEXT: uzp1 z0.q, z1.q, z2.q
diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch.s b/llvm/test/MC/AArch64/SVE2/directive-arch.s
index 5f042ca386623..7f1b6def2f3a7 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-arch.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-arch.s
@@ -47,3 +47,7 @@ bfscale z0.h, p0/m, z0.h, z0.h
.arch armv9.6-a+sve-rcpc
ldapro z0, [x0]
// CHECK: ldapro z0, [x0]
+
+.arch armv9.8-a
+zip1 z0.q, z1.q, z2.q
+// CHECK: zip1 z0.q, z1.q, z2.q
diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s
index c03e7deb6490b..f1bd2b6cc6eac 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s
@@ -66,3 +66,9 @@ bfscale z0.h, p0/m, z0.h, z0.h
ldapro z0, [x0]
// CHECK: error: instruction requires: sve-rcpc
// CHECK-NEXT: ldapro z0, [x0]
+
+.arch_extension sve-perm256
+.arch_extension nosve-perm256
+zip1 z0.q, z1.q, z2.q
+// CHECK: error: instruction requires: f64mm or sve-perm256
+// CHECK-NEXT: zip1 z0.q, z1.q, z2.q
diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s b/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s
index 940d7f179f5e2..43a00abd1a48c 100644
--- a/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s
+++ b/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s
@@ -43,3 +43,7 @@ bfscale z0.h, p0/m, z0.h, z0.h
.arch_extension sve-rcpc
ldapro z0, [x0]
// CHECK: ldapro z0, [x0]
+
+.arch_extension sve-perm256
+zip1 z0.q, z1.q, z2.q
+// CHECK: zip1 z0.q, z1.q, z2.q
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index ca977888ed3f7..192f22fb5b79d 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -1509,7 +1509,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
AArch64::AEK_POPS, AArch64::AEK_SVESM4,
AArch64::AEK_MTETC, AArch64::AEK_HINTE,
AArch64::AEK_CFLT, AArch64::AEK_LSC64B,
- AArch64::AEK_SVE_RCPC,
+ AArch64::AEK_SVE_RCPC, AArch64::AEK_SVE_PERM256,
};
std::vector<StringRef> Features;
@@ -1637,6 +1637,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
EXPECT_TRUE(llvm::is_contained(Features, "+cflt"));
EXPECT_TRUE(llvm::is_contained(Features, "+lsc64b"));
EXPECT_TRUE(llvm::is_contained(Features, "+sve-rcpc"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+sve-perm256"));
// Assuming we listed every extension above, this should produce the same
// result.
@@ -1821,6 +1822,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
{"cflt", "nocflt", "+cflt", "-cflt"},
{"lsc64b", "nolsc64b", "+lsc64b", "-lsc64b"},
{"sve-rcpc", "nosve-rcpc", "+sve-rcpc", "-sve-rcpc"},
+ {"sve-perm256", "nosve-perm256", "+sve-perm256", "-sve-perm256"},
};
for (unsigned i = 0; i < std::size(ArchExt); i++) {
@@ -1967,6 +1969,7 @@ AArch64ExtensionDependenciesBaseArchTestParams
{}},
{AArch64::ARMV9_5A, {}, {"v9.5a", "mops", "cpa"}, {}},
{AArch64::ARMV9_7A, {}, {"v9.7a", "f16f32dot"}, {}},
+ {AArch64::ARMV9_8A, {}, {"v9.8a", "sve-perm256"}, {}},
// Positive modifiers
{AArch64::ARMV8A, {"fp16"}, {"fullfp16"}, {}},
>From 3d32432c68721324ab7032051530643a7c2df62e Mon Sep 17 00:00:00 2001
From: Martin Wehking <martin.wehking at arm.com>
Date: Wed, 14 Oct 2026 09:01:54 +0000
Subject: [PATCH 2/2] fixup! Make predicate more condensed
Remove the sve_perm256 predicate and replace the only other predicate
using it with a more condensed one and make it capture the entire
condition.
---
llvm/lib/Target/AArch64/AArch64.td | 2 +-
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 6 ++----
llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 4 ++--
3 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index d3cbf32413c0b..c0a5253fa32e0 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -111,7 +111,7 @@ def SME2Unsupported : AArch64Unsupported {
def SMEUnsupported : AArch64Unsupported {
let F = !listconcat([HasSME, HasSMEI16I64, HasSMEF16F16, HasSMEF64F64, HasSMEFA64,
- HasMatMulFP64_or_SVE_PERM256,
+ HasNonStreamingMatMulFP64_or_SVE_PERM256,
HasSMEandIsNonStreamingSafe],
SME2Unsupported.F);
}
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 9fc0a7fe5a70d..4446e4c0186a7 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -243,8 +243,6 @@ def HasLSC64B : Predicate<"Subtarget->hasLSC64B()">,
AssemblerPredicateWithAll<(all_of FeatureLSC64B), "lsc64b">;
def HasSVE_RCPC : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasSVE_RCPC()">,
AssemblerPredicateWithAll<(all_of FeatureSVE_RCPC), "sve-rcpc">;
-def HasSVE_PERM256 : Predicate<"Subtarget->hasSVE_PERM256()">,
- AssemblerPredicateWithAll<(all_of FeatureSVE_PERM256), "sve-perm256">;
// A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified.
@@ -324,8 +322,8 @@ def HasNonStreamingSVE2p2_or_SME2p2
AssemblerPredicateWithAll<(any_of FeatureSVE2p2, FeatureSME2p2),
"sme2p2 or sve2p2">;
-def HasMatMulFP64_or_SVE_PERM256
- : Predicate<"Subtarget->hasSVE_PERM256() || (Subtarget->isSVEAvailable() && Subtarget->hasMatMulFP64())">,
+def HasNonStreamingMatMulFP64_or_SVE_PERM256
+ : Predicate<"(Subtarget->isSVEorStreamingSVEAvailable() && Subtarget->hasSVE_PERM256()) || (Subtarget->isSVEAvailable() && Subtarget->hasMatMulFP64())">,
AssemblerPredicateWithAll<(any_of FeatureMatMulFP64, FeatureSVE_PERM256),
"f64mm or sve-perm256">;
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index e5332dab0080e..da49e3278339b 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -3957,14 +3957,14 @@ let Predicates = [HasSVE, HasMatMulFP64] in {
defm LD1RO_D : sve_mem_ldor_ss<0b11, "ld1rod", Z_d, ZPR64, GPR64NoXZRshifted64, nxv2i64, nxv2i1, AArch64ld1ro_z, am_sve_regreg_lsl3>;
} // End HasSVE, HasMatMulFP64
-let Predicates = [HasSVE_or_SME, HasMatMulFP64_or_SVE_PERM256] in {
+let Predicates = [HasSVE_or_SME, HasNonStreamingMatMulFP64_or_SVE_PERM256] in {
defm ZIP1_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b00, 0, "zip1", int_aarch64_sve_zip1q>;
defm ZIP2_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b00, 1, "zip2", int_aarch64_sve_zip2q>;
defm UZP1_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b01, 0, "uzp1", int_aarch64_sve_uzp1q>;
defm UZP2_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b01, 1, "uzp2", int_aarch64_sve_uzp2q>;
defm TRN1_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b11, 0, "trn1", int_aarch64_sve_trn1q>;
defm TRN2_ZZZ_Q : sve_int_perm_bin_perm_128_zz<0b11, 1, "trn2", int_aarch64_sve_trn2q>;
-} // End HasSVE_or_SME, HasMatMulFP64_or_SVE_PERM256
+} // End HasSVE_or_SME, HasNonStreamingMatMulFP64_or_SVE_PERM256
let Predicates = [HasSVE2_or_SME] in {
// SVE2 integer multiply-add (indexed)
More information about the llvm-branch-commits
mailing list