diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index 232b3d6a6dbb1c..d1a3c94bc18eda 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -162,6 +162,8 @@ enum ArchExtKind : unsigned { AEK_FPMR = 58, // FEAT_FPMR AEK_FP8 = 59, // FEAT_FP8 AEK_FAMINMAX = 60, // FEAT_FAMINMAX + AEK_FP8FMA = 61, // FEAT_FP8FMA + AEK_SSVE_FP8FMA = 62, // FEAT_SSVE_FP8FMA AEK_NUM_EXTENSIONS }; using ExtensionBitset = Bitset; @@ -273,6 +275,8 @@ inline constexpr ExtensionInfo Extensions[] = { {"fpmr", AArch64::AEK_FPMR, "+fpmr", "-fpmr", FEAT_INIT, "", 0}, {"fp8", AArch64::AEK_FP8, "+fp8", "-fp8", FEAT_INIT, "+fpmr", 0}, {"faminmax", AArch64::AEK_FAMINMAX, "+faminmax", "-faminmax", FEAT_INIT, "", 0}, + {"fp8fma", AArch64::AEK_FP8FMA, "+fp8fma", "-fp8fma", FEAT_INIT, "+fpmr", 0}, + {"ssve-fp8fma", AArch64::AEK_SSVE_FP8FMA, "+ssve-fp8fma", "-ssve-fp8fma", FEAT_INIT, "+sme2", 0}, // Special cases {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", ExtensionInfo::MaxFMVPriority}, }; diff --git a/llvm/include/llvm/TargetParser/SubtargetFeature.h b/llvm/include/llvm/TargetParser/SubtargetFeature.h index e4dddfb78effbc..2e1f00dad2df36 100644 --- a/llvm/include/llvm/TargetParser/SubtargetFeature.h +++ b/llvm/include/llvm/TargetParser/SubtargetFeature.h @@ -31,7 +31,7 @@ namespace llvm { class raw_ostream; class Triple; -const unsigned MAX_SUBTARGET_WORDS = 4; +const unsigned MAX_SUBTARGET_WORDS = 5; const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64; /// Container class for subtarget features. diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index 8fd9358c9f9c7a..d3d4bd84f1e984 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -517,6 +517,12 @@ def FeatureSME2p1 : SubtargetFeature<"sme2p1", "HasSME2p1", "true", def FeatureFAMINMAX: SubtargetFeature<"faminmax", "HasFAMINMAX", "true", "Enable FAMIN and FAMAX instructions (FEAT_FAMINMAX)">; +def FeatureFP8FMA : SubtargetFeature<"fp8fma", "HasFP8FMA", "true", + "Enable fp8 multiply-add instructions (FEAT_FP8FMA)">; + +def FeatureSSVE_FP8FMA : SubtargetFeature<"ssve-fp8fma", "HasSSVE_FP8FMA", "true", + "Enable SVE2 fp8 multiply-add instructions (FEAT_SSVE_FP8FMA)", [FeatureSME2]>; + def FeatureAppleA7SysReg : SubtargetFeature<"apple-a7-sysreg", "HasAppleA7SysReg", "true", "Apple A7 (the CPU formerly known as Cyclone)">; @@ -747,7 +753,7 @@ let F = [HasSVE2p1, HasSVE2p1_or_HasSME2, HasSVE2p1_or_HasSME2p1] in def SVE2p1Unsupported : AArch64Unsupported; def SVE2Unsupported : AArch64Unsupported { - let F = !listconcat([HasSVE2, HasSVE2orSME, + let F = !listconcat([HasSVE2, HasSVE2orSME, HasSSVE_FP8FMA, HasSVE2AES, HasSVE2SHA3, HasSVE2SM4, HasSVE2BitPerm], SVE2p1Unsupported.F); } @@ -761,7 +767,7 @@ let F = [HasSME2p1, HasSVE2p1_or_HasSME2p1] in def SME2p1Unsupported : AArch64Unsupported; def SME2Unsupported : AArch64Unsupported { - let F = !listconcat([HasSME2, HasSVE2p1_or_HasSME2], + let F = !listconcat([HasSME2, HasSVE2p1_or_HasSME2, HasSSVE_FP8FMA], SME2p1Unsupported.F); } diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index a48bf77a774b75..152e3b4c7407db 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -6055,6 +6055,15 @@ multiclass SIMDThreeSameVectorFML size, string asm, v4f32, v8f16, OpNode>; } +multiclass SIMDThreeSameVectorMLA{ + def v8f16 : BaseSIMDThreeSameVectorDot; +} + +multiclass SIMDThreeSameVectorMLAL sz, string asm>{ + def v4f32 : BaseSIMDThreeSameVectorDot; +} // FP8 assembly/disassembly classes @@ -8521,6 +8530,31 @@ class BF16ToSinglePrecision } } // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 +//---------------------------------------------------------------------------- +class BaseSIMDThreeSameVectorIndexB sz, bits<4> opc, + string asm, string dst_kind, + RegisterOperand RegType, + RegisterOperand RegType_lo> + : BaseSIMDIndexedTied { + + // idx = H:L:M + bits<4> idx; + let Inst{11} = idx{3}; + let Inst{21-19} = idx{2-0}; +} + +multiclass SIMDThreeSameVectorMLAIndex { + def v8f16 : BaseSIMDThreeSameVectorIndexB; +} + +multiclass SIMDThreeSameVectorMLALIndex sz, string asm> { + def v4f32 : BaseSIMDThreeSameVectorIndexB; +} + //---------------------------------------------------------------------------- // Armv8.6 Matrix Multiply Extension //---------------------------------------------------------------------------- diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index d262c8bbe485ac..20f872dfc17b29 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -166,6 +166,13 @@ def HasFP8 : Predicate<"Subtarget->hasFP8()">, AssemblerPredicateWithAll<(all_of FeatureFP8), "fp8">; def HasFAMINMAX : Predicate<"Subtarget->hasFAMINMAX()">, AssemblerPredicateWithAll<(all_of FeatureFAMINMAX), "faminmax">; +def HasFP8FMA : Predicate<"Subtarget->hasFP8FMA()">, + AssemblerPredicateWithAll<(all_of FeatureFP8FMA), "fp8fma">; +def HasSSVE_FP8FMA : Predicate<"Subtarget->SSVE_FP8FMA() || " + "(Subtarget->hasSVE2() && Subtarget->hasFP8FMA())">, + AssemblerPredicateWithAll<(any_of FeatureSSVE_FP8FMA, + (all_of FeatureSVE2, FeatureFP8FMA)), + "ssve-fp8fma or (sve2 and fp8fma)">; // A subset of SVE(2) instructions are legal in Streaming SVE execution mode, // they should be enabled if either has been specified. @@ -9286,6 +9293,21 @@ let Predicates = [HasFAMINMAX] in { defm FAMIN : SIMDThreeSameVectorFP<0b1, 0b1, 0b011, "famin", null_frag>; } // End let Predicates = [HasFAMAXMIN] +let Predicates = [HasFP8FMA] in { + defm FMLALBlane : SIMDThreeSameVectorMLAIndex<0b0, "fmlalb">; + defm FMLALTlane : SIMDThreeSameVectorMLAIndex<0b1, "fmlalt">; + defm FMLALLBBlane : SIMDThreeSameVectorMLALIndex<0b0, 0b00, "fmlallbb">; + defm FMLALLBTlane : SIMDThreeSameVectorMLALIndex<0b0, 0b01, "fmlallbt">; + defm FMLALLTBlane : SIMDThreeSameVectorMLALIndex<0b1, 0b00, "fmlalltb">; + defm FMLALLTTlane : SIMDThreeSameVectorMLALIndex<0b1, 0b01, "fmlalltt">; + + defm FMLALB : SIMDThreeSameVectorMLA<0b0, "fmlalb">; + defm FMLALT : SIMDThreeSameVectorMLA<0b1, "fmlalt">; + defm FMLALLBB : SIMDThreeSameVectorMLAL<0b0, 0b00, "fmlallbb">; + defm FMLALLBT : SIMDThreeSameVectorMLAL<0b0, 0b01, "fmlallbt">; + defm FMLALLTB : SIMDThreeSameVectorMLAL<0b1, 0b00, "fmlalltb">; + defm FMLALLTT : SIMDThreeSameVectorMLAL<0b1, 0b01, "fmlalltt">; +} // End let Predicates = [HasFP8FMA] include "AArch64InstrAtomics.td" include "AArch64SVEInstrInfo.td" diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp index cc5384613f1ab3..1a730a0b955d3d 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -981,6 +981,8 @@ unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, case AArch64::FPR64_loRegClassID: case AArch64::FPR16_loRegClassID: return 16; + case AArch64::FPR128_0to7RegClassID: + return 8; } } diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index eb26591908fd79..497c143584d48d 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -467,6 +467,13 @@ def FPR128_lo : RegisterClass<"AArch64", v8bf16], 128, (trunc FPR128, 16)>; +// The lower 8 vector registers. Some instructions can only take registers +// in this range. +def FPR128_0to7 : RegisterClass<"AArch64", + [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16, + v8bf16], + 128, (trunc FPR128, 8)>; + // Pairs, triples, and quads of 64-bit vector registers. def DSeqPairs : RegisterTuples<[dsub0, dsub1], [(rotl FPR64, 0), (rotl FPR64, 1)]>; def DSeqTriples : RegisterTuples<[dsub0, dsub1, dsub2], @@ -534,6 +541,15 @@ def V128_lo : RegisterOperand { let ParserMatchClass = VectorRegLoAsmOperand; } +def VectorReg0to7AsmOperand : AsmOperandClass { + let Name = "VectorReg0to7"; + let PredicateMethod = "isNeonVectorReg0to7"; +} + +def V128_0to7 : RegisterOperand { + let ParserMatchClass = VectorReg0to7AsmOperand; +} + class TypedVecListAsmOperand : AsmOperandClass { let Name = "TypedVectorList" # count # "_" # lanes # eltsize; diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 3faa06f995e5be..abe07dc0ce3270 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4045,3 +4045,22 @@ let Predicates = [HasSVE2orSME2, HasFAMINMAX] in { defm FAMIN_ZPmZ : sve_fp_2op_p_zds<0b1111, "famin", "", null_frag, DestructiveOther>; defm FAMAX_ZPmZ : sve_fp_2op_p_zds<0b1110, "famax", "", null_frag, DestructiveOther>; } // End HasSVE2orSME2, HasFAMINMAX + +let Predicates = [HasSSVE_FP8FMA] in { +// FP8 Widening Multiply-Add Long - Indexed Group +def FMLALB_ZZZI : sve2_fp8_mla_long_by_indexed_elem<0b0, "fmlalb">; +def FMLALT_ZZZI : sve2_fp8_mla_long_by_indexed_elem<0b1, "fmlalt">; +// FP8 Widening Multiply-Add Long Group +def FMLALB_ZZZ : sve2_fp8_mla<0b100, ZPR16, "fmlalb">; +def FMLALT_ZZZ : sve2_fp8_mla<0b101, ZPR16, "fmlalt">; +// FP8 Widening Multiply-Add Long Long - Indexed Group +def FMLALLBB_ZZZI : sve2_fp8_mla_long_long_by_indexed_elem<0b00, "fmlallbb">; +def FMLALLBT_ZZZI : sve2_fp8_mla_long_long_by_indexed_elem<0b01, "fmlallbt">; +def FMLALLTB_ZZZI : sve2_fp8_mla_long_long_by_indexed_elem<0b10, "fmlalltb">; +def FMLALLTT_ZZZI : sve2_fp8_mla_long_long_by_indexed_elem<0b11, "fmlalltt">; +// FP8 Widening Multiply-Add Long Long Group +def FMLALLBB_ZZZ : sve2_fp8_mla<0b000, ZPR32, "fmlallbb">; +def FMLALLBT_ZZZ : sve2_fp8_mla<0b001, ZPR32, "fmlallbt">; +def FMLALLTB_ZZZ : sve2_fp8_mla<0b010, ZPR32, "fmlalltb">; +def FMLALLTT_ZZZ : sve2_fp8_mla<0b011, ZPR32, "fmlalltt">; +} // End HasSSVE_FP8FMA diff --git a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td index f3e844dc5b270d..1de0e8291ef12d 100644 --- a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td +++ b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td @@ -23,7 +23,7 @@ def A64FXModel : SchedMachineModel { list UnsupportedFeatures = [HasSVE2, HasSVE2AES, HasSVE2SM4, HasSVE2SHA3, HasSVE2BitPerm, HasPAuth, HasSVE2orSME, HasMTE, HasMatMulInt8, HasBF16, HasSME2, HasSME2p1, HasSVE2p1, - HasSVE2p1_or_HasSME2p1, HasSMEF16F16]; + HasSVE2p1_or_HasSME2p1, HasSMEF16F16, HasSSVE_FP8FMA]; let FullInstRWOverlapCheck = 0; } diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 35abe3563eb81a..afecff1303666e 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1223,6 +1223,12 @@ class AArch64Operand : public MCParsedAsmOperand { Reg.RegNum)); } + bool isNeonVectorReg0to7() const { + return Kind == k_Register && Reg.Kind == RegKind::NeonVector && + (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains( + Reg.RegNum)); + } + bool isMatrix() const { return Kind == k_MatrixRegister; } bool isMatrixTileList() const { return Kind == k_MatrixTileList; } @@ -1766,6 +1772,11 @@ class AArch64Operand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createReg(getReg())); } + void addVectorReg0to7Operands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createReg(getReg())); + } + enum VecListIndexType { VecListIdx_DReg = 0, VecListIdx_QReg = 1, @@ -2598,31 +2609,31 @@ static std::optional> parseVectorKind(StringRef Suffix, switch (VectorKind) { case RegKind::NeonVector: - Res = - StringSwitch>(Suffix.lower()) - .Case("", {0, 0}) - .Case(".1d", {1, 64}) - .Case(".1q", {1, 128}) - // '.2h' needed for fp16 scalar pairwise reductions - .Case(".2h", {2, 16}) - .Case(".2s", {2, 32}) - .Case(".2d", {2, 64}) - // '.4b' is another special case for the ARMv8.2a dot product - // operand - .Case(".4b", {4, 8}) - .Case(".4h", {4, 16}) - .Case(".4s", {4, 32}) - .Case(".8b", {8, 8}) - .Case(".8h", {8, 16}) - .Case(".16b", {16, 8}) - // Accept the width neutral ones, too, for verbose syntax. If those - // aren't used in the right places, the token operand won't match so - // all will work out. - .Case(".b", {0, 8}) - .Case(".h", {0, 16}) - .Case(".s", {0, 32}) - .Case(".d", {0, 64}) - .Default({-1, -1}); + Res = StringSwitch>(Suffix.lower()) + .Case("", {0, 0}) + .Case(".1d", {1, 64}) + .Case(".1q", {1, 128}) + // '.2h' needed for fp16 scalar pairwise reductions + .Case(".2h", {2, 16}) + .Case(".2b", {2, 8}) + .Case(".2s", {2, 32}) + .Case(".2d", {2, 64}) + // '.4b' is another special case for the ARMv8.2a dot product + // operand + .Case(".4b", {4, 8}) + .Case(".4h", {4, 16}) + .Case(".4s", {4, 32}) + .Case(".8b", {8, 8}) + .Case(".8h", {8, 16}) + .Case(".16b", {16, 8}) + // Accept the width neutral ones, too, for verbose syntax. If + // those aren't used in the right places, the token operand won't + // match so all will work out. + .Case(".b", {0, 8}) + .Case(".h", {0, 16}) + .Case(".s", {0, 32}) + .Case(".d", {0, 64}) + .Default({-1, -1}); break; case RegKind::SVEPredicateAsCounter: case RegKind::SVEPredicateVector: @@ -3641,6 +3652,8 @@ static const struct Extension { {"fpmr", {AArch64::FeatureFPMR}}, {"fp8", {AArch64::FeatureFP8}}, {"faminmax", {AArch64::FeatureFAMINMAX}}, + {"fp8fma", {AArch64::FeatureFP8FMA}}, + {"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}}, }; static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) { diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index df817f62f99fbf..cf2d3879292d19 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -44,6 +44,9 @@ static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo, static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); +static DecodeStatus +DecodeFPR128_0to7RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, + const MCDisassembler *Decoder); static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); @@ -437,6 +440,14 @@ DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder); } +static DecodeStatus +DecodeFPR128_0to7RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, + const MCDisassembler *Decoder) { + if (RegNo > 7) + return Fail; + return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder); +} + static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, const MCDisassembler *Decoder) { diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp index b956cd4782b794..21f9f6437e4fe9 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp @@ -245,9 +245,10 @@ AArch64RegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, case AArch64::FPR32_with_hsub_in_FPR16_loRegClassID: case AArch64::FPR32RegClassID: case AArch64::FPR64RegClassID: - case AArch64::FPR64_loRegClassID: case AArch64::FPR128RegClassID: + case AArch64::FPR64_loRegClassID: case AArch64::FPR128_loRegClassID: + case AArch64::FPR128_0to7RegClassID: case AArch64::DDRegClassID: case AArch64::DDDRegClassID: case AArch64::DDDDRegClassID: diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index ff641a85f84404..20ccd61219039c 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -10121,4 +10121,75 @@ class sve2_fp8_down_cvt_single opc, string mnemonic, multiclass sve2_fp8_down_cvt_single opc, string mnemonic, RegisterOperand src> { def NAME : sve2_fp8_down_cvt_single; -} \ No newline at end of file +} + +// FP8 Widening Multiply-Add Long - Indexed Group +class sve2_fp8_mla_long_by_indexed_elem + : I<(outs ZPR16:$Zda), + (ins ZPR16:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4), + mnemonic, "\t$Zda, $Zn, $Zm$imm4", + "", []>, Sched<[]>{ + bits<5> Zda; + bits<5> Zn; + bits<3> Zm; + bits<4> imm4; + let Inst{31-24} = 0b01100100; + let Inst{23} = T; + let Inst{22-21} = 0b01; + let Inst{20-19} = imm4{3-2}; + let Inst{18-16} = Zm; + let Inst{15-12} = 0b0101; + let Inst{11-10} = imm4{1-0}; + let Inst{9-5} = Zn; + let Inst{4-0} = Zda; + let Constraints = "$Zda = $_Zda"; + let DestructiveInstType = DestructiveOther; + let ElementSize = ZPR16.ElementSize; +} + +// FP8 Widening Multiply-Add (Long)/(Long Long) Group +class sve2_fp8_mlaopc, ZPRRegOp dst_ty, string mnemonic> + : I<(outs dst_ty:$Zda), + (ins dst_ty:$_Zda, ZPR8:$Zn, ZPR8:$Zm), + mnemonic, "\t$Zda, $Zn, $Zm", + "", []>, Sched<[]>{ + bits<5> Zda; + bits<5> Zn; + bits<5> Zm; + let Inst{31-24} = 0b01100100; + let Inst{23} = opc{2}; + let Inst{22-21} = 0b01; + let Inst{20-16} = Zm; + let Inst{15-14} = 0b10; + let Inst{13-12} = opc{1-0}; + let Inst{11-10} = 0b10; + let Inst{9-5} = Zn; + let Inst{4-0} = Zda; + let Constraints = "$Zda = $_Zda"; + let DestructiveInstType = DestructiveOther; + let ElementSize = dst_ty.ElementSize; +} + +// FP8 Widening Multiply-Add Long Long - Indexed Group +class sve2_fp8_mla_long_long_by_indexed_elem TT, string mnemonic> + : I<(outs ZPR32:$Zda), + (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4), + mnemonic, "\t$Zda, $Zn, $Zm$imm4", + "", []>, Sched<[]>{ + bits<5> Zda; + bits<5> Zn; + bits<3> Zm; + bits<4> imm4; + let Inst{31-24} = 0b01100100; + let Inst{23-22} = TT; + let Inst{21} = 0b1; + let Inst{20-19} = imm4{3-2}; + let Inst{18-16} = Zm; + let Inst{15-12} = 0b1100; + let Inst{11-10} = imm4{1-0}; + let Inst{9-5} = Zn; + let Inst{4-0} = Zda; + let Constraints = "$Zda = $_Zda"; + let DestructiveInstType = DestructiveOther; + let ElementSize = ZPR32.ElementSize; +} diff --git a/llvm/test/MC/AArch64/FP8/directive-arch-negative.s b/llvm/test/MC/AArch64/FP8/directive-arch-negative.s index 86525ff68134c9..7a45f25fa052de 100644 --- a/llvm/test/MC/AArch64/FP8/directive-arch-negative.s +++ b/llvm/test/MC/AArch64/FP8/directive-arch-negative.s @@ -12,3 +12,14 @@ famax v31.4h, v31.4h, v31.4h // CHECK: error: instruction requires: faminmax // CHECK: famax v31.4h, v31.4h, v31.4h +.arch armv9-a+fp8fma +.arch armv9-a+nofp8fma +fmlalb v0.8h, v0.16b, v0.16b +// CHECK: error: instruction requires: fp8fma +// CHECK: fmlalb v0.8h, v0.16b, v0.16b + +.arch armv9-a+ssve-fp8fma +.arch armv9-a+nossve-fp8fma +fmlalb z23.h, z13.b, z0.b[7] +// CHECK: error: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK: fmlalb z23.h, z13.b, z0.b[7] diff --git a/llvm/test/MC/AArch64/FP8/directive-arch.s b/llvm/test/MC/AArch64/FP8/directive-arch.s index e3f0a94c2ff9a3..f3627f537b92df 100644 --- a/llvm/test/MC/AArch64/FP8/directive-arch.s +++ b/llvm/test/MC/AArch64/FP8/directive-arch.s @@ -3,11 +3,19 @@ .arch armv9-a+fp8 bf1cvtl v0.8h, v0.8b // CHECK: bf1cvtl v0.8h, v0.8b - .arch armv9-a+nofp8 + .arch armv9-a+faminmax famax v31.4h, v31.4h, v31.4h // CHECK: famax v31.4h, v31.4h, v31.4h - .arch armv9-a+nofaminmax +.arch armv9-a+fp8fma +fmlalb v0.8h, v0.16b, v0.16b +// CHECK: fmlalb v0.8h, v0.16b, v0.16b +.arch armv9-a+nofp8fma + +.arch armv9-a+ssve-fp8fma +fmlalb z23.h, z13.b, z0.b[7] +// CHECK: fmlalb z23.h, z13.b, z0.b[7] +.arch armv9-a+nossve-fp8fma diff --git a/llvm/test/MC/AArch64/FP8/mla-diagnostic.s b/llvm/test/MC/AArch64/FP8/mla-diagnostic.s new file mode 100644 index 00000000000000..91a23a3d73e0ca --- /dev/null +++ b/llvm/test/MC/AArch64/FP8/mla-diagnostic.s @@ -0,0 +1,85 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=fp8fma 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Element size extension incorrect +fmlalb v0.8h, v0.8b, v0.8b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalb v0.8h, v0.8b, v0.8b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalt v31.8h, v31.16b, v31.16h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier +// CHECK-NEXT: fmlalt v31.8h, v31.16b, v31.16h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlallbb v0.4s, v0, v31 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlallbb v0.4s, v0, v31 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlallbt v31.4b, v31.16b, v0.16b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlallbt v31.4b, v31.16b, v0.16b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltb v31.b, v31.16b, v0.16b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalltb v31.b, v31.16b, v0.16b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltt v0.4s, v0.16b, v31.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalltt v0.4s, v0.16b, v31.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalt v31.8s, v31.16b, v31.16b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier +// CHECK-NEXT: fmlalt v31.8s, v31.16b, v31.16b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +//--------------------------------------------------------------------------// +// Last Register range is between 0-7 + +fmlalltb v0.4s, v31.16b, v8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalltb v0.4s, v31.16b, v8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}$ + +fmlalt v31.8h, v0.16b, v8.b[15] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalt v31.8h, v0.16b, v8.b[15] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:$ + + +// --------------------------------------------------------------------------// +// Out of range index +fmlalb v31.8h, v0.16b, v0.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlalb v31.8h, v0.16b, v0.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalt v31.8h, v0.16b, v0.b[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlalt v31.8h, v0.16b, v0.b[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlallbb v31.4s, v0.16b, v7.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlallbb v31.4s, v0.16b, v7.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltt v31.4s, v0.16b, v7.b[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlalltt v31.4s, v0.16b, v7.b[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltb v0.4s, v31.16b, v7.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlalltb v0.4s, v31.16b, v7.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}} + +fmlallbt v0.4s, v31.16b, v0.b[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlallbt v0.4s, v31.16b, v0.b[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/FP8/mla.s b/llvm/test/MC/AArch64/FP8/mla.s new file mode 100644 index 00000000000000..b3b6f1eb180621 --- /dev/null +++ b/llvm/test/MC/AArch64/FP8/mla.s @@ -0,0 +1,98 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fp8fma < %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=+fp8fma < %s \ +// RUN: | llvm-objdump -d --mattr=+fp8fma - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+fp8fma < %s \ +// RUN: | llvm-objdump -d --mattr=-fp8fma - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fp8fma < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+fp8fma -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +/// VECTOR +// MLA +fmlalb v0.8h, v0.16b, v0.16b +// CHECK-INST: fmlalb v0.8h, v0.16b, v0.16b +// CHECK-ENCODING: [0x00,0xfc,0xc0,0x0e] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 0ec0fc00 + +fmlalt v31.8h, v31.16b, v31.16b +// CHECK-INST: fmlalt v31.8h, v31.16b, v31.16b +// CHECK-ENCODING: [0xff,0xff,0xdf,0x4e] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 4edfffff + + +// MLALL +fmlallbb v0.4s, v0.16b, v31.16b +// CHECK-INST: fmlallbb v0.4s, v0.16b, v31.16b +// CHECK-ENCODING: [0x00,0xc4,0x1f,0x0e] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 0e1fc400 + +fmlallbt v31.4s, v31.16b, v0.16b +// CHECK-INST: fmlallbt v31.4s, v31.16b, v0.16b +// CHECK-ENCODING: [0xff,0xc7,0x40,0x0e] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 0e40c7ff + +fmlalltb v31.4s, v31.16b, v0.16b +// CHECK-INST: fmlalltb v31.4s, v31.16b, v0.16b +// CHECK-ENCODING: [0xff,0xc7,0x00,0x4e] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 4e00c7ff + +fmlalltt v0.4s, v0.16b, v31.16b +// CHECK-INST: fmlalltt v0.4s, v0.16b, v31.16b +// CHECK-ENCODING: [0x00,0xc4,0x5f,0x4e] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 4e5fc400 + +fmlalltt v31.4s, v31.16b, v31.16b // 01001110-01011111-11000111-11111111 +// CHECK-INST: fmlalltt v31.4s, v31.16b, v31.16b +// CHECK-ENCODING: [0xff,0xc7,0x5f,0x4e] +// CHECK-ERROR: instruction requires: fp8 +// CHECK-UNKNOWN: 4e5fc7ff + +//INDEXED +// MLA +fmlalb v31.8h, v0.16b, v0.b[0] +// CHECK-INST: fmlalb v31.8h, v0.16b, v0.b[0] +// CHECK-ENCODING: [0x1f,0x00,0xc0,0x0f] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 0fc0001f + +fmlalt v31.8h, v0.16b, v0.b[15] +// CHECK-INST: fmlalt v31.8h, v0.16b, v0.b[15] +// CHECK-ENCODING: [0x1f,0x08,0xf8,0x4f] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 4ff8081f + +// MLALL +fmlallbb v31.4s, v0.16b, v7.b[0] +// CHECK-INST: fmlallbb v31.4s, v0.16b, v7.b[0] +// CHECK-ENCODING: [0x1f,0x80,0x07,0x2f] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 2f07801f + +fmlalltt v31.4s, v0.16b, v7.b[0] +// CHECK-INST: fmlalltt v31.4s, v0.16b, v7.b[0] +// CHECK-ENCODING: [0x1f,0x80,0x47,0x6f] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 6f47801f + +fmlalltb v0.4s, v31.16b, v7.b[15] +// CHECK-INST: fmlalltb v0.4s, v31.16b, v7.b[15] +// CHECK-ENCODING: [0xe0,0x8b,0x3f,0x6f] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 6f3f8be0 + +fmlallbt v0.4s, v31.16b, v0.b[15] +// CHECK-INST: fmlallbt v0.4s, v31.16b, v0.b[15] +// CHECK-ENCODING: [0xe0,0x8b,0x78,0x2f] +// CHECK-ERROR: instruction requires: fp8fma +// CHECK-UNKNOWN: 2f788be0 diff --git a/llvm/test/MC/AArch64/FP8_SVE2/fmlal-diagnostics.s b/llvm/test/MC/AArch64/FP8_SVE2/fmlal-diagnostics.s new file mode 100644 index 00000000000000..627ec0f044bb99 --- /dev/null +++ b/llvm/test/MC/AArch64/FP8_SVE2/fmlal-diagnostics.s @@ -0,0 +1,64 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+ssve-fp8fma 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// z register out of range for index +fmlalb z0.h, z1.b, z8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalb z0.h, z1.b, z8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalt z0.h, z1.b, z8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalt z0.h, z1.b, z8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Index out of bounds + +fmlalb z0.h, z1.b, z7.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlalb z0.h, z1.b, z7.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalt z0.h, z1.b, z7.b[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlalt z0.h, z1.b, z7.b[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Invalid element width + +fmlalb z0.h, z1.h, z2.h[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmlalb z0.h, z1.h, z2.h[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalb z0.h, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmlalb z0.h, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalt z0.s, z1.b, z2.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmlalt z0.s, z1.b, z2.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalt z0.s, z1.b, z2.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmlalt z0.s, z1.b, z2.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.b, p0/z, z0.b +fmlalb z0.h, z1.b, z7.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx +// CHECK-NEXT: fmlalb z0.h, z1.b, z7.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z29.b, p0/z, z7.b +fmlalt z29.h, z30.b, z31.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx +// CHECK-NEXT: fmlalt z29.h, z30.b, z31.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/FP8_SVE2/fmlal.s b/llvm/test/MC/AArch64/FP8_SVE2/fmlal.s new file mode 100644 index 00000000000000..b567364b078856 --- /dev/null +++ b/llvm/test/MC/AArch64/FP8_SVE2/fmlal.s @@ -0,0 +1,114 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+ssve-fp8fma < %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=+sve2,+fp8fma < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2,+fp8fma --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST + +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2,+fp8fma < %s \ +// RUN: | llvm-objdump -d --mattr=-fp8fma --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=+sve2,+fp8fma < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2,+fp8fma -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// +// FMLALB instructions +// +// fmlalb - indexed + +fmlalb z0.h, z0.b, z0.b[0] // 01100100-00100000-01010000-00000000 +// CHECK-INST: fmlalb z0.h, z0.b, z0.b[0] +// CHECK-ENCODING: [0x00,0x50,0x20,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64205000 + +movprfx z23, z31 +fmlalb z23.h, z13.b, z0.b[7] // 01100100-00101000-01011101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlalb z23.h, z13.b, z0.b[7] +// CHECK-ENCODING: [0xb7,0x5d,0x28,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64285db7 + +fmlalb z31.h, z31.b, z7.b[15] // 01100100-00111111-01011111-11111111 +// CHECK-INST: fmlalb z31.h, z31.b, z7.b[15] +// CHECK-ENCODING: [0xff,0x5f,0x3f,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 643f5fff + + +// fmlalb - group + +fmlalb z0.h, z0.b, z0.b // 01100100-10100000-10001000-00000000 +// CHECK-INST: fmlalb z0.h, z0.b, z0.b +// CHECK-ENCODING: [0x00,0x88,0xa0,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64a08800 + +movprfx z23, z31 +fmlalb z23.h, z13.b, z8.b // 01100100-10101000-10001001-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlalb z23.h, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0x89,0xa8,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64a889b7 + +fmlalb z31.h, z31.b, z31.b // 01100100-10111111-10001011-11111111 +// CHECK-INST: fmlalb z31.h, z31.b, z31.b +// CHECK-ENCODING: [0xff,0x8b,0xbf,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64bf8bff + + +// +// FMLALT instructions +// +// fmlalt - indexed + +fmlalt z0.h, z0.b, z0.b[0] // 01100100-10100000-01010000-00000000 +// CHECK-INST: fmlalt z0.h, z0.b, z0.b[0] +// CHECK-ENCODING: [0x00,0x50,0xa0,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64a05000 + +movprfx z23, z31 +fmlalt z23.h, z13.b, z0.b[7] // 01100100-10101000-01011101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlalt z23.h, z13.b, z0.b[7] +// CHECK-ENCODING: [0xb7,0x5d,0xa8,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64a85db7 + +fmlalt z31.h, z31.b, z7.b[15] // 01100100-10111111-01011111-11111111 +// CHECK-INST: fmlalt z31.h, z31.b, z7.b[15] +// CHECK-ENCODING: [0xff,0x5f,0xbf,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64bf5fff + + +// fmlalt - group + +fmlalt z0.h, z0.b, z0.b // 01100100-10100000-10011000-00000000 +// CHECK-INST: fmlalt z0.h, z0.b, z0.b +// CHECK-ENCODING: [0x00,0x98,0xa0,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64a09800 + +movprfx z23, z31 +fmlalt z23.h, z13.b, z8.b // 01100100-10101000-10011001-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlalt z23.h, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0x99,0xa8,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64a899b7 + +fmlalt z31.h, z31.b, z31.b // 01100100-10111111-10011011-11111111 +// CHECK-INST: fmlalt z31.h, z31.b, z31.b +// CHECK-ENCODING: [0xff,0x9b,0xbf,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64bf9bff diff --git a/llvm/test/MC/AArch64/FP8_SVE2/fmlall-diagnostics.s b/llvm/test/MC/AArch64/FP8_SVE2/fmlall-diagnostics.s new file mode 100644 index 00000000000000..7a8a299b8756da --- /dev/null +++ b/llvm/test/MC/AArch64/FP8_SVE2/fmlall-diagnostics.s @@ -0,0 +1,85 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+ssve-fp8fma 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// z register out of range for index + +fmlallbb z0.s, z1.b, z8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlallbb z0.s, z1.b, z8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlallbt z0.s, z1.b, z8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlallbt z0.s, z1.b, z8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltb z0.s, z1.b, z8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalltb z0.s, z1.b, z8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltt z0.s, z1.b, z8.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: fmlalltt z0.s, z1.b, z8.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Index out of bounds + +fmlallbb z0.s, z1.b, z7.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlallbb z0.s, z1.b, z7.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlallbt z0.s, z1.b, z7.b[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlallbt z0.s, z1.b, z7.b[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltb z0.s, z1.b, z7.b[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlalltb z0.s, z1.b, z7.b[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltt z0.s, z1.b, z7.b[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: fmlalltt z0.s, z1.b, z7.b[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Invalid element width + +fmlallbb z0.h, z1.b, z2.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmlallbb z0.h, z1.b, z2.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlallbt z0.h, z1.b, z2.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmlallbt z0.h, z1.b, z2.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltb z0.s, z1.h, z2.h[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmlalltb z0.s, z1.h, z2.h[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +fmlalltt z0.s, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: fmlalltt z0.s, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z0.s, p0/z, z0.s +fmlallbb z0.s, z1.b, z7.b[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx +// CHECK-NEXT: fmlallbb z0.s, z1.b, z7.b[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movprfx z29.s, p0/z, z7.s +fmlalltt z29.s, z30.b, z31.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx +// CHECK-NEXT: fmlalltt z29.s, z30.b, z31.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/FP8_SVE2/fmlall.s b/llvm/test/MC/AArch64/FP8_SVE2/fmlall.s new file mode 100644 index 00000000000000..319e664172da65 --- /dev/null +++ b/llvm/test/MC/AArch64/FP8_SVE2/fmlall.s @@ -0,0 +1,222 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+ssve-fp8fma < %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=+sve2,+fp8fma < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2,+fp8fma --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST + +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2,+fp8fma < %s \ +// RUN: | llvm-objdump -d --mattr=-sve2 --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=+sve2,+fp8fma < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2,+fp8fma -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// +// FMLALLBB instructions +// +// fmlallbb - indexed + +fmlallbb z0.s, z0.b, z0.b[0] // 01100100-00100000-11000000-00000000 +// CHECK-INST: fmlallbb z0.s, z0.b, z0.b[0] +// CHECK-ENCODING: [0x00,0xc0,0x20,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 6420c000 + +movprfx z23, z31 +fmlallbb z23.s, z13.b, z0.b[7] // 01100100-00101000-11001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlallbb z23.s, z13.b, z0.b[7] +// CHECK-ENCODING: [0xb7,0xcd,0x28,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 6428cdb7 + +fmlallbb z31.s, z31.b, z7.b[15] // 01100100-00111111-11001111-11111111 +// CHECK-INST: fmlallbb z31.s, z31.b, z7.b[15] +// CHECK-ENCODING: [0xff,0xcf,0x3f,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 643fcfff + +// +// FMLALLBB instructions +// +// fmlallbb - group + +fmlallbb z0.s, z0.b, z0.b // 01100100-00100000-10001000-00000000 +// CHECK-INST: fmlallbb z0.s, z0.b, z0.b +// CHECK-ENCODING: [0x00,0x88,0x20,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64208800 + +movprfx z23, z31 +fmlallbb z23.s, z13.b, z8.b // 01100100-00101000-10001001-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlallbb z23.s, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0x89,0x28,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 642889b7 + +fmlallbb z31.s, z31.b, z31.b // 01100100-00111111-10001011-11111111 +// CHECK-INST: fmlallbb z31.s, z31.b, z31.b +// CHECK-ENCODING: [0xff,0x8b,0x3f,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 643f8bff + +//--------------------------------------------// +// +// FMLALLBT instructions +// +// fmlallbt - indexed + +fmlallbt z0.s, z0.b, z0.b[0] // 01100100-01100000-11000000-00000000 +// CHECK-INST: fmlallbt z0.s, z0.b, z0.b[0] +// CHECK-ENCODING: [0x00,0xc0,0x60,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 6460c000 + +movprfx z23, z31 +fmlallbt z23.s, z13.b, z0.b[7] // 01100100-01101000-11001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlallbt z23.s, z13.b, z0.b[7] +// CHECK-ENCODING: [0xb7,0xcd,0x68,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 6468cdb7 + +fmlallbt z31.s, z31.b, z7.b[15] // 01100100-01111111-11001111-11111111 +// CHECK-INST: fmlallbt z31.s, z31.b, z7.b[15] +// CHECK-ENCODING: [0xff,0xcf,0x7f,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 647fcfff + +// +// FMLALLBT instructions +// +// fmlallbt - group + +fmlallbt z0.s, z0.b, z0.b // 01100100-00100000-10011000-00000000 +// CHECK-INST: fmlallbt z0.s, z0.b, z0.b +// CHECK-ENCODING: [0x00,0x98,0x20,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64209800 + +movprfx z23, z31 +fmlallbt z23.s, z13.b, z8.b // 01100100-00101000-10011001-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlallbt z23.s, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0x99,0x28,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 642899b7 + +fmlallbt z31.s, z31.b, z31.b // 01100100-00111111-10011011-11111111 +// CHECK-INST: fmlallbt z31.s, z31.b, z31.b +// CHECK-ENCODING: [0xff,0x9b,0x3f,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 643f9bff + +//--------------------------------------------// +// +// FMLALLTB instructions +// +// fmlalltb - indexed + +fmlalltb z0.s, z0.b, z0.b[0] // 01100100-10100000-11000000-00000000 +// CHECK-INST: fmlalltb z0.s, z0.b, z0.b[0] +// CHECK-ENCODING: [0x00,0xc0,0xa0,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64a0c000 + +movprfx z23, z31 +fmlalltb z23.s, z13.b, z0.b[7] // 01100100-10101000-11001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlalltb z23.s, z13.b, z0.b[7] +// CHECK-ENCODING: [0xb7,0xcd,0xa8,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64a8cdb7 + +fmlalltb z31.s, z31.b, z7.b[15] // 01100100-10111111-11001111-11111111 +// CHECK-INST: fmlalltb z31.s, z31.b, z7.b[15] +// CHECK-ENCODING: [0xff,0xcf,0xbf,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64bfcfff + +// +// FMLALLTB instructions +// +// fmlalltb - group + +fmlalltb z0.s, z0.b, z0.b // 01100100-00100000-10101000-00000000 +// CHECK-INST: fmlalltb z0.s, z0.b, z0.b +// CHECK-ENCODING: [0x00,0xa8,0x20,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 6420a800 + +movprfx z23, z31 +fmlalltb z23.s, z13.b, z8.b // 01100100-00101000-10101001-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlalltb z23.s, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0xa9,0x28,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 6428a9b7 + +fmlalltb z31.s, z31.b, z31.b // 01100100-00111111-10101011-11111111 +// CHECK-INST: fmlalltb z31.s, z31.b, z31.b +// CHECK-ENCODING: [0xff,0xab,0x3f,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 643fabff + + +//--------------------------------------------// +// +// FMLALLTT instructions +// +// fmlalltt - indexed + +fmlalltt z0.s, z0.b, z0.b[0] // 01100100-11100000-11000000-00000000 +// CHECK-INST: fmlalltt z0.s, z0.b, z0.b[0] +// CHECK-ENCODING: [0x00,0xc0,0xe0,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64e0c000 + +movprfx z23, z31 +fmlalltt z23.s, z13.b, z0.b[7] // 01100100-11101000-11001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlalltt z23.s, z13.b, z0.b[7] +// CHECK-ENCODING: [0xb7,0xcd,0xe8,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64e8cdb7 + +fmlalltt z31.s, z31.b, z7.b[15] // 01100100-11111111-11001111-11111111 +// CHECK-INST: fmlalltt z31.s, z31.b, z7.b[15] +// CHECK-ENCODING: [0xff,0xcf,0xff,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 64ffcfff + + +// +// FMLALLTT instructions +// +// fmlalltt - group + +fmlalltt z0.s, z0.b, z0.b // 01100100-00100000-10111000-00000000 +// CHECK-INST: fmlalltt z0.s, z0.b, z0.b +// CHECK-ENCODING: [0x00,0xb8,0x20,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 6420b800 + +movprfx z23, z31 +fmlalltt z23.s, z13.b, z8.b // 01100100-00101000-10111001-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: fmlalltt z23.s, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0xb9,0x28,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 6428b9b7 + +fmlalltt z31.s, z31.b, z31.b // 01100100-00111111-10111011-11111111 +// CHECK-INST: fmlalltt z31.s, z31.b, z31.b +// CHECK-ENCODING: [0xff,0xbb,0x3f,0x64] +// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma) +// CHECK-UNKNOWN: 643fbbff diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 45f39a66ea8b34..3c6d463fee2598 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -1713,26 +1713,27 @@ TEST(TargetParserTest, testAArch64Extension) { TEST(TargetParserTest, AArch64ExtensionFeatures) { std::vector Extensions = { - AArch64::AEK_CRC, AArch64::AEK_LSE, AArch64::AEK_RDM, - AArch64::AEK_CRYPTO, AArch64::AEK_SM4, AArch64::AEK_SHA3, - AArch64::AEK_SHA2, AArch64::AEK_AES, AArch64::AEK_DOTPROD, - AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_FP16, - AArch64::AEK_FP16FML, AArch64::AEK_PROFILE, AArch64::AEK_RAS, - AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2AES, - AArch64::AEK_SVE2SM4, AArch64::AEK_SVE2SHA3, AArch64::AEK_SVE2BITPERM, - AArch64::AEK_RCPC, AArch64::AEK_RAND, AArch64::AEK_MTE, - AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_PREDRES, - AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_F32MM, - AArch64::AEK_F64MM, AArch64::AEK_TME, AArch64::AEK_LS64, - AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, - AArch64::AEK_SME, AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64, - AArch64::AEK_SME2, AArch64::AEK_HBC, AArch64::AEK_MOPS, - AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1, AArch64::AEK_SME2p1, - AArch64::AEK_B16B16, AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC, - AArch64::AEK_RCPC3, AArch64::AEK_THE, AArch64::AEK_D128, - AArch64::AEK_LSE128, AArch64::AEK_SPECRES2, AArch64::AEK_RASv2, - AArch64::AEK_ITE, AArch64::AEK_GCS, AArch64::AEK_FPMR, - AArch64::AEK_FP8, AArch64::AEK_FAMINMAX}; + AArch64::AEK_CRC, AArch64::AEK_LSE, AArch64::AEK_RDM, + AArch64::AEK_CRYPTO, AArch64::AEK_SM4, AArch64::AEK_SHA3, + AArch64::AEK_SHA2, AArch64::AEK_AES, AArch64::AEK_DOTPROD, + AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_FP16, + AArch64::AEK_FP16FML, AArch64::AEK_PROFILE, AArch64::AEK_RAS, + AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2AES, + AArch64::AEK_SVE2SM4, AArch64::AEK_SVE2SHA3, AArch64::AEK_SVE2BITPERM, + AArch64::AEK_RCPC, AArch64::AEK_RAND, AArch64::AEK_MTE, + AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_PREDRES, + AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_F32MM, + AArch64::AEK_F64MM, AArch64::AEK_TME, AArch64::AEK_LS64, + AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, + AArch64::AEK_SME, AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64, + AArch64::AEK_SME2, AArch64::AEK_HBC, AArch64::AEK_MOPS, + AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1, AArch64::AEK_SME2p1, + AArch64::AEK_B16B16, AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC, + AArch64::AEK_RCPC3, AArch64::AEK_THE, AArch64::AEK_D128, + AArch64::AEK_LSE128, AArch64::AEK_SPECRES2, AArch64::AEK_RASv2, + AArch64::AEK_ITE, AArch64::AEK_GCS, AArch64::AEK_FPMR, + AArch64::AEK_FP8, AArch64::AEK_FAMINMAX, AArch64::AEK_FP8FMA, + AArch64::AEK_SSVE_FP8FMA}; std::vector Features; @@ -1807,6 +1808,8 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { EXPECT_TRUE(llvm::is_contained(Features, "+fpmr")); EXPECT_TRUE(llvm::is_contained(Features, "+fp8")); EXPECT_TRUE(llvm::is_contained(Features, "+faminmax")); + EXPECT_TRUE(llvm::is_contained(Features, "+fp8fma")); + EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8fma")); // Assuming we listed every extension above, this should produce the same // result. (note that AEK_NONE doesn't have a name so it won't be in the @@ -1933,6 +1936,8 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { {"fpmr", "nofpmr", "+fpmr", "-fpmr"}, {"fp8", "nofp8", "+fp8", "-fp8"}, {"faminmax", "nofaminmax", "+faminmax", "-faminmax"}, + {"fp8fma", "nofp8fma", "+fp8fma", "-fp8fma"}, + {"ssve-fp8fma", "nossve-fp8fma", "+ssve-fp8fma", "-ssve-fp8fma"}, }; for (unsigned i = 0; i < std::size(ArchExt); i++) {