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

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Oct 13 02:59:02 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-backend-aarch64

Author: Martin Wehking (MartinWehking)

<details>
<summary>Changes</summary>

Add support for FEAT_SME_F16F8F16 (SME half-precision and FP8 sum-of-products accumulating to half-precision instructions).

---

Patch is 31.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/231435.diff


15 Files Affected:

- (modified) clang/test/Driver/aarch64-vfat.c (+4) 
- (modified) clang/test/Driver/print-supported-extensions-aarch64.c (+1) 
- (modified) llvm/lib/Target/AArch64/AArch64Features.td (+4) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+2) 
- (modified) llvm/lib/Target/AArch64/AArch64RegisterInfo.td (+6) 
- (modified) llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td (+9) 
- (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+5) 
- (modified) llvm/lib/Target/AArch64/SMEInstrFormats.td (+57) 
- (modified) llvm/test/MC/AArch64/SME/directives-negative.s (+12) 
- (modified) llvm/test/MC/AArch64/SME/directives.s (+10) 
- (added) llvm/test/MC/AArch64/SME2/fmopab-fmopat-diagnostics.s (+49) 
- (added) llvm/test/MC/AArch64/SME2/fmopab-fmopat.s (+38) 
- (added) llvm/test/MC/AArch64/SME2/fp_dot-diagnostics.s (+166) 
- (added) llvm/test/MC/AArch64/SME2/fp_dot.s (+62) 
- (modified) llvm/unittests/TargetParser/TargetParserTest.cpp (+22-3) 


``````````diff
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 c65c5760179e5..55465def571bb 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 ef790f6b463bc..a9e5b4f8f0a58 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 25f2bfaf2ac3c..0d1152dadfd4b 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -241,6 +241,8 @@ def HasCFLT          : Predicate<"Subtarget->hasCFLT()">,
                                  AssemblerPredicateWithAll<(all_of FeatureCFLT), "cflt">;
 def HasLSC64B        : Predicate<"Subtarget->hasLSC64B()">,
                                  AssemblerPredicateWithAll<(all_of FeatureLSC64B), "lsc64b">;
+def HasSMEF16F8F16   : Predicate<"Subtarget->isStreaming() && Subtarget->hasSMEF16F8F16()">,
+                                 AssemblerPredicateWithAll<(all_of FeatureSMEF16F8F16), "sme-f16f8f16">;
 def HasSVE_PERM256     : Predicate<"Subtarget->hasSVE_PERM256()">,
                                  AssemblerPredicateWithAll<(all_of FeatureSVE_PERM256), "sve-perm256">;
 def HasSVE_LRCPC     : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasSVE_LRCPC()">,
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 14cbf038f579c..49c253c658b69 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-lrcpc"}, {AArch64::FeatureSVE_LRCPC}},
     {{"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], { z...
[truncated]

``````````

</details>


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


More information about the llvm-branch-commits mailing list