diff --git a/clang/test/Driver/aarch64-v97a.c b/clang/test/Driver/aarch64-v97a.c index a607c1f92ed07..1392029ecda6e 100644 --- a/clang/test/Driver/aarch64-v97a.c +++ b/clang/test/Driver/aarch64-v97a.c @@ -26,6 +26,14 @@ // RUN: %clang -target aarch64 -march=armv9.7-a+sve2p3 -### -c %s 2>&1 | FileCheck -check-prefix=V97A-SVE2p3 %s // V97A-SVE2p3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+sve2p3" +// RUN: %clang -target aarch64 -march=armv9.7a+sve-b16mm -### -c %s 2>&1 | FileCheck -check-prefix=V97A-SVE-B16MM %s +// RUN: %clang -target aarch64 -march=armv9.7-a+sve-b16mm -### -c %s 2>&1 | FileCheck -check-prefix=V97A-SVE-B16MM %s +// V97A-SVE-B16MM: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+sve-b16mm" + +// RUN: %clang -target aarch64 -march=armv9.7a+f16mm -### -c %s 2>&1 | FileCheck -check-prefix=V97A-F16MM %s +// RUN: %clang -target aarch64 -march=armv9.7-a+f16mm -### -c %s 2>&1 | FileCheck -check-prefix=V97A-F16MM %s +// V97A-F16MM: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+f16mm" + // RUN: %clang -target aarch64 -march=armv9.7a+cmh -### -c %s 2>&1 | FileCheck -check-prefix=V97A-CMH %s // RUN: %clang -target aarch64 -march=armv9.7-a+cmh -### -c %s 2>&1 | FileCheck -check-prefix=V97A-CMH %s // V97A-CMH: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+cmh" diff --git a/clang/test/Driver/print-supported-extensions-aarch64.c b/clang/test/Driver/print-supported-extensions-aarch64.c index ef53f9fba4c43..50c3610123646 100644 --- a/clang/test/Driver/print-supported-extensions-aarch64.c +++ b/clang/test/Driver/print-supported-extensions-aarch64.c @@ -18,6 +18,7 @@ // CHECK-NEXT: d128 FEAT_D128, FEAT_LVA3, FEAT_SYSREG128, FEAT_SYSINSTR128 Enable Armv9.4-A 128-bit Page Table Descriptors, System Registers and instructions // CHECK-NEXT: dit FEAT_DIT Enable Armv8.4-A Data Independent Timing instructions // CHECK-NEXT: dotprod FEAT_DotProd Enable dot product support +// CHECK-NEXT: f16mm FEAT_F16MM Enable Armv9.7-A non-widening half-precision matrix multiply-accumulate // CHECK-NEXT: f32mm FEAT_F32MM Enable Matrix Multiply FP32 Extension // CHECK-NEXT: f64mm FEAT_F64MM Enable Matrix Multiply FP64 Extension // CHECK-NEXT: f8f16mm FEAT_F8F16MM Enable Armv9.6-A FP8 to Half-Precision Matrix Multiplication @@ -95,6 +96,7 @@ // CHECK-NEXT: sve-aes FEAT_SVE_AES, FEAT_SVE_PMULL128 Enable SVE AES and quadword SVE polynomial multiply instructions // CHECK-NEXT: sve-aes2 FEAT_SVE_AES2 Enable Armv9.6-A SVE multi-vector AES and multi-vector quadword polynomial multiply instructions // CHECK-NEXT: sve-b16b16 FEAT_SVE_B16B16 Enable SVE2 non-widening and SME2 Z-targeting non-widening BFloat16 instructions +// CHECK-NEXT: sve-b16mm FEAT_SVE_B16MM Enable Armv9.7-A SVE non-widening BFloat16 matrix multiply-accumulate // CHECK-NEXT: sve-bfscale FEAT_SVE_BFSCALE Enable Armv9.6-A SVE BFloat16 scaling instructions // 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 diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index 463465310c95b..a4529a5844ab7 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -74,7 +74,7 @@ def SVEUnsupported : AArch64Unsupported { } def SME2p3Unsupported : AArch64Unsupported { - let F = [HasSVE2p3_or_SME2p3]; + let F = [HasSVE2p3_or_SME2p3, HasSVE_B16MM]; } def SME2p2Unsupported : AArch64Unsupported { diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td index 22e1e6ea3de4a..5f943d39321f9 100644 --- a/llvm/lib/Target/AArch64/AArch64Features.td +++ b/llvm/lib/Target/AArch64/AArch64Features.td @@ -613,6 +613,12 @@ def FeatureSVE2p3 : ExtensionWithMArch<"sve2p3", "SVE2p3", "FEAT_SVE2p3", def FeatureSME2p3 : ExtensionWithMArch<"sme2p3", "SME2p3", "FEAT_SME2p3", "Enable Armv9.7-A Scalable Matrix Extension 2.3 instructions", [FeatureSME2p2]>; +def FeatureSVE_B16MM : ExtensionWithMArch<"sve-b16mm", "SVE_B16MM", "FEAT_SVE_B16MM", + "Enable Armv9.7-A SVE non-widening BFloat16 matrix multiply-accumulate", [FeatureSVE]>; + +def FeatureF16MM : ExtensionWithMArch<"f16mm", "F16MM", "FEAT_F16MM", + "Enable Armv9.7-A non-widening half-precision matrix multiply-accumulate", [FeatureFullFP16]>; + //===----------------------------------------------------------------------===// // Other Features //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 6bdfbecaa2759..9f7d6ddea31e5 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -246,6 +246,12 @@ def HasCMH : Predicate<"Subtarget->hasCMH()">, AssemblerPredicateWithAll<(all_of FeatureCMH), "cmh">; def HasLSCP : Predicate<"Subtarget->hasLSCP()">, AssemblerPredicateWithAll<(all_of FeatureLSCP), "lscp">; +def HasSVE2p2 : Predicate<"Subtarget->hasSVE2p2()">, + AssemblerPredicateWithAll<(all_of FeatureSVE2p2), "sve2p2">; +def HasSVE_B16MM : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasSVE_B16MM()">, + AssemblerPredicateWithAll<(all_of FeatureSVE_B16MM), "sve-b16mm">; +def HasF16MM : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasF16MM()">, + AssemblerPredicateWithAll<(all_of FeatureF16MM), "f16mm">; // 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/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 0d82e8c7798cf..04bb3b1e41293 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -2569,7 +2569,7 @@ let Predicates = [HasBF16, HasSVE_or_SME] in { } // End HasBF16, HasSVE_or_SME let Predicates = [HasBF16, HasSVE] in { - defm BFMMLA_ZZZ_HtoS : sve_fp_matrix_mla<0b01, "bfmmla", ZPR32, ZPR16, int_aarch64_sve_bfmmla, nxv4f32, nxv8bf16>; + defm BFMMLA_ZZZ_HtoS : sve_fp_matrix_mla<0b011, "bfmmla", ZPR32, ZPR16, int_aarch64_sve_bfmmla, nxv4f32, nxv8bf16>; } // End HasBF16, HasSVE let Predicates = [HasBF16, HasSVE_or_SME] in { @@ -3680,15 +3680,15 @@ let Predicates = [HasSVE_or_SME, HasMatMulInt8] in { } // End HasSVE_or_SME, HasMatMulInt8 let Predicates = [HasSVE, HasMatMulFP32] in { - defm FMMLA_ZZZ_S : sve_fp_matrix_mla<0b10, "fmmla", ZPR32, ZPR32, int_aarch64_sve_fmmla, nxv4f32, nxv4f32>; + defm FMMLA_ZZZ_S : sve_fp_matrix_mla<0b101, "fmmla", ZPR32, ZPR32, int_aarch64_sve_fmmla, nxv4f32, nxv4f32>; } // End HasSVE, HasMatMulFP32 let Predicates = [HasSVE_F16F32MM] in { - def FMLLA_ZZZ_HtoS : sve_fp_matrix_mla<0b00, "fmmla", ZPR32, ZPR16>; + def FMLLA_ZZZ_HtoS : sve_fp_matrix_mla<0b001, "fmmla", ZPR32, ZPR16>; } // End HasSVE_F16F32MM let Predicates = [HasSVE, HasMatMulFP64] in { - defm FMMLA_ZZZ_D : sve_fp_matrix_mla<0b11, "fmmla", ZPR64, ZPR64, int_aarch64_sve_fmmla, nxv2f64, nxv2f64>; + defm FMMLA_ZZZ_D : sve_fp_matrix_mla<0b111, "fmmla", ZPR64, ZPR64, int_aarch64_sve_fmmla, nxv2f64, nxv2f64>; defm LD1RO_B_IMM : sve_mem_ldor_si<0b00, "ld1rob", Z_b, ZPR8, nxv16i8, nxv16i1, AArch64ld1ro_z>; defm LD1RO_H_IMM : sve_mem_ldor_si<0b01, "ld1roh", Z_h, ZPR16, nxv8i16, nxv8i1, AArch64ld1ro_z>; defm LD1RO_W_IMM : sve_mem_ldor_si<0b10, "ld1row", Z_s, ZPR32, nxv4i32, nxv4i1, AArch64ld1ro_z>; @@ -4631,8 +4631,30 @@ let Predicates = [HasSVE2p3_or_SME2p3] in { defm SABAL_ZZZ : sve2_int_two_way_absdiff_accum_long<0b0, "sabal">; defm UABAL_ZZZ : sve2_int_two_way_absdiff_accum_long<0b1, "uabal">; + // SVE2 integer dot product + def SDOT_ZZZ_BtoH : sve_intx_dot<0b01, 0b00000, 0b0, "sdot", ZPR16, ZPR8>; + def UDOT_ZZZ_BtoH : sve_intx_dot<0b01, 0b00000, 0b1, "udot", ZPR16, ZPR8>; + + // SVE2 integer indexed dot product + def SDOT_ZZZI_BtoH : sve_intx_dot_by_indexed_elem_x<0b0, "sdot">; + def UDOT_ZZZI_BtoH : sve_intx_dot_by_indexed_elem_x<0b1, "udot">; + } // End HasSME2p3orSVE2p3 +//===----------------------------------------------------------------------===// +// SVE_B16MM Instructions +//===----------------------------------------------------------------------===// +let Predicates = [HasSVE_B16MM] in { + def BFMMLA_ZZZ_H : sve_fp_matrix_mla<0b110, "bfmmla", ZPR16, ZPR16>; +} + +//===----------------------------------------------------------------------===// +// F16MM Instructions +//===----------------------------------------------------------------------===// +let Predicates = [HasSVE2p2, HasF16MM] in { + def FMMLA_ZZZ_H : sve_fp_matrix_mla<0b100, "fmmla", ZPR16, ZPR16>; +} + //===----------------------------------------------------------------------===// // SME2.2 or SVE2.2 instructions - Legal in streaming mode iff target has SME2p2 //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 4bfc74f7aa984..d9f3c4ffd5226 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3892,6 +3892,8 @@ static const struct Extension { {"gcie", {AArch64::FeatureGCIE}}, {"sme2p3", {AArch64::FeatureSME2p3}}, {"sve2p3", {AArch64::FeatureSVE2p3}}, + {"sve-b16mm", {AArch64::FeatureSVE_B16MM}}, + {"f16mm", {AArch64::FeatureF16MM}}, }; static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) { diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 337c6b694a505..21b9310f69159 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -3787,7 +3787,7 @@ multiclass sve2p1_two_way_dot_vv : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop), @@ -3795,8 +3795,7 @@ class sve_intx_dot_by_indexed_elem, Sched<[]> { bits<5> Zda; bits<5> Zn; - let Inst{31-23} = 0b010001001; - let Inst{22} = sz; + let Inst{31-24} = 0b01000100; let Inst{21} = 0b1; let Inst{15-11} = 0; let Inst{10} = U; @@ -3810,16 +3809,18 @@ class sve_intx_dot_by_indexed_elem { - def _BtoS : sve_intx_dot_by_indexed_elem<0b0, opc, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b_timm> { + def _BtoS : sve_intx_dot_by_indexed_elem { bits<2> iop; bits<3> Zm; + let Inst{23-22} = 0b10; let Inst{20-19} = iop; let Inst{18-16} = Zm; } - def _HtoD : sve_intx_dot_by_indexed_elem<0b1, opc, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b_timm> { + def _HtoD : sve_intx_dot_by_indexed_elem { bits<1> iop; bits<4> Zm; - let Inst{20} = iop; + let Inst{23-22} = 0b11; + let Inst{20} = iop; let Inst{19-16} = Zm; } @@ -3827,6 +3828,16 @@ multiclass sve_intx_dot_by_indexed_elem(NAME # _HtoD)>; } +class sve_intx_dot_by_indexed_elem_x +: sve_intx_dot_by_indexed_elem { + bits<3> iop; + bits<3> Zm; + let Inst{23} = 0b0; + let Inst{22} = iop{2-2}; + let Inst{20-19} = iop{1-0}; + let Inst{18-16} = Zm; +} + //===----------------------------------------------------------------------===// // SVE2 Complex Integer Dot Product Group //===----------------------------------------------------------------------===// @@ -9616,17 +9627,18 @@ multiclass sve_int_dot_mixed_indexed { // SVE Floating Point Matrix Multiply Accumulate Group //===----------------------------------------------------------------------===// -class sve_fp_matrix_mla opc, string asm, ZPRRegOp zda_ty, ZPRRegOp reg_ty> +class sve_fp_matrix_mla opc, string asm, ZPRRegOp zda_ty, ZPRRegOp reg_ty> : I<(outs zda_ty:$Zda), (ins zda_ty:$_Zda, reg_ty:$Zn, reg_ty:$Zm), asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> { bits<5> Zda; bits<5> Zn; bits<5> Zm; let Inst{31-24} = 0b01100100; - let Inst{23-22} = opc; + let Inst{23-22} = opc{2-1}; let Inst{21} = 1; let Inst{20-16} = Zm; - let Inst{15-10} = 0b111001; + let Inst{15-11} = 0b11100; + let Inst{10} = opc{0}; let Inst{9-5} = Zn; let Inst{4-0} = Zda; @@ -9636,10 +9648,12 @@ class sve_fp_matrix_mla opc, string asm, ZPRRegOp zda_ty, ZPRRegOp reg_t let mayRaiseFPException = 1; } -multiclass sve_fp_matrix_mla opc, string asm, ZPRRegOp zda_ty, ZPRRegOp reg_ty, SDPatternOperator op, ValueType zda_vt, ValueType reg_vt> { +multiclass sve_fp_matrix_mla opc, string asm, ZPRRegOp zda_ty, + ZPRRegOp reg_ty, SDPatternOperator op, + ValueType zda_vt, ValueType reg_vt> { def NAME : sve_fp_matrix_mla; - def : SVE_3_Op_Pat(NAME)>; + def : SVE_3_Op_Pat(NAME)>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AArch64/SVE/bfmmla-diagnostics.s b/llvm/test/MC/AArch64/SVE/bfmmla-diagnostics.s index 409c2c5741cab..4695b050a681e 100644 --- a/llvm/test/MC/AArch64/SVE/bfmmla-diagnostics.s +++ b/llvm/test/MC/AArch64/SVE/bfmmla-diagnostics.s @@ -5,11 +5,6 @@ bfmmla z0.s, z1.s, z2.h // CHECK-NEXT: bfmmla z0.s, z1.s, z2.h // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: -bfmmla z0.h, z1.h, z2.h -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width -// CHECK-NEXT: bfmmla z0.h, z1.h, z2.h -// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: - bfmmla z0.s, z1.h, z2.s // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width // CHECK-NEXT: bfmmla z0.s, z1.h, z2.s diff --git a/llvm/test/MC/AArch64/SVE2p1/sdot-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/sdot-diagnostics.s index 344abb1fe9082..42c6ae7da156b 100644 --- a/llvm/test/MC/AArch64/SVE2p1/sdot-diagnostics.s +++ b/llvm/test/MC/AArch64/SVE2p1/sdot-diagnostics.s @@ -29,7 +29,7 @@ sdot z0.s, z0.h, z0.h[-1] // Invalid vector suffix sdot z0.h, z0.s, z0.s -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction // CHECK-NEXT: sdot z0.h, z0.s, z0.s // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2p1/udot-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/udot-diagnostics.s index 0debddf82b37c..aa2ec7f4d3204 100644 --- a/llvm/test/MC/AArch64/SVE2p1/udot-diagnostics.s +++ b/llvm/test/MC/AArch64/SVE2p1/udot-diagnostics.s @@ -29,11 +29,11 @@ udot z0.s, z0.h, z0.h[-1] // Invalid vector suffix udot z0.h, z0.s, z0.s -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction // CHECK-NEXT: udot z0.h, z0.s, z0.s // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: udot z0.h, z0.s, z0.s[1] -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction // CHECK-NEXT: udot z0.h, z0.s, z0.s[1] // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2p2/fmmla-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/fmmla-diagnostics.s new file mode 100644 index 0000000000000..1a48582cfc742 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p2/fmmla-diagnostics.s @@ -0,0 +1,24 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2,+f16mm 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid element width + +fmmla z0.b, z0.b, z0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmmla z0.b, z0.b, z0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +fmmla z0.h, z0.h, z0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: fmmla z0.h, z0.h, z0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +fmmla z0.h, z0.h, z0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: fmmla z0.h, z0.h, z0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2p2/fmmla.s b/llvm/test/MC/AArch64/SVE2p2/fmmla.s new file mode 100644 index 0000000000000..19929a921dba6 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p2/fmmla.s @@ -0,0 +1,45 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2,+f16mm < %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=+sve2p2,+f16mm < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2p2,+f16mm --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p2,+f16mm < %s \ +// RUN: | llvm-objdump -d --mattr=-sve2p2,-f16mm --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2,+f16mm < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p2,+f16mm -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +fmmla z0.h, z0.h, z0.h +// CHECK-INST: fmmla z0.h, z0.h, z0.h +// CHECK-ENCODING: encoding: [0x00,0xe0,0xa0,0x64] +// CHECK-ERROR: instruction requires: f16mm sve2p2 +// CHECK-UNKNOWN: 64a0e000 + +fmmla z10.h, z10.h, z10.h +// CHECK-INST: fmmla z10.h, z10.h, z10.h +// CHECK-ENCODING: encoding: [0x4a,0xe1,0xaa,0x64] +// CHECK-ERROR: instruction requires: f16mm sve2p2 +// CHECK-UNKNOWN: 64aae14a + +fmmla z21.h, z21.h, z21.h +// CHECK-INST: fmmla z21.h, z21.h, z21.h +// CHECK-ENCODING: encoding: [0xb5,0xe2,0xb5,0x64] +// CHECK-ERROR: instruction requires: f16mm sve2p2 +// CHECK-UNKNOWN: 64b5e2b5 + +fmmla z31.h, z31.h, z31.h +// CHECK-INST: fmmla z31.h, z31.h, z31.h +// CHECK-ENCODING: encoding: [0xff,0xe3,0xbf,0x64] +// CHECK-ERROR: instruction requires: f16mm sve2p2 +// CHECK-UNKNOWN: 64bfe3ff + +movprfx z0, z7 +fmmla z0.h, z1.h, z2.h +// CHECK-INST: movprfx z0, z7 +// CHECK-INST: fmmla z0.h, z1.h, z2.h +// CHECK-ENCODING: encoding: [0x20,0xe0,0xa2,0x64] +// CHECK-ERROR: instruction requires: f16mm sve2p2 +// CHECK-UNKNOWN: 64a2e020 diff --git a/llvm/test/MC/AArch64/SVE2p3/bfmmla-diagnostics.s b/llvm/test/MC/AArch64/SVE2p3/bfmmla-diagnostics.s new file mode 100644 index 0000000000000..dc85e527d16a7 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p3/bfmmla-diagnostics.s @@ -0,0 +1,34 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve-b16mm 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid element width + +bfmmla z0.h, z0.b, z0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: bfmmla z0.h, z0.b, z0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bfmmla z0.s, z0.s, z0.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: bfmmla z0.s, z0.s, z0.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bfmmla z0.d, z0.d, z0.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: bfmmla z0.d, z0.d, z0.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +bfmmla z0.h, z0.h, z0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: bfmmla z0.h, z0.h, z0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +bfmmla z0.h, z0.h, z0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: bfmmla z0.h, z0.h, z0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2p3/bfmmla.s b/llvm/test/MC/AArch64/SVE2p3/bfmmla.s new file mode 100644 index 0000000000000..77440eeb30f97 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p3/bfmmla.s @@ -0,0 +1,45 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve-b16mm < %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=+sve-b16mm < %s \ +// RUN: | llvm-objdump -d --mattr=+sve-b16mm --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve-b16mm < %s \ +// RUN: | llvm-objdump -d --mattr=-sve-b16mm --no-print-imm-hex - | 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-b16mm < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve-b16mm -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +bfmmla z0.h, z0.h, z0.h +// CHECK-INST: bfmmla z0.h, z0.h, z0.h +// CHECK-ENCODING: encoding: [0x00,0xe0,0xe0,0x64] +// CHECK-ERROR: instruction requires: sve-b16mm +// CHECK-UNKNOWN: 64e0e000 + +bfmmla z10.h, z10.h, z10.h +// CHECK-INST: bfmmla z10.h, z10.h, z10.h +// CHECK-ENCODING: encoding: [0x4a,0xe1,0xea,0x64] +// CHECK-ERROR: instruction requires: sve-b16mm +// CHECK-UNKNOWN: 64eae14a + +bfmmla z21.h, z21.h, z21.h +// CHECK-INST: bfmmla z21.h, z21.h, z21.h +// CHECK-ENCODING: encoding: [0xb5,0xe2,0xf5,0x64] +// CHECK-ERROR: instruction requires: sve-b16mm +// CHECK-UNKNOWN: 64f5e2b5 + +bfmmla z31.h, z31.h, z31.h +// CHECK-INST: bfmmla z31.h, z31.h, z31.h +// CHECK-ENCODING: encoding: [0xff,0xe3,0xff,0x64] +// CHECK-ERROR: instruction requires: sve-b16mm +// CHECK-UNKNOWN: 64ffe3ff + +movprfx z0, z7 +bfmmla z0.h, z1.h, z2.h +// CHECK-INST: movprfx z0, z7 +// CHECK-INST: bfmmla z0.h, z1.h, z2.h +// CHECK-ENCODING: encoding: [0x20,0xe0,0xe2,0x64] +// CHECK-ERROR: instruction requires: sve-b16mm +// CHECK-UNKNOWN: 64e2e020 diff --git a/llvm/test/MC/AArch64/SVE2p3/dot-diagnostics.s b/llvm/test/MC/AArch64/SVE2p3/dot-diagnostics.s new file mode 100644 index 0000000000000..b6f2f35a2fdc1 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p3/dot-diagnostics.s @@ -0,0 +1,188 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid element width + +sdot z0.b, z0.b, z0.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.b, z0.b, z0.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.h, z0.h, z0.h[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.h, z0.h, z0.h[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.s, z0.s, z0.s[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.s, z0.s, z0.s[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.d, z0.d, z0.d[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.d, z0.d, z0.d[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.d, z0.s, z0.s[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.d, z0.s, z0.s[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.b, z0.b, z0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.b, z0.b, z0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.h, z0.h, z0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.h, z0.h, z0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.s, z0.s, z0.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.s, z0.s, z0.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.d, z0.d, z0.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.d, z0.d, z0.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.d, z0.s, z0.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdot z0.d, z0.s, z0.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.b, z0.b, z0.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.b, z0.b, z0.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.h, z0.h, z0.h[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.h, z0.h, z0.h[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.s, z0.s, z0.s[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.s, z0.s, z0.s[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.d, z0.d, z0.d[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.d, z0.d, z0.d[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.d, z0.s, z0.s[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.d, z0.s, z0.s[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.b, z0.b, z0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.b, z0.b, z0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.h, z0.h, z0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.h, z0.h, z0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.s, z0.s, z0.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.s, z0.s, z0.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.d, z0.d, z0.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.d, z0.d, z0.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.d, z0.s, z0.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udot z0.d, z0.s, z0.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid register range and index + +sdot z0.h, z0.b, z8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: sdot z0.h, z0.b, z8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.h, z0.b, z0.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: sdot z0.h, z0.b, z0.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdot z0.h, z0.b, z0.b[8] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: sdot z0.h, z0.b, z0.b[8] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.h, z0.b, z8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: udot z0.h, z0.b, z8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.h, z0.b, z0.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: udot z0.h, z0.b, z0.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udot z0.h, z0.b, z0.b[8] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: udot z0.h, z0.b, z0.b[8] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.h, p0/m, z7.h +sdot z0.h, z0.b, z0.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: sdot z0.h, z0.b, z0.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +sdot z0.h, z0.b, z0.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: sdot z0.h, z0.b, z0.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.h, p0/m, z7.h +sdot z0.h, z0.b, z0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: sdot z0.h, z0.b, z0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +sdot z0.h, z0.b, z0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: sdot z0.h, z0.b, z0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.h, p0/m, z7.h +udot z0.h, z0.b, z0.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: udot z0.h, z0.b, z0.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +udot z0.h, z0.b, z0.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: udot z0.h, z0.b, z0.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0.h, p0/m, z7.h +udot z0.h, z0.b, z0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: udot z0.h, z0.b, z0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z0, z7 +udot z0.h, z0.b, z0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx and destination also used as non-destructive source +// CHECK-NEXT: udot z0.h, z0.b, z0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2p3/dot.s b/llvm/test/MC/AArch64/SVE2p3/dot.s new file mode 100644 index 0000000000000..01021b38e2f26 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p3/dot.s @@ -0,0 +1,173 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p3 < %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=+sve2p3 < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2p3 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p3 < %s \ +// RUN: | llvm-objdump -d --mattr=-sve2p3 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p3 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +sdot z0.h, z0.b, z0.b +// CHECK-INST: sdot z0.h, z0.b, z0.b +// CHECK-ENCODING: encoding: [0x00,0x00,0x40,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44400000 + +sdot z10.h, z10.b, z10.b +// CHECK-INST: sdot z10.h, z10.b, z10.b +// CHECK-ENCODING: encoding: [0x4a,0x01,0x4a,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 444a014a + +sdot z21.h, z21.b, z21.b +// CHECK-INST: sdot z21.h, z21.b, z21.b +// CHECK-ENCODING: encoding: [0xb5,0x02,0x55,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 445502b5 + +sdot z31.h, z31.b, z31.b +// CHECK-INST: sdot z31.h, z31.b, z31.b +// CHECK-ENCODING: encoding: [0xff,0x03,0x5f,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 445f03ff + +movprfx z0, z7 +sdot z0.h, z1.b, z2.b +// CHECK-INST: movprfx z0, z7 +// CHECK-INST: sdot z0.h, z1.b, z2.b +// CHECK-ENCODING: encoding: [0x20,0x00,0x42,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44420020 + +// sdot indexed + +sdot z0.h, z0.b, z0.b[0] +// CHECK-INST: sdot z0.h, z0.b, z0.b[0] +// CHECK-ENCODING: encoding: [0x00,0x00,0x20,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44200000 + +sdot z31.h, z31.b, z7.b[0] +// CHECK-INST: sdot z31.h, z31.b, z7.b[0] +// CHECK-ENCODING: encoding: [0xff,0x03,0x27,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 442703ff + +sdot z0.h, z0.b, z0.b[1] +// CHECK-INST: sdot z0.h, z0.b, z0.b[1] +// CHECK-ENCODING: encoding: [0x00,0x00,0x28,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44280000 + +sdot z31.h, z31.b, z7.b[1] +// CHECK-INST: sdot z31.h, z31.b, z7.b[1] +// CHECK-ENCODING: encoding: [0xff,0x03,0x2f,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 442f03ff + +sdot z0.h, z0.b, z0.b[7] +// CHECK-INST: sdot z0.h, z0.b, z0.b[7] +// CHECK-ENCODING: encoding: [0x00,0x00,0x78,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44780000 + +sdot z31.h, z31.b, z7.b[7] +// CHECK-INST: sdot z31.h, z31.b, z7.b[7] +// CHECK-ENCODING: encoding: [0xff,0x03,0x7f,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 447f03ff + +movprfx z0, z7 +sdot z0.h, z1.b, z2.b[0] +// CHECK-INST: movprfx z0, z7 +// CHECK-INST: sdot z0.h, z1.b, z2.b[0] +// CHECK-ENCODING: encoding: [0x20,0x00,0x22,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44220020 + +// udot + +udot z0.h, z0.b, z0.b +// CHECK-INST: udot z0.h, z0.b, z0.b +// CHECK-ENCODING: encoding: [0x00,0x04,0x40,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44400400 + +udot z10.h, z10.b, z10.b +// CHECK-INST: udot z10.h, z10.b, z10.b +// CHECK-ENCODING: encoding: [0x4a,0x05,0x4a,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 444a054a + +udot z21.h, z21.b, z21.b +// CHECK-INST: udot z21.h, z21.b, z21.b +// CHECK-ENCODING: encoding: [0xb5,0x06,0x55,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 445506b5 + +udot z31.h, z31.b, z31.b +// CHECK-INST: udot z31.h, z31.b, z31.b +// CHECK-ENCODING: encoding: [0xff,0x07,0x5f,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 445f07ff + +movprfx z0, z7 +udot z0.h, z1.b, z2.b +// CHECK-INST: movprfx z0, z7 +// CHECK-INST: udot z0.h, z1.b, z2.b +// CHECK-ENCODING: encoding: [0x20,0x04,0x42,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44420420 + +// udot indexed + +udot z0.h, z0.b, z0.b[0] +// CHECK-INST: udot z0.h, z0.b, z0.b[0] +// CHECK-ENCODING: encoding: [0x00,0x04,0x20,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44200400 + +udot z31.h, z31.b, z7.b[0] +// CHECK-INST: udot z31.h, z31.b, z7.b[0] +// CHECK-ENCODING: encoding: [0xff,0x07,0x27,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 442707ff + +udot z0.h, z0.b, z0.b[1] +// CHECK-INST: udot z0.h, z0.b, z0.b[1] +// CHECK-ENCODING: encoding: [0x00,0x04,0x28,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44280400 + +udot z31.h, z31.b, z7.b[1] +// CHECK-INST: udot z31.h, z31.b, z7.b[1] +// CHECK-ENCODING: encoding: [0xff,0x07,0x2f,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 442f07ff + +udot z0.h, z0.b, z0.b[7] +// CHECK-INST: udot z0.h, z0.b, z0.b[7] +// CHECK-ENCODING: encoding: [0x00,0x04,0x78,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44780400 + +udot z31.h, z31.b, z7.b[7] +// CHECK-INST: udot z31.h, z31.b, z7.b[7] +// CHECK-ENCODING: encoding: [0xff,0x07,0x7f,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 447f07ff + +movprfx z0, z7 +udot z0.h, z1.b, z2.b[0] +// CHECK-INST: movprfx z0, z7 +// CHECK-INST: udot z0.h, z1.b, z2.b[0] +// CHECK-ENCODING: encoding: [0x20,0x04,0x22,0x44] +// CHECK-ERROR: instruction requires: sme2p3 or sve2p3 +// CHECK-UNKNOWN: 44220420 diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 3c4ccef151260..a259c1419a146 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -1447,7 +1447,8 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { AArch64::AEK_LSCP, AArch64::AEK_TLBID, AArch64::AEK_MPAMV2, AArch64::AEK_MTETC, AArch64::AEK_GCIE, AArch64::AEK_SME2P3, - AArch64::AEK_SVE2P3, + AArch64::AEK_SVE2P3, AArch64::AEK_SVE_B16MM, + AArch64::AEK_F16MM, }; std::vector Features; @@ -1567,6 +1568,8 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { EXPECT_TRUE(llvm::is_contained(Features, "+gcie")); EXPECT_TRUE(llvm::is_contained(Features, "+sme2p3")); EXPECT_TRUE(llvm::is_contained(Features, "+sve2p3")); + EXPECT_TRUE(llvm::is_contained(Features, "+sve-b16mm")); + EXPECT_TRUE(llvm::is_contained(Features, "+f16mm")); // Assuming we listed every extension above, this should produce the same // result. @@ -1741,6 +1744,8 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { {"gcie", "nogcie", "+gcie", "-gcie"}, {"sme2p3", "nosme2p3", "+sme2p3", "-sme2p3"}, {"sve2p3", "nosve2p3", "+sve2p3", "-sve2p3"}, + {"sve-b16mm", "nosve-b16mm", "+sve-b16mm", "-sve-b16mm"}, + {"f16mm", "nof16mm", "+f16mm", "-f16mm"}, }; for (unsigned i = 0; i < std::size(ArchExt); i++) { @@ -1989,17 +1994,19 @@ AArch64ExtensionDependenciesBaseArchTestParams {AArch64::ARMV8A, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}}, {AArch64::ARMV8A, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}}, - // fp16 -> {fp16fml, sve} + // fp16 -> {fp16fml, sve, f16mm} {AArch64::ARMV8A, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}}, {AArch64::ARMV8A, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}}, {AArch64::ARMV8A, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}}, {AArch64::ARMV8A, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}}, + {AArch64::ARMV9_7A, {"nofp16", "f16mm"}, {"fullfp16", "f16mm"}, {}}, + {AArch64::ARMV9_7A, {"f16mm", "nofp16"}, {}, {"fullfp16", "f16mm"}}, // bf16 -> {sme} {AArch64::ARMV8A, {"nobf16", "sme"}, {"bf16", "sme"}, {}}, {AArch64::ARMV8A, {"sme", "nobf16"}, {}, {"bf16", "sme"}}, - // sve -> {sve2, f32mm, f64mm, sve-f16f32mm} + // sve -> {sve2, f32mm, f64mm, sve-f16f32mm, sve-b16mm} {AArch64::ARMV8A, {"nosve", "sve2"}, {"sve", "sve2"}, {}}, {AArch64::ARMV8A, {"sve2", "nosve"}, {}, {"sve", "sve2"}}, {AArch64::ARMV8A, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}}, @@ -2014,6 +2021,8 @@ AArch64ExtensionDependenciesBaseArchTestParams {"sve-f16f32mm", "nosve"}, {}, {"sve", "sve-f16f32mm"}}, + {AArch64::ARMV9_7A, {"nosve", "sve-b16mm"}, {"sve", "sve-b16mm"}, {}}, + {AArch64::ARMV9_7A, {"sve-b16mm", "nosve"}, {}, {"sve", "sve-b16mm"}}, // aes -> {sve-aes} {AArch64::ARMV8A, {"noaes", "sve-aes"}, {"aes", "sve-aes"}, {}},