[llvm-branch-commits] [clang] [llvm] [AArch64][llvm] Add support for FEAT_SME_F16F8F16 (PR #231435)

Martin Wehking via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Oct 14 03:18:36 PDT 2026


https://github.com/MartinWehking updated https://github.com/llvm/llvm-project/pull/231435

>From d2c7d18bf98f29fb5e17e7362ea152cc2a540d52 Mon Sep 17 00:00:00 2001
From: Martin Wehking <martin.wehking at arm.com>
Date: Tue, 15 Sep 2026 10:53:51 +0000
Subject: [PATCH 1/2] [AArch64][llvm] Add support for FEAT_SME_F16F8F16

Add support for FEAT_SME_F16F8F16 (SME half-precision and FP8 sum-of-products
accumulating to half-precision instructions).
---
 clang/test/Driver/aarch64-vfat.c              |   4 +
 .../print-supported-extensions-aarch64.c      |   1 +
 llvm/lib/Target/AArch64/AArch64Features.td    |   4 +
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |   2 +
 .../lib/Target/AArch64/AArch64RegisterInfo.td |   6 +
 .../lib/Target/AArch64/AArch64SMEInstrInfo.td |   9 +
 .../AArch64/AsmParser/AArch64AsmParser.cpp    |   5 +
 llvm/lib/Target/AArch64/SMEInstrFormats.td    |  57 ++++++
 .../test/MC/AArch64/SME/directives-negative.s |  12 ++
 llvm/test/MC/AArch64/SME/directives.s         |  10 ++
 .../AArch64/SME2/fmopab-fmopat-diagnostics.s  |  49 ++++++
 llvm/test/MC/AArch64/SME2/fmopab-fmopat.s     |  38 ++++
 .../test/MC/AArch64/SME2/fp_dot-diagnostics.s | 166 ++++++++++++++++++
 llvm/test/MC/AArch64/SME2/fp_dot.s            |  62 +++++++
 .../TargetParser/TargetParserTest.cpp         |  25 ++-
 15 files changed, 447 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2/fmopab-fmopat.s
 create mode 100644 llvm/test/MC/AArch64/SME2/fp_dot-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/SME2/fp_dot.s

diff --git a/clang/test/Driver/aarch64-vfat.c b/clang/test/Driver/aarch64-vfat.c
index 047869fe816c0..64aabd3cc8c3d 100644
--- a/clang/test/Driver/aarch64-vfat.c
+++ b/clang/test/Driver/aarch64-vfat.c
@@ -17,3 +17,7 @@
 // RUN: %clang -target aarch64 -march=armv9.7a+btie -### -c %s 2>&1 | FileCheck -check-prefix=VFAT-BTIE %s
 // RUN: %clang -target aarch64 -march=armv9.7-a+btie -### -c %s 2>&1 | FileCheck -check-prefix=VFAT-BTIE %s
 // VFAT-BTIE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+btie"
+
+// RUN: %clang -target aarch64 -march=armv9.8a+sme-f16f8f16 -### -c %s 2>&1 | FileCheck -check-prefix=VFAT-SME-F16F8F16 %s
+// RUN: %clang -target aarch64 -march=armv9.8-a+sme-f16f8f16 -### -c %s 2>&1 | FileCheck -check-prefix=VFAT-SME-F16F8F16 %s
+// VFAT-SME-F16F8F16: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.8a"{{.*}} "-target-feature" "+sme-f16f8f16"
diff --git a/clang/test/Driver/print-supported-extensions-aarch64.c b/clang/test/Driver/print-supported-extensions-aarch64.c
index 4ee6e1d7d80cb..ff569373f2c93 100644
--- a/clang/test/Driver/print-supported-extensions-aarch64.c
+++ b/clang/test/Driver/print-supported-extensions-aarch64.c
@@ -76,6 +76,7 @@
 // CHECK-NEXT:     sme                 FEAT_SME                                               Enable Scalable Matrix Extension (SME)
 // CHECK-NEXT:     sme-b16b16          FEAT_SME_B16B16                                        Enable SME2.1 ZA-targeting non-widening BFloat16 instructions
 // CHECK-NEXT:     sme-f16f16          FEAT_SME_F16F16                                        Enable SME non-widening Float16 instructions
+// CHECK-NEXT:     sme-f16f8f16        FEAT_SME_F16F8F16                                      Enable SME half-precision and FP8 sum-of-products accumulating to half-precision instructions
 // CHECK-NEXT:     sme-f64f64          FEAT_SME_F64F64                                        Enable Scalable Matrix Extension (SME) F64F64 instructions
 // CHECK-NEXT:     sme-f8f16           FEAT_SME_F8F16                                         Enable Scalable Matrix Extension (SME) F8F16 instructions
 // CHECK-NEXT:     sme-f8f32           FEAT_SME_F8F32                                         Enable Scalable Matrix Extension (SME) F8F32 instructions
diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td
index 3410d2eb3d42f..4a5d056c90666 100644
--- a/llvm/lib/Target/AArch64/AArch64Features.td
+++ b/llvm/lib/Target/AArch64/AArch64Features.td
@@ -650,6 +650,10 @@ def FeatureS1POE2: ExtensionWithMArch<"poe2", "POE2", "FEAT_S1POE2",
 def FeatureTEV: ExtensionWithMArch<"tev", "TEV", "FEAT_TEV",
   "Enable TIndex Exception-like Vector instructions">;
 
+def FeatureSMEF16F8F16 : ExtensionWithMArch<"sme-f16f8f16", "SME_F16F8F16", "FEAT_SME_F16F8F16",
+  "Enable SME half-precision and FP8 sum-of-products accumulating to half-precision instructions",
+  [FeatureSME2, FeatureFP8]>;
+
 //===----------------------------------------------------------------------===//
 //  Other Features
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 9fc0a7fe5a70d..57ce1060317f6 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -245,6 +245,8 @@ def HasSVE_RCPC      : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasS
                                  AssemblerPredicateWithAll<(all_of FeatureSVE_RCPC), "sve-rcpc">;
 def HasSVE_PERM256     : Predicate<"Subtarget->hasSVE_PERM256()">,
                                  AssemblerPredicateWithAll<(all_of FeatureSVE_PERM256), "sve-perm256">;
+def HasSMEF16F8F16   : Predicate<"Subtarget->isStreaming() && Subtarget->hasSMEF16F8F16()">,
+                                 AssemblerPredicateWithAll<(all_of FeatureSMEF16F8F16), "sme-f16f8f16">;
 
 // A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
 // they should be enabled if either has been specified.
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index 690983dc20360..f31a945bb0011 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -1266,6 +1266,12 @@ def ZK : RegisterOperand<ZPR_K, "printSVERegOp<>">{
   let ParserMatchClass = ZPRAsmOperand<"Vector_20to23or28to31", 0, "_K">;
 }
 
+def ZK_b : RegisterOperand<ZPR_K, "printSVERegOp<'b'>">{
+  let EncoderMethod = "EncodeZK";
+  let DecoderMethod = "DecodeZK";
+  let ParserMatchClass = ZPRAsmOperand<"Vector_b_20to23or28to31", 8, "_K">;
+}
+
 def ZPR8Mul2_Lo  : ZPRMul2_MinToMaxRegOp<"b", ZPRMul2AsmOp8_Lo,   0, 14, ElementSizeB, ZPRMul2_Lo>;
 def ZPR8Mul2_Hi  : ZPRMul2_MinToMaxRegOp<"b", ZPRMul2AsmOp8_Hi,  16, 30, ElementSizeB, ZPRMul2_Hi>;
 def ZPR16Mul2_Lo : ZPRMul2_MinToMaxRegOp<"h", ZPRMul2AsmOp16_Lo,  0, 14, ElementSizeH, ZPRMul2_Lo>;
diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index 68865c6dd7a8e..eab08dd8fc891 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -1136,6 +1136,15 @@ let Predicates = [HasSME_MOP4, HasSMEF64F64] in {
   defm FMOP4S : sme2_fmop4as_fp64_non_widening<1, "fmop4s", "int_aarch64_sme_mop4s">;
 }
 
+// SME2 mixed-precision FP8 instructions
+let Predicates = [HasSMEF16F8F16] in {
+  def FMOPAB_M2ZZZ_BtoH: sme2_fp8_fmop_za16<"fmopab", 0b0>;
+  def FMOPAT_M2ZZZ_BtoH: sme2_fp8_fmop_za16<"fmopat", 0b1>;
+
+  defm FDOT_VG2_M2ZZIZ_BtoH  : sme2_fp8_fdot_za16_vg1x2<"fdot", 0b0>;
+  defm FVDOT_VG2_M2ZZIZ_BtoH : sme2_fp8_fdot_za16_vg1x2<"fvdot", 0b1>;
+}
+
 //===----------------------------------------------------------------------===//
 // SME2.3 instructions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 0807906fe4510..fc93c92408bbe 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -3766,6 +3766,7 @@ constexpr EnumStringDef<FeatureBitset> ExtensionDefs[] = {
     {{"lsc64b"}, {AArch64::FeatureLSC64B}},
     {{"sve-rcpc"}, {AArch64::FeatureSVE_RCPC}},
     {{"sve-perm256"}, {AArch64::FeatureSVE_PERM256}},
+    {{"sme-f16f8f16"}, {AArch64::FeatureSMEF16F8F16}},
 };
 constexpr auto ExtensionMap = BUILD_ENUM_STRINGS(ExtensionDefs);
 
@@ -6327,6 +6328,9 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
   case Match_InvalidZPR_K0:
     return Error(Loc, "invalid restricted vector register, expected register "
                       "in z20..z23 or z28..z31");
+  case Match_InvalidZPR_K8:
+    return Error(Loc, "invalid restricted vector register, expected register "
+                      "in z20.b..z23.b or z28.b..z31.b");
   case Match_InvalidSVEPattern:
     return Error(Loc, "invalid predicate pattern");
   case Match_InvalidSVEPPRorPNRAnyReg:
@@ -7049,6 +7053,7 @@ bool AArch64AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidZPRMul2_Lo64:
   case Match_InvalidZPRMul2_Hi64:
   case Match_InvalidZPR_K0:
+  case Match_InvalidZPR_K8:
   case Match_InvalidSVEVectorList2x8Mul2:
   case Match_InvalidSVEVectorList2x16Mul2:
   case Match_InvalidSVEVectorList2x32Mul2:
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 5a8a357464227..d516b57aa7432 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -6416,3 +6416,60 @@ multiclass sme2_fp8_fdot_multi_vg1x4<string mnemonic, bits<7> op,
 
   def : SME2_ZA_TwoOp_VG4_Multi_Multi_Pat<NAME, intrinsic, sme_elm_idx0_7, nxv16i8, tileslice16>;
 }
+
+class sme2_fp8_fmop_za16<string asm, bit tb>
+  : I<(outs TileOp16:$ZAda), (ins TileOp16:$_ZAda, ZZ_h_mul_r:$Zn, ZPR8:$Zm, ZK_b:$Zk),
+     asm, "\t$ZAda, $Zn, $Zm, $Zk", "", []>, Sched<[]> {
+  bits<1> ZAda;
+  bits<4> Zn;
+  bits<3> Zk;
+  bits<5> Zm;
+  let Inst{31-21} = 0b10000000101;
+  let Inst{20-16} = Zm;
+  let Inst{15}    = tb;
+  let Inst{14-13} = 0b00;
+  let Inst{12-10} = Zk;
+  let Inst{9-6}   = Zn;
+  let Inst{5-1}   = 0b01100;
+  let Inst{0}     = ZAda;
+
+  let Constraints = "$ZAda = $_ZAda";
+  let Uses = [ FPCR, FPMR ];
+}
+
+class sme2_fp8_fdot_za16_vg1x2<string mnemonic, bit v>: I<(outs MatrixOp16:$ZA),
+                  (ins MatrixOp16:$_ZA, MatrixIndexGPR32Op8_11:$Rv,
+                   sme_elm_idx0_7:$off3, ZZ_b_mul_r:$Zn, ZPR4b16:$Zm,
+                   VectorIndexS:$i2, ZK_b:$Zk), mnemonic,
+                   "\t$ZA[$Rv, $off3, vgx2], $Zn, $Zm$i2, $Zk", "", []>, Sched<[]> {
+  bits<0> ZA;
+  bits<3> off3;
+  bits<2> i2;
+  bits<4> Zn;
+  bits<3> Zk;
+  bits<2> Rv;
+  bits<4> Zm;
+  let Inst{31-24} = 0b11000000;
+  let Inst{23}    = v;
+  let Inst{22-20} = 0b110;
+  let Inst{19-16} = Zm;
+  let Inst{15}    = 0b0;
+  let Inst{14-13} = Rv;
+  let Inst{12-10} = Zk;
+  let Inst{9-6}   = Zn;
+  let Inst{5}     = 0b0;
+  let Inst{4-3}   = i2;
+  let Inst{2-0}   = off3;
+
+  let Constraints = "$ZA = $_ZA";
+  let Uses = [ FPCR, FPMR ];
+}
+
+multiclass sme2_fp8_fdot_za16_vg1x2<string mnemonic, bit v> {
+  def NAME : sme2_fp8_fdot_za16_vg1x2<mnemonic, v>;
+
+  def : InstAlias<mnemonic # "\t$ZA[$Rv, $off3], $Zn, $Zm$i2, $Zk",
+        (!cast<Instruction>(NAME) MatrixOp16:$ZA,  MatrixIndexGPR32Op8_11:$Rv,
+         sme_elm_idx0_7:$off3, ZZ_b_mul_r:$Zn, ZPR4b16:$Zm, VectorIndexS:$i2,
+         ZK_b:$Zk), 0>;
+}
diff --git a/llvm/test/MC/AArch64/SME/directives-negative.s b/llvm/test/MC/AArch64/SME/directives-negative.s
index 123c3a383d71e..fd669666b8ef8 100644
--- a/llvm/test/MC/AArch64/SME/directives-negative.s
+++ b/llvm/test/MC/AArch64/SME/directives-negative.s
@@ -18,6 +18,12 @@ addha za0.d, p0/m, p0/m, z0.d
 // CHECK: error: instruction requires: sme-i16i64
 // CHECK-NEXT: addha za0.d, p0/m, p0/m, z0.d
 
+.arch_extension sme-f16f8f16
+.arch_extension nosme-f16f8f16
+fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
+// CHECK: error: instruction requires: sme-f16f8f16
+// CHECK-NEXT: fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
+
 .arch armv9-a+sme
 .arch armv9-a+nosme
 zero {za}
@@ -35,3 +41,9 @@ fmopa za0.d, p0/m, p0/m, z0.d, z0.d
 addha za0.d, p0/m, p0/m, z0.d
 // CHECK: error: instruction requires: sme-i16i64
 // CHECK-NEXT: addha za0.d, p0/m, p0/m, z0.d
+
+.arch armv9-a+sme-f16f8f16
+.arch armv9-a+nosme-f16f8f16
+fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
+// CHECK: error: instruction requires: sme-f16f8f16
+// CHECK-NEXT: fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
diff --git a/llvm/test/MC/AArch64/SME/directives.s b/llvm/test/MC/AArch64/SME/directives.s
index ca3ba9c2f8e1e..492792255c1d0 100644
--- a/llvm/test/MC/AArch64/SME/directives.s
+++ b/llvm/test/MC/AArch64/SME/directives.s
@@ -18,6 +18,12 @@ addha za0.d, p0/m, p0/m, z0.d
 
 .arch_extension nosme-i16i64
 
+.arch_extension sme-f16f8f16
+fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
+// CHECK: fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
+
+.arch_extension nosme-f16f8f16
+
 .arch armv9-a+sme
 smstart
 // CHECK: smstart
@@ -33,3 +39,7 @@ fmopa za0.d, p0/m, p0/m, z0.d, z0.d
 .arch armv9-a+sme-i16i64
 addha za0.d, p0/m, p0/m, z0.d
 // CHECK: addha za0.d, p0/m, p0/m, z0.d
+
+.arch armv9-a+sme-f16f8f16
+fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
+// CHECK: fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
diff --git a/llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s b/llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s
new file mode 100644
index 0000000000000..118229593aa93
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s
@@ -0,0 +1,49 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme-f16f8f16 2>&1 < %s \
+// RUN:   | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid ZA tile
+
+fmopab za2.h, { z0.h, z1.h }, z0.b, z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmopab za2.h, { z0.h, z1.h }, z0.b, z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmopat za0.s, { z0.h, z1.h }, z0.b, z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-1].h
+// CHECK-NEXT: fmopat za0.s, { z0.h, z1.h }, z0.b, z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector list
+
+fmopab za0.h, { z1.h, z2.h }, z0.b, z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: fmopab za0.h, { z1.h, z2.h }, z0.b, z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmopat za0.h, { z0.h, z2.h }, z0.b, z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmopat za0.h, { z0.h, z2.h }, z0.b, z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector element width
+
+fmopab za0.h, { z0.h, z1.h }, z0.h, z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmopab za0.h, { z0.h, z1.h }, z0.h, z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid Zk register
+
+fmopat za0.h, { z0.h, z1.h }, z0.b, z19.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fmopat za0.h, { z0.h, z1.h }, z0.b, z19.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmopab za0.h, { z0.h, z1.h }, z0.b, z24.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fmopab za0.h, { z0.h, z1.h }, z0.b, z24.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2/fmopab-fmopat.s b/llvm/test/MC/AArch64/SME2/fmopab-fmopat.s
new file mode 100644
index 0000000000000..af965c21403b2
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/fmopab-fmopat.s
@@ -0,0 +1,38 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme-f16f8f16 < %s \
+// RUN:   | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme-f16f8f16 < %s \
+// RUN:   | llvm-objdump -d --mattr=+sme-f16f8f16 --no-print-imm-hex - \
+// RUN:   | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme-f16f8f16 < %s \
+// RUN:   | llvm-objdump -d --mattr=-sme-f16f8f16 --no-print-imm-hex - \
+// RUN:   | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme-f16f8f16 < %s \
+// RUN:   | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:   | llvm-mc -triple=aarch64 -mattr=+sme-f16f8f16 -disassemble -show-encoding \
+// RUN:   | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
+// CHECK-INST: fmopab za0.h, { z0.h, z1.h }, z0.b, z20.b
+// CHECK-ENCODING: encoding: [0x18,0x00,0xa0,0x80]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: 80a00018 <unknown>
+
+fmopab za1.h, { z30.h, z31.h }, z0.b, z23.b
+// CHECK-INST: fmopab za1.h, { z30.h, z31.h }, z0.b, z23.b
+// CHECK-ENCODING: encoding: [0xd9,0x0f,0xa0,0x80]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: 80a00fd9 <unknown>
+
+fmopat za0.h, { z0.h, z1.h }, z31.b, z28.b
+// CHECK-INST: fmopat za0.h, { z0.h, z1.h }, z31.b, z28.b
+// CHECK-ENCODING: encoding: [0x18,0x90,0xbf,0x80]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: 80bf9018 <unknown>
+
+fmopat za1.h, { z30.h, z31.h }, z31.b, z31.b
+// CHECK-INST: fmopat za1.h, { z30.h, z31.h }, z31.b, z31.b
+// CHECK-ENCODING: encoding: [0xd9,0x9f,0xbf,0x80]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: 80bf9fd9 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2/fp_dot-diagnostics.s b/llvm/test/MC/AArch64/SME2/fp_dot-diagnostics.s
new file mode 100644
index 0000000000000..ee281f0e5cd54
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/fp_dot-diagnostics.s
@@ -0,0 +1,166 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme-f16f8f16 2>&1 < %s \
+// RUN:   | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid vector select register
+
+fdot za.h[w7, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [w8, w11]
+// CHECK-NEXT: fdot za.h[w7, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w7, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [w8, w11]
+// CHECK-NEXT: fvdot za.h[w7, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w12, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [w8, w11]
+// CHECK-NEXT: fvdot za.h[w12, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fdot za.h[w12, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [w8, w11]
+// CHECK-NEXT: fdot za.h[w12, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector select offset
+
+fdot za.h[w8, -1, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 7].
+// CHECK-NEXT: fdot za.h[w8, -1, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, -1, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 7].
+// CHECK-NEXT: fvdot za.h[w8, -1, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 8, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 7].
+// CHECK-NEXT: fvdot za.h[w8, 8, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fdot za.h[w8, 8, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 7].
+// CHECK-NEXT: fdot za.h[w8, 8, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid matrix operand
+
+fdot za.s[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fdot za.s[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.s[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fvdot za.s[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector grouping
+
+fvdot za.h[w8, 0, vgx4], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx4], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fdot za.h[w8, 0, vgx4], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fdot za.h[w8, 0, vgx4], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector list
+
+fdot za.h[w8, 0, vgx2], { z0.b, z2.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fdot za.h[w8, 0, vgx2], { z0.b, z2.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 0, vgx2], { z0.b, z2.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx2], { z0.b, z2.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 0, vgx2], { z1.b, z2.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx2], { z1.b, z2.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fdot za.h[w8, 0, vgx2], { z1.b, z2.b }, z0.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fdot za.h[w8, 0, vgx2], { z1.b, z2.b }, z0.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid indexed vector register
+
+fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z16.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+// CHECK-NEXT: fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z16.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z16.h[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z16.h[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.s[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.s[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.s[0], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+// CHECK-NEXT: fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.s[0], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid lane index
+
+fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[-1], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[-1], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[-1], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[-1], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[4], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[4], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[4], z20.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[4], z20.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid Zk register
+
+fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z19.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z19.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z19.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z19.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z24.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z24.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z24.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z24.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME2/fp_dot.s b/llvm/test/MC/AArch64/SME2/fp_dot.s
new file mode 100644
index 0000000000000..b2bf5125dee81
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/fp_dot.s
@@ -0,0 +1,62 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme-f16f8f16 < %s \
+// RUN:   | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme-f16f8f16 < %s \
+// RUN:   | llvm-objdump -d --mattr=+sme-f16f8f16 --no-print-imm-hex - \
+// RUN:   | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme-f16f8f16 < %s \
+// RUN:   | llvm-objdump -d --mattr=-sme-f16f8f16 --no-print-imm-hex - \
+// RUN:   | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme-f16f8f16 < %s \
+// RUN:   | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:   | llvm-mc -triple=aarch64 -mattr=+sme-f16f8f16 -disassemble -show-encoding \
+// RUN:   | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-INST: fdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-ENCODING: encoding: [0x00,0x00,0x60,0xc0]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: c0600000 <unknown>
+
+fdot za.h[w8, 7], { z30.b, z31.b }, z15.h[3], z23.b
+// CHECK-INST: fdot za.h[w8, 7, vgx2], { z30.b, z31.b }, z15.h[3], z23.b
+// CHECK-ENCODING: encoding: [0xdf,0x0f,0x6f,0xc0]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: c06f0fdf <unknown>
+
+fdot za.h[w11, 0, vgx2], { z0.b, z1.b }, z15.h[3], z28.b
+// CHECK-INST: fdot za.h[w11, 0, vgx2], { z0.b, z1.b }, z15.h[3], z28.b
+// CHECK-ENCODING: encoding: [0x18,0x70,0x6f,0xc0]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: c06f7018 <unknown>
+
+fdot za.h[w11, 7], { z30.b, z31.b }, z0.h[0], z31.b
+// CHECK-INST: fdot za.h[w11, 7, vgx2], { z30.b, z31.b }, z0.h[0], z31.b
+// CHECK-ENCODING: encoding: [0xc7,0x7f,0x60,0xc0]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: c0607fc7 <unknown>
+
+fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-INST: fvdot za.h[w8, 0, vgx2], { z0.b, z1.b }, z0.h[0], z20.b
+// CHECK-ENCODING: encoding: [0x00,0x00,0xe0,0xc0]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: c0e00000 <unknown>
+
+fvdot za.h[w8, 7], { z30.b, z31.b }, z15.h[3], z23.b
+// CHECK-INST: fvdot za.h[w8, 7, vgx2], { z30.b, z31.b }, z15.h[3], z23.b
+// CHECK-ENCODING: encoding: [0xdf,0x0f,0xef,0xc0]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: c0ef0fdf <unknown>
+
+fvdot za.h[w11, 0, vgx2], { z0.b, z1.b }, z15.h[3], z28.b
+// CHECK-INST: fvdot za.h[w11, 0, vgx2], { z0.b, z1.b }, z15.h[3], z28.b
+// CHECK-ENCODING: encoding: [0x18,0x70,0xef,0xc0]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: c0ef7018 <unknown>
+
+fvdot za.h[w11, 7], { z30.b, z31.b }, z0.h[0], z31.b
+// CHECK-INST: fvdot za.h[w11, 7, vgx2], { z30.b, z31.b }, z0.h[0], z31.b
+// CHECK-ENCODING: encoding: [0xc7,0x7f,0xe0,0xc0]
+// CHECK-ERROR: instruction requires: sme-f16f8f16
+// CHECK-UNKNOWN: c0e07fc7 <unknown>
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 192f22fb5b79d..40835817040fa 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -1510,6 +1510,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
       AArch64::AEK_MTETC,        AArch64::AEK_HINTE,
       AArch64::AEK_CFLT,         AArch64::AEK_LSC64B,
       AArch64::AEK_SVE_RCPC,     AArch64::AEK_SVE_PERM256,
+      AArch64::AEK_SME_F16F8F16,
   };
 
   std::vector<StringRef> Features;
@@ -1638,6 +1639,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
   EXPECT_TRUE(llvm::is_contained(Features, "+lsc64b"));
   EXPECT_TRUE(llvm::is_contained(Features, "+sve-rcpc"));
   EXPECT_TRUE(llvm::is_contained(Features, "+sve-perm256"));
+  EXPECT_TRUE(llvm::is_contained(Features, "+sme-f16f8f16"));
 
   // Assuming we listed every extension above, this should produce the same
   // result.
@@ -1823,6 +1825,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
       {"lsc64b", "nolsc64b", "+lsc64b", "-lsc64b"},
       {"sve-rcpc", "nosve-rcpc", "+sve-rcpc", "-sve-rcpc"},
       {"sve-perm256", "nosve-perm256", "+sve-perm256", "-sve-perm256"},
+      {"sme-f16f8f16", "nosme-f16f8f16", "+sme-f16f8f16", "-sme-f16f8f16"},
   };
 
   for (unsigned i = 0; i < std::size(ArchExt); i++) {
@@ -2191,7 +2194,7 @@ AArch64ExtensionDependenciesBaseArchTestParams
         {AArch64::ARMV8A, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}},
 
         // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16,
-        // sme-f8f32, sme-b16b16, ssve-aes}
+        // sme-f8f32, sme-b16b16, sme-f16f8f16, ssve-aes}
         {AArch64::ARMV8A, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}},
         {AArch64::ARMV8A, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}},
         {AArch64::ARMV8A,
@@ -2224,6 +2227,14 @@ AArch64ExtensionDependenciesBaseArchTestParams
         {AArch64::ARMV8A, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}},
         {AArch64::ARMV8A, {"nosme2", "sme-b16b16"}, {"sme2", "sme-b16b16"}, {}},
         {AArch64::ARMV8A, {"sme-b16b16", "nosme2"}, {}, {"sme2", "sme-b16b16"}},
+        {AArch64::ARMV8A,
+         {"nosme2", "sme-f16f8f16"},
+         {"sme2", "sme-f16f8f16"},
+         {}},
+        {AArch64::ARMV8A,
+         {"sme-f16f8f16", "nosme2"},
+         {},
+         {"sme2", "sme-f16f8f16"}},
         {AArch64::ARMV9_6A, {"nosme2", "ssve-aes"}, {"sme2", "ssve-aes"}, {}},
         {AArch64::ARMV9_6A, {"ssve-aes", "nosme2"}, {}, {"ssve-aes", "sme2"}},
 
@@ -2235,12 +2246,20 @@ AArch64ExtensionDependenciesBaseArchTestParams
         {AArch64::ARMV9_7A, {"nosme2p2", "sme2p3"}, {"sme2p3", "sme2p2"}, {}},
         {AArch64::ARMV9_7A, {"sme2p3", "nosme2p2"}, {}, {"sme2p2", "sme2p3"}},
 
-        // fp8 -> {sme-f8f16, sme-f8f32, f8f16mm, f8f32mm, fp8dot4, fp8dot2,
-        // ssve-fp8dot4, ssve-fp8dot2}
+        // fp8 -> {sme-f8f16, sme-f8f32, sme-f16f8f16, f8f16mm, f8f32mm,
+        // fp8dot4, fp8dot2, ssve-fp8dot4, ssve-fp8dot2}
         {AArch64::ARMV8A, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}},
         {AArch64::ARMV8A, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}},
         {AArch64::ARMV8A, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}},
         {AArch64::ARMV8A, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}},
+        {AArch64::ARMV8A,
+         {"nofp8", "sme-f16f8f16"},
+         {"fp8", "sme-f16f8f16"},
+         {}},
+        {AArch64::ARMV8A,
+         {"sme-f16f8f16", "nofp8"},
+         {},
+         {"fp8", "sme-f16f8f16"}},
         {AArch64::ARMV9_6A, {"nofp8", "f8f16mm"}, {"fp8", "f8f16mm"}, {}},
         {AArch64::ARMV9_6A, {"f8f16mm", "nofp8"}, {}, {"fp8", "f8f16mm"}},
         {AArch64::ARMV9_6A, {"nofp8", "f8f32mm"}, {"fp8", "f8f32mm"}, {}},

>From 92d83c4ee7cf3b1e69eeea3d2dc060604d392081 Mon Sep 17 00:00:00 2001
From: Martin Wehking <martin.wehking at arm.com>
Date: Wed, 14 Oct 2026 10:03:01 +0000
Subject: [PATCH 2/2] fixup! Extend diagnostic test ranges

---
 .../AArch64/SME2/fmopab-fmopat-diagnostics.s  | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s b/llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s
index 118229593aa93..e789edfdc90bf 100644
--- a/llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s
+++ b/llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s
@@ -43,7 +43,27 @@ fmopat za0.h, { z0.h, z1.h }, z0.b, z19.b
 // CHECK-NEXT: fmopat za0.h, { z0.h, z1.h }, z0.b, z19.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
+fmopab za0.h, { z0.h, z1.h }, z0.b, z19.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fmopab za0.h, { z0.h, z1.h }, z0.b, z19.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmopat za0.h, { z0.h, z1.h }, z0.b, z24.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fmopat za0.h, { z0.h, z1.h }, z0.b, z24.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
 fmopab za0.h, { z0.h, z1.h }, z0.b, z24.b
 // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
 // CHECK-NEXT: fmopab za0.h, { z0.h, z1.h }, z0.b, z24.b
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmopat za0.h, { z0.h, z1.h }, z0.b, z27.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fmopat za0.h, { z0.h, z1.h }, z0.b, z27.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmopab za0.h, { z0.h, z1.h }, z0.b, z27.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20.b..z23.b or z28.b..z31.b
+// CHECK-NEXT: fmopab za0.h, { z0.h, z1.h }, z0.b, z27.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:



More information about the llvm-branch-commits mailing list