[llvm-branch-commits] [clang] [llvm] [AArch64][llvm] Add support for FEAT_FPv2 (PR #231436)
Martin Wehking via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Oct 13 03:02:06 PDT 2026
https://github.com/MartinWehking created https://github.com/llvm/llvm-project/pull/231436
Add support for FEAT_FPv2 (IEEE 754-2019 floating-point standard alignment) instructions.
>From 2cb69649447d412a6acfadaf3600f559fb514eb3 Mon Sep 17 00:00:00 2001
From: Martin Wehking <martin.wehking at arm.com>
Date: Tue, 15 Sep 2026 11:10:58 +0000
Subject: [PATCH] [AArch64][llvm] Add support for FEAT_FPv2
Add support for FEAT_FPv2 (IEEE 754-2019 floating-point standard alignment)
instructions.
---
clang/test/Driver/aarch64-vfat.c | 4 +
.../print-supported-extensions-aarch64.c | 1 +
llvm/lib/Target/AArch64/AArch64Features.td | 4 +
.../lib/Target/AArch64/AArch64InstrFormats.td | 54 +-
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 13 +
.../lib/Target/AArch64/AArch64SVEInstrInfo.td | 26 +
llvm/lib/Target/AArch64/AArch64SchedA53.td | 3 +-
llvm/lib/Target/AArch64/AArch64SchedA57.td | 3 +-
llvm/lib/Target/AArch64/AArch64SchedA64FX.td | 3 +-
.../lib/Target/AArch64/AArch64SchedAmpere1.td | 2 +-
.../Target/AArch64/AArch64SchedAmpere1B.td | 3 +-
.../lib/Target/AArch64/AArch64SchedCyclone.td | 3 +-
.../Target/AArch64/AArch64SchedExynosM3.td | 3 +-
.../Target/AArch64/AArch64SchedExynosM4.td | 3 +-
.../Target/AArch64/AArch64SchedExynosM5.td | 3 +-
llvm/lib/Target/AArch64/AArch64SchedFalkor.td | 3 +-
llvm/lib/Target/AArch64/AArch64SchedHIP12.td | 3 +-
llvm/lib/Target/AArch64/AArch64SchedKryo.td | 3 +-
.../Target/AArch64/AArch64SchedNeoverseN1.td | 3 +-
.../Target/AArch64/AArch64SchedNeoverseN2.td | 3 +-
.../Target/AArch64/AArch64SchedNeoverseN3.td | 3 +-
.../Target/AArch64/AArch64SchedNeoverseV1.td | 3 +-
.../Target/AArch64/AArch64SchedNeoverseV2.td | 3 +-
.../Target/AArch64/AArch64SchedNeoverseV3.td | 3 +-
.../AArch64/AArch64SchedNeoverseV3AE.td | 3 +-
.../lib/Target/AArch64/AArch64SchedOlympus.td | 3 +-
llvm/lib/Target/AArch64/AArch64SchedOryon.td | 3 +-
llvm/lib/Target/AArch64/AArch64SchedTSV110.td | 3 +-
.../Target/AArch64/AArch64SchedThunderX.td | 3 +-
.../AArch64/AArch64SchedThunderX2T99.td | 3 +-
.../AArch64/AArch64SchedThunderX3T110.td | 3 +-
.../AArch64/AsmParser/AArch64AsmParser.cpp | 1 +
llvm/lib/Target/AArch64/SVEInstrFormats.td | 100 ++++
.../test/MC/AArch64/FPv2/minmax-diagnostics.s | 31 ++
llvm/test/MC/AArch64/FPv2/minmax.s | 247 +++++++++
llvm/test/MC/AArch64/FPv2/total-compare.s | 49 ++
.../AArch64/SVE2p3/directive-arch-negative.s | 6 +
llvm/test/MC/AArch64/SVE2p3/directive-arch.s | 5 +
.../directive-arch_extension-negative.s | 7 +
.../AArch64/SVE2p3/directive-arch_extension.s | 6 +
.../MC/AArch64/SVE2p3/fcmtl-diagnostics.s | 64 +++
.../MC/AArch64/SVE2p3/minmax-diagnostics.s | 64 +++
llvm/test/MC/AArch64/SVE2p3/minmax.s | 514 ++++++++++++++++++
llvm/test/MC/AArch64/SVE2p3/total-compare.s | 51 ++
llvm/test/MC/AArch64/basic-a64-diagnostics.s | 37 ++
.../test/MC/AArch64/directive-arch-negative.s | 6 +
llvm/test/MC/AArch64/directive-arch.s | 4 +
.../directive-arch_extension-negative.s | 6 +
.../MC/AArch64/directive-arch_extension.s | 4 +
.../TargetParser/TargetParserTest.cpp | 7 +-
50 files changed, 1351 insertions(+), 34 deletions(-)
create mode 100644 llvm/test/MC/AArch64/FPv2/minmax-diagnostics.s
create mode 100644 llvm/test/MC/AArch64/FPv2/minmax.s
create mode 100644 llvm/test/MC/AArch64/FPv2/total-compare.s
create mode 100644 llvm/test/MC/AArch64/SVE2p3/directive-arch.s
create mode 100644 llvm/test/MC/AArch64/SVE2p3/directive-arch_extension.s
create mode 100644 llvm/test/MC/AArch64/SVE2p3/fcmtl-diagnostics.s
create mode 100644 llvm/test/MC/AArch64/SVE2p3/minmax-diagnostics.s
create mode 100644 llvm/test/MC/AArch64/SVE2p3/minmax.s
create mode 100644 llvm/test/MC/AArch64/SVE2p3/total-compare.s
diff --git a/clang/test/Driver/aarch64-vfat.c b/clang/test/Driver/aarch64-vfat.c
index 64aabd3cc8c3d..d61db5bca6d7d 100644
--- a/clang/test/Driver/aarch64-vfat.c
+++ b/clang/test/Driver/aarch64-vfat.c
@@ -21,3 +21,7 @@
// 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"
+
+// RUN: %clang -target aarch64 -march=armv9.8a+fpv2 -### -c %s 2>&1 | FileCheck -check-prefix=VFAT-FPV2 %s
+// RUN: %clang -target aarch64 -march=armv9.8-a+fpv2 -### -c %s 2>&1 | FileCheck -check-prefix=VFAT-FPV2 %s
+// VFAT-FPV2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.8a"{{.*}} "-target-feature" "+fpv2"
diff --git a/clang/test/Driver/print-supported-extensions-aarch64.c b/clang/test/Driver/print-supported-extensions-aarch64.c
index 55465def571bb..6ebcc018ac5f8 100644
--- a/clang/test/Driver/print-supported-extensions-aarch64.c
+++ b/clang/test/Driver/print-supported-extensions-aarch64.c
@@ -35,6 +35,7 @@
// CHECK-NEXT: fp8dot4 FEAT_FP8DOT4 Enable FP8 4-way dot instructions
// CHECK-NEXT: fp8fma FEAT_FP8FMA Enable Armv9.5-A FP8 multiply-add instructions
// CHECK-NEXT: fprcvt FEAT_FPRCVT Enable Armv9.6-A base convert instructions for SIMD&FP scalar register operands of different input and output sizes
+// CHECK-NEXT: fpv2 FEAT_FPv2 Enable IEEE 754-2019 floating-point standard alignment instructions
// CHECK-NEXT: fp16 FEAT_FP16 Enable half-precision floating-point data processing
// CHECK-NEXT: gcie FEAT_GCIE Enable GICv5 (Generic Interrupt Controller) CPU Interface Extension
// CHECK-NEXT: gcs FEAT_GCS Enable Armv9.4-A Guarded Call Stack Extension
diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td
index a9e5b4f8f0a58..b4c918ffa80bb 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 FeatureFPv2 : ExtensionWithMArch<"fpv2", "FPv2", "FEAT_FPv2",
+ "Enable IEEE 754-2019 floating-point standard alignment instructions",
+ [FeatureFullFP16]>;
+
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]>;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 3df66fa00fc28..297023ce9449f 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -5980,6 +5980,20 @@ multiclass TwoOperandFPData<bits<4> opcode, string asm,
}
}
+multiclass TwoOperandFPDataFPv2<bits<4> opcode, string asm> {
+ def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, []> {
+ let Inst{23-22} = 0b11; // 16-bit size flag
+ }
+
+ def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, []> {
+ let Inst{23-22} = 0b00; // 32-bit size flag
+ }
+
+ def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, []> {
+ let Inst{23-22} = 0b01; // 64-bit size flag
+ }
+}
+
multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm,
SDPatternOperator node> {
def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
@@ -6127,9 +6141,9 @@ class BaseOneOperandFPComparison<bit signalAllNans,
let PostEncoderMethod = "fixOneOperandFPComparison";
}
-let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
-class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
- string asm, list<dag> pat>
+let mayLoad = 0, mayStore = 0, hasSideEffects = 0, Uses = [FPCR] in
+class BaseTwoOperandFPComparison<bit signalAllNans, bit totalOrder, bit magnitude,
+ RegisterClass regtype, string asm, list<dag> pat>
: I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
Sched<[WriteFCmp]> {
bits<5> Rm;
@@ -6137,16 +6151,20 @@ class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
let Inst{31-24} = 0b00011110;
let Inst{21} = 1;
let Inst{20-16} = Rm;
- let Inst{15-10} = 0b001000;
+ let Inst{15} = totalOrder;
+ let Inst{14-10} = 0b01000;
let Inst{9-5} = Rn;
let Inst{4} = signalAllNans;
- let Inst{3-0} = 0b0000;
+ let Inst{3} = magnitude;
+ let Inst{2-0} = 0b000;
+
+ let mayRaiseFPException = !not(totalOrder);
}
multiclass FPComparison<bit signalAllNans, string asm,
SDPatternOperator OpNode = null_frag> {
let Defs = [NZCV] in {
- def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
+ def Hrr : BaseTwoOperandFPComparison<signalAllNans, 0b0, 0b0, FPR16, asm,
[(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
let Inst{23-22} = 0b11;
let Predicates = [HasFullFP16];
@@ -6158,7 +6176,7 @@ multiclass FPComparison<bit signalAllNans, string asm,
let Predicates = [HasFullFP16];
}
- def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
+ def Srr : BaseTwoOperandFPComparison<signalAllNans, 0b0, 0b0, FPR32, asm,
[(set NZCV, (OpNode FPR32:$Rn, (f32 FPR32:$Rm)))]> {
let Inst{23-22} = 0b00;
}
@@ -6168,7 +6186,7 @@ multiclass FPComparison<bit signalAllNans, string asm,
let Inst{23-22} = 0b00;
}
- def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
+ def Drr : BaseTwoOperandFPComparison<signalAllNans, 0b0, 0b0, FPR64, asm,
[(set NZCV, (OpNode FPR64:$Rn, (f64 FPR64:$Rm)))]> {
let Inst{23-22} = 0b01;
}
@@ -6180,6 +6198,26 @@ multiclass FPComparison<bit signalAllNans, string asm,
} // Defs = [NZCV]
}
+multiclass FPTotalOrderComparison<bit magnitude, string asm> {
+ let Defs = [NZCV] in {
+ let Predicates = [HasFullFP16, HasFPv2] in {
+ def Hrr : BaseTwoOperandFPComparison<0b0, 0b1, magnitude, FPR16, asm, []> {
+ let Inst{23-22} = 0b11;
+ }
+ }
+
+ let Predicates = [HasFPv2] in {
+ def Srr : BaseTwoOperandFPComparison<0b0, 0b1, magnitude, FPR32, asm, []> {
+ let Inst{23-22} = 0b00;
+ }
+
+ def Drr : BaseTwoOperandFPComparison<0b0, 0b1, magnitude, FPR64, asm, []> {
+ let Inst{23-22} = 0b01;
+ }
+ }
+ }
+}
+
//---
// Floating point conditional comparisons
//---
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 0d1152dadfd4b..6c0c152495f42 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -247,6 +247,8 @@ def HasSVE_PERM256 : Predicate<"Subtarget->hasSVE_PERM256()">,
AssemblerPredicateWithAll<(all_of FeatureSVE_PERM256), "sve-perm256">;
def HasSVE_LRCPC : Predicate<"Subtarget->isSVEAvailable() && Subtarget->hasSVE_LRCPC()">,
AssemblerPredicateWithAll<(all_of FeatureSVE_LRCPC), "sve-lrcpc">;
+def HasFPv2 : Predicate<"Subtarget->hasFPv2()">,
+ AssemblerPredicateWithAll<(all_of FeatureFPv2), "fpv2">;
// A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified.
@@ -5966,6 +5968,15 @@ defm FNMUL : TwoOperandFPDataNeg<0b1000, "fnmul", any_fmul>;
}
defm FSUB : TwoOperandFPData<0b0011, "fsub", any_fsub>;
+let Predicates = [HasFPv2] in {
+defm FMAXINM : TwoOperandFPDataFPv2<0b1010, "fmaxinm">;
+defm FMAXMG : TwoOperandFPDataFPv2<0b1100, "fmaxmg">;
+defm FMAXMGINM : TwoOperandFPDataFPv2<0b1110, "fmaxmginm">;
+defm FMININM : TwoOperandFPDataFPv2<0b1011, "fmininm">;
+defm FMINMG : TwoOperandFPDataFPv2<0b1101, "fminmg">;
+defm FMINMGINM : TwoOperandFPDataFPv2<0b1111, "fminmginm">;
+}
+
multiclass FMULScalarFromIndexedLane0Patterns<string inst,
string inst_f16_suffix,
string inst_f32_suffix,
@@ -6080,6 +6091,8 @@ def : Pat<(f64 (fma (fneg FPR64:$Rn), FPR64:$Rm, (fneg FPR64:$Ra))),
defm FCMPE : FPComparison<1, "fcmpe", AArch64strict_fcmpe>;
defm FCMP : FPComparison<0, "fcmp", AArch64any_fcmp>;
+defm FCMTL : FPTotalOrderComparison<0, "fcmtl">;
+defm FCMTLMG : FPTotalOrderComparison<1, "fcmtlmg">;
//===----------------------------------------------------------------------===//
// Floating point conditional comparison instructions.
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index b407d58ec1dd2..bffdcab44f123 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -5327,6 +5327,32 @@ let Predicates = [HasSVE, HasCPA] in {
def MLA_CPA : sve_int_mla_cpa<"mlapt">;
}
+//===----------------------------------------------------------------------===//
+// (FEAT_SVE2p3 || FEAT_SME2p3) && FEAT_FPv2 Instructions
+//===----------------------------------------------------------------------===//
+let Predicates = [HasSVE2p3_or_SME2p3, HasFPv2], hasNoSchedulingInfo = 1 in {
+ defm FCMTL_PZZ : sve_fp_3op_u_pd_totalcomp<0b100, "fcmtl">;
+ defm FCMTLMG_PZZ : sve_fp_3op_u_pd_totalcomp<0b101, "fcmtlmg">;
+} // End HasSVE_or_SME
+
+
+let Predicates = [HasSVE2p3_or_SME2p3, HasFPv2], hasNoSchedulingInfo = 1 in {
+ defm FMAXINM_ZPmZZ : sve_fp_2op_p_zds_minmax<0b0, 0b00, "fmaxinm">;
+ defm FMININM_ZPmZZ : sve_fp_2op_p_zds_minmax<0b0, 0b01, "fmininm">;
+ defm FMAXMGINM_ZPmZZ : sve_fp_2op_p_zds_minmax<0b1, 0b00, "fmaxmginm">;
+ defm FMINMGINM_ZPmZZ : sve_fp_2op_p_zds_minmax<0b1, 0b01, "fminmginm">;
+ defm FMAXMG_ZPmZZ : sve_fp_2op_p_zds_minmax<0b1, 0b10, "fmaxmg">;
+ defm FMINMG_ZPmZZ : sve_fp_2op_p_zds_minmax<0b1, 0b11, "fminmg">;
+
+ defm FMAXINMV_VPZ : sve_fp_fast_red_minmax<0b00, 0b0, "fmaxinmv">;
+ defm FMININMV_VPZ : sve_fp_fast_red_minmax<0b01, 0b0, "fmininmv">;
+ defm FMAXMGINMV_VPZ : sve_fp_fast_red_minmax<0b00, 0b1, "fmaxmginmv">;
+ defm FMINMGINMV_VPZ : sve_fp_fast_red_minmax<0b01, 0b1, "fminmginmv">;
+ defm FMAXMGV_VPZ : sve_fp_fast_red_minmax<0b10, 0b1, "fmaxmgv">;
+ defm FMINMGV_VPZ : sve_fp_fast_red_minmax<0b11, 0b1, "fminmgv">;
+} // End HasSVE_or_SME
+
+
//===----------------------------------------------------------------------===//
// Load-Acquire/Store-Release octaword (FEAT_SVE_LRCPC)
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedA53.td b/llvm/lib/Target/AArch64/AArch64SchedA53.td
index 291f78582d94a..dbc1edc06da19 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedA53.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedA53.td
@@ -29,7 +29,8 @@ def CortexA53Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
diff --git a/llvm/lib/Target/AArch64/AArch64SchedA57.td b/llvm/lib/Target/AArch64/AArch64SchedA57.td
index 9260379fb5b27..e4a473ce2a80a 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedA57.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedA57.td
@@ -34,7 +34,8 @@ def CortexA57Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td
index 8ecfa612af63e..7f4ed347b89ed 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td
@@ -23,7 +23,8 @@ def A64FXModel : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SMEUnsupported.F, SVEUnsupported.F,
[HasMTE, HasMatMulInt8, HasBF16,
HasPAuth, HasPAuthLR, HasCPA,
- HasCSSC, HasMOPS, HasMOPS_GO]);
+ HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
let FullInstRWOverlapCheck = 0;
}
diff --git a/llvm/lib/Target/AArch64/AArch64SchedAmpere1.td b/llvm/lib/Target/AArch64/AArch64SchedAmpere1.td
index 269f4ec5e5fb1..d013bc559a305 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedAmpere1.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedAmpere1.td
@@ -27,7 +27,7 @@ def Ampere1Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
SMEUnsupported.F,
PAUnsupported.F,
- [HasMTE]);
+ [HasMTE, HasFPv2]);
}
let SchedModel = Ampere1Model in {
diff --git a/llvm/lib/Target/AArch64/AArch64SchedAmpere1B.td b/llvm/lib/Target/AArch64/AArch64SchedAmpere1B.td
index d77c48126af39..347f0e2444c40 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedAmpere1B.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedAmpere1B.td
@@ -27,7 +27,8 @@ def Ampere1BModel : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
SMEUnsupported.F,
PAUnsupported.F,
- [HasMOPS, HasMOPS_GO]);
+ [HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
let SchedModel = Ampere1BModel in {
diff --git a/llvm/lib/Target/AArch64/AArch64SchedCyclone.td b/llvm/lib/Target/AArch64/AArch64SchedCyclone.td
index 7929ede8d099b..4f5616917742d 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedCyclone.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedCyclone.td
@@ -21,7 +21,8 @@ def CycloneModel : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td
index 3644617928dc2..12eaf12e6d28c 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td
@@ -27,7 +27,8 @@ def ExynosM3Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td
index e72d91101582a..5c8ea5788442a 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td
@@ -27,7 +27,8 @@ def ExynosM4Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td
index 35a787bdd8fc7..ef8a1afa50bf8 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td
@@ -27,7 +27,8 @@ def ExynosM5Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedFalkor.td b/llvm/lib/Target/AArch64/AArch64SchedFalkor.td
index 778a2621618a7..9d430da4c1c57 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedFalkor.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedFalkor.td
@@ -26,7 +26,8 @@ def FalkorModel : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
// FIXME: Remove when all errors have been fixed.
let FullInstRWOverlapCheck = 0;
}
diff --git a/llvm/lib/Target/AArch64/AArch64SchedHIP12.td b/llvm/lib/Target/AArch64/AArch64SchedHIP12.td
index 06a139bebcbe8..ade92141d0621 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedHIP12.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedHIP12.td
@@ -22,7 +22,8 @@ def HIP12Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SMEUnsupported.F,
SVE2p1Unsupported.F,
[HasSVEB16B16, HasSVEBFSCALE, HasMTE,
- HasCPA, HasCSSC, HasMOPS, HasMOPS_GO]);
+ HasCPA, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
let SchedModel = HIP12Model in {
diff --git a/llvm/lib/Target/AArch64/AArch64SchedKryo.td b/llvm/lib/Target/AArch64/AArch64SchedKryo.td
index eec8f37906fd4..f4e17f66609f5 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedKryo.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedKryo.td
@@ -30,7 +30,8 @@ def KryoModel : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
// FIXME: Remove when all errors have been fixed.
let FullInstRWOverlapCheck = 0;
}
diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN1.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN1.td
index 8847f32a9da9a..bd3389d215070 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN1.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN1.td
@@ -27,7 +27,8 @@ def NeoverseN1Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(PAUnsupported.F,
SMEUnsupported.F,
SVEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td
index 60eaf069ca3e1..b503dce891aec 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td
@@ -20,7 +20,8 @@ def NeoverseN2Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SMEUnsupported.F,
SVE2p1Unsupported.F,
- [HasSVE2p1, HasSVEB16B16, HasSVEBFSCALE, HasPAuthLR, HasCPA, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasSVE2p1, HasSVEB16B16, HasSVEBFSCALE, HasPAuthLR, HasCPA, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN3.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN3.td
index 0e0fcc554f753..bf407784c5682 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN3.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN3.td
@@ -20,7 +20,8 @@ def NeoverseN3Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SMEUnsupported.F,
SVE2p1Unsupported.F,
- [HasSVE2p1, HasSVEB16B16, HasSVEBFSCALE, HasPAuthLR, HasCPA, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasSVE2p1, HasSVEB16B16, HasSVEBFSCALE, HasPAuthLR, HasCPA, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td
index eb9f8f8c04bff..4bd21739dc262 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td
@@ -31,7 +31,8 @@ def NeoverseV1Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVE2Unsupported.F,
SMEUnsupported.F,
[HasMTE, HasCPA,
- HasCSSC, HasMOPS, HasMOPS_GO]);
+ HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV2.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV2.td
index 1e16cfbef8bd0..177978b16c548 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV2.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV2.td
@@ -27,7 +27,8 @@ def NeoverseV2Model : SchedMachineModel {
SVE2p1Unsupported.F,
[HasSVE2p1, HasSVEB16B16,
HasSVEBFSCALE,
- HasCPA, HasCSSC, HasMOPS, HasMOPS_GO]);
+ HasCPA, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV3.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV3.td
index 4fbaba8aa6c73..c7789c1db2500 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV3.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV3.td
@@ -25,7 +25,8 @@ def NeoverseV3Model : SchedMachineModel {
SVE2p1Unsupported.F,
[HasSVE2p1, HasSVEB16B16,
HasSVEBFSCALE,
- HasCPA, HasCSSC, HasMOPS, HasMOPS_GO]);
+ HasCPA, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV3AE.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV3AE.td
index 3fcef7d7cc31a..39d545ef284bd 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV3AE.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV3AE.td
@@ -25,7 +25,8 @@ def NeoverseV3AEModel : SchedMachineModel {
SVE2p1Unsupported.F,
[HasSVE2p1, HasSVEB16B16,
HasSVEBFSCALE,
- HasCPA, HasCSSC, HasMOPS, HasMOPS_GO]);
+ HasCPA, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedOlympus.td b/llvm/lib/Target/AArch64/AArch64SchedOlympus.td
index 39cda0de13750..c80f56f952678 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedOlympus.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedOlympus.td
@@ -28,7 +28,8 @@ def OlympusModel : SchedMachineModel {
[HasSVE2p1, HasSVEB16B16,
HasSVEBFSCALE,
HasCPA, HasCSSC,
- HasMatMulFP64, HasMOPS, HasMOPS_GO]);
+ HasMatMulFP64, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedOryon.td b/llvm/lib/Target/AArch64/AArch64SchedOryon.td
index e113bf4525274..0a44a29d04d66 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedOryon.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedOryon.td
@@ -27,7 +27,8 @@ def OryonModel : SchedMachineModel {
SMEUnsupported.F,
MTEUnsupported.F,
PAUnsupported.F,
- [HasPAuth, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasPAuth, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
let SchedModel = OryonModel in {
diff --git a/llvm/lib/Target/AArch64/AArch64SchedTSV110.td b/llvm/lib/Target/AArch64/AArch64SchedTSV110.td
index 2915b69de47ef..7382250526fea 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedTSV110.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedTSV110.td
@@ -28,7 +28,8 @@ def TSV110Model : SchedMachineModel {
SVE2p1Unsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
}
// Define each kind of processor resource and number available on the TSV110,
diff --git a/llvm/lib/Target/AArch64/AArch64SchedThunderX.td b/llvm/lib/Target/AArch64/AArch64SchedThunderX.td
index e9f2d7618e199..a45308851196b 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedThunderX.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedThunderX.td
@@ -28,7 +28,8 @@ def ThunderXT8XModel : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
// FIXME: Remove when all errors have been fixed.
let FullInstRWOverlapCheck = 0;
}
diff --git a/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td b/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td
index 5d2adb938d687..1d3a77c282c54 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td
@@ -28,7 +28,8 @@ def ThunderX2T99Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
// FIXME: Remove when all errors have been fixed.
let FullInstRWOverlapCheck = 0;
}
diff --git a/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td b/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td
index 80f37d306a48a..4cb1d7a8a79f7 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td
@@ -27,7 +27,8 @@ def ThunderX3T110Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
PAUnsupported.F,
SMEUnsupported.F,
- [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO]);
+ [HasMTE, HasCSSC, HasMOPS, HasMOPS_GO,
+ HasFPv2]);
// FIXME: Remove when all errors have been fixed.
let FullInstRWOverlapCheck = 0;
}
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 49c253c658b69..e2910cc0518fd 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -3767,6 +3767,7 @@ constexpr EnumStringDef<FeatureBitset> ExtensionDefs[] = {
{{"sve-lrcpc"}, {AArch64::FeatureSVE_LRCPC}},
{{"sve-perm256"}, {AArch64::FeatureSVE_PERM256}},
{{"sme-f16f8f16"}, {AArch64::FeatureSMEF16F8F16}},
+ {{"fpv2"}, {AArch64::FeatureFPv2}},
};
constexpr auto ExtensionMap = BUILD_ENUM_STRINGS(ExtensionDefs);
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 7b1aade4cc004..11974390bcfb1 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -6308,6 +6308,106 @@ multiclass sve_fp_2op_p_pd<bits<3> opc, string asm,
}
+//===----------------------------------------------------------------------===//
+// SVE Floating Point Compare - Total Order
+//===----------------------------------------------------------------------===//
+
+class sve_fp_3op_u_pd<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty,
+ PPRRegOp pprty>
+: I<(outs pprty:$Pd), (ins zprty:$Zn, zprty:$Zm),
+ asm, "\t$Pd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<4> Pd;
+ bits<5> Zm;
+ bits<5> Zn;
+ let Inst{31-24} = 0b01100101;
+ let Inst{23-22} = sz;
+ let Inst{21} = 0b0;
+ let Inst{20-16} = Zm;
+ let Inst{15-13} = 0b000;
+ let Inst{12-10} = opc;
+ let Inst{9-5} = Zn;
+ let Inst{4} = 0;
+ let Inst{3-0} = Pd;
+
+ let hasSideEffects = 0;
+ let Uses = [ FPCR ];
+}
+
+
+multiclass sve_fp_3op_u_pd_totalcomp<bits<3> opc, string asm> {
+ def _H : sve_fp_3op_u_pd<0b01, opc, asm, ZPR16, PPR16>;
+ def _S : sve_fp_3op_u_pd<0b10, opc, asm, ZPR32, PPR32>;
+ def _D : sve_fp_3op_u_pd<0b11, opc, asm, ZPR64, PPR64>;
+}
+
+//===----------------------------------------------------------------------===//
+// SVE Min Max
+//===----------------------------------------------------------------------===//
+
+class sve_fp_2op_p_zds_minmax<bits<2> sz, bits<1> op, bits<2> opc, string asm,
+ ZPRRegOp zprty>
+: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
+ asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
+ "",
+ []>, Sched<[]> {
+ bits<3> Pg;
+ bits<5> Zdn;
+ bits<5> Zm;
+ let Inst{31-24} = 0b01100100;
+ let Inst{23-22} = sz;
+ let Inst{21-20} = 0b00;
+ let Inst{19} = op;
+ let Inst{18} = 0b0;
+ let Inst{17-16} = opc;
+ let Inst{15-13} = 0b111;
+ let Inst{12-10} = Pg;
+ let Inst{9-5} = Zm;
+ let Inst{4-0} = Zdn;
+
+ let Constraints = "$Zdn = $_Zdn";
+ let DestructiveInstType = DestructiveOther;
+ let ElementSize = zprty.ElementSize;
+ let Uses = [ FPCR ];
+}
+
+multiclass sve_fp_2op_p_zds_minmax<bits<1> op, bits<2> opc, string asm> {
+ def _H : sve_fp_2op_p_zds_minmax<0b01, op, opc, asm, ZPR16>;
+ def _S : sve_fp_2op_p_zds_minmax<0b10, op, opc, asm, ZPR32>;
+ def _D : sve_fp_2op_p_zds_minmax<0b11, op, opc, asm, ZPR64>;
+}
+
+class sve_fp_fast_red_minmax<bits<2> sz, bits<2> opc, bit R, string asm,
+ ZPRRegOp zprty, RegisterClass dstRegClass>
+: I<(outs dstRegClass:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
+ asm, "\t$Vd, $Pg, $Zn",
+ "",
+ []>, Sched<[]> {
+ bits<5> Vd;
+ bits<5> Zn;
+ bits<3> Pg;
+ let Inst{31-24} = 0b01100100;
+ let Inst{23-22} = sz;
+ let Inst{21-18} = 0b0101;
+ let Inst{17-16} = opc;
+ let Inst{15-14} = 0b11;
+ let Inst{13} = R;
+ let Inst{12-10} = Pg;
+ let Inst{9-5} = Zn;
+ let Inst{4-0} = Vd;
+
+ let hasSideEffects = 0;
+ let mayRaiseFPException = 1;
+ let Uses = [ FPCR ];
+}
+
+multiclass sve_fp_fast_red_minmax<bits<2> opc, bit R, string asm> {
+ def _H : sve_fp_fast_red_minmax<0b01, opc, R, asm, ZPR16, FPR16>;
+ def _S : sve_fp_fast_red_minmax<0b10, opc, R, asm, ZPR32, FPR32>;
+ def _D : sve_fp_fast_red_minmax<0b11, opc, R, asm, ZPR64, FPR64>;
+}
+
+
//===----------------------------------------------------------------------===//
//SVE Index Generation Group
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/FPv2/minmax-diagnostics.s b/llvm/test/MC/AArch64/FPv2/minmax-diagnostics.s
new file mode 100644
index 0000000000000..ebbba316737f4
--- /dev/null
+++ b/llvm/test/MC/AArch64/FPv2/minmax-diagnostics.s
@@ -0,0 +1,31 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+fpv2 2>&1 < %s | FileCheck %s
+
+fmaxinm h0, s1, h2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmaxinm h0, s1, h2
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmininm s0, s1, d2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmininm s0, s1, d2
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmaxmg d0, h1, d2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmaxmg d0, h1, d2
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fminmg b0, b1, b2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fminmg b0, b1, b2
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmaxmginm b0, b1, b2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmaxmginm b0, b1, b2
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fminmginm b0, b1, b2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fminmginm b0, b1, b2
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/FPv2/minmax.s b/llvm/test/MC/AArch64/FPv2/minmax.s
new file mode 100644
index 0000000000000..d6b864453cee0
--- /dev/null
+++ b/llvm/test/MC/AArch64/FPv2/minmax.s
@@ -0,0 +1,247 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fpv2 < %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=+fpv2 < %s \
+// RUN: | llvm-objdump -d --mattr=+fpv2 --no-print-imm-hex - \
+// RUN: | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+fpv2 < %s \
+// RUN: | llvm-objdump -d --mattr=-fpv2 --no-print-imm-hex - \
+// RUN: | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fpv2 < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+fpv2 -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// FMAXINM
+
+fmaxinm h0, h0, h0
+// CHECK-INST: fmaxinm h0, h0, h0
+// CHECK-ENCODING: encoding: [0x00,0xa8,0xe0,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1ee0a800 <unknown>
+
+fmaxinm h31, h31, h31
+// CHECK-INST: fmaxinm h31, h31, h31
+// CHECK-ENCODING: encoding: [0xff,0xab,0xff,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1effabff <unknown>
+
+fmaxinm s0, s0, s0
+// CHECK-INST: fmaxinm s0, s0, s0
+// CHECK-ENCODING: encoding: [0x00,0xa8,0x20,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e20a800 <unknown>
+
+fmaxinm s31, s31, s31
+// CHECK-INST: fmaxinm s31, s31, s31
+// CHECK-ENCODING: encoding: [0xff,0xab,0x3f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e3fabff <unknown>
+
+fmaxinm d0, d0, d0
+// CHECK-INST: fmaxinm d0, d0, d0
+// CHECK-ENCODING: encoding: [0x00,0xa8,0x60,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e60a800 <unknown>
+
+fmaxinm d31, d31, d31
+// CHECK-INST: fmaxinm d31, d31, d31
+// CHECK-ENCODING: encoding: [0xff,0xab,0x7f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e7fabff <unknown>
+
+
+// FMININM
+
+fmininm h0, h0, h0
+// CHECK-INST: fmininm h0, h0, h0
+// CHECK-ENCODING: encoding: [0x00,0xb8,0xe0,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1ee0b800 <unknown>
+
+fmininm h31, h31, h31
+// CHECK-INST: fmininm h31, h31, h31
+// CHECK-ENCODING: encoding: [0xff,0xbb,0xff,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1effbbff <unknown>
+
+fmininm s0, s0, s0
+// CHECK-INST: fmininm s0, s0, s0
+// CHECK-ENCODING: encoding: [0x00,0xb8,0x20,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e20b800 <unknown>
+
+fmininm s31, s31, s31
+// CHECK-INST: fmininm s31, s31, s31
+// CHECK-ENCODING: encoding: [0xff,0xbb,0x3f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e3fbbff <unknown>
+
+fmininm d0, d0, d0
+// CHECK-INST: fmininm d0, d0, d0
+// CHECK-ENCODING: encoding: [0x00,0xb8,0x60,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e60b800 <unknown>
+
+fmininm d31, d31, d31
+// CHECK-INST: fmininm d31, d31, d31
+// CHECK-ENCODING: encoding: [0xff,0xbb,0x7f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e7fbbff <unknown>
+
+
+// FMAXMG
+
+fmaxmg h0, h0, h0
+// CHECK-INST: fmaxmg h0, h0, h0
+// CHECK-ENCODING: encoding: [0x00,0xc8,0xe0,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1ee0c800 <unknown>
+
+fmaxmg h31, h31, h31
+// CHECK-INST: fmaxmg h31, h31, h31
+// CHECK-ENCODING: encoding: [0xff,0xcb,0xff,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1effcbff <unknown>
+
+fmaxmg s0, s0, s0
+// CHECK-INST: fmaxmg s0, s0, s0
+// CHECK-ENCODING: encoding: [0x00,0xc8,0x20,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e20c800 <unknown>
+
+fmaxmg s31, s31, s31
+// CHECK-INST: fmaxmg s31, s31, s31
+// CHECK-ENCODING: encoding: [0xff,0xcb,0x3f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e3fcbff <unknown>
+
+fmaxmg d0, d0, d0
+// CHECK-INST: fmaxmg d0, d0, d0
+// CHECK-ENCODING: encoding: [0x00,0xc8,0x60,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e60c800 <unknown>
+
+fmaxmg d31, d31, d31
+// CHECK-INST: fmaxmg d31, d31, d31
+// CHECK-ENCODING: encoding: [0xff,0xcb,0x7f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e7fcbff <unknown>
+
+
+// FMINMG
+
+fminmg h0, h0, h0
+// CHECK-INST: fminmg h0, h0, h0
+// CHECK-ENCODING: encoding: [0x00,0xd8,0xe0,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1ee0d800 <unknown>
+
+fminmg h31, h31, h31
+// CHECK-INST: fminmg h31, h31, h31
+// CHECK-ENCODING: encoding: [0xff,0xdb,0xff,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1effdbff <unknown>
+
+fminmg s0, s0, s0
+// CHECK-INST: fminmg s0, s0, s0
+// CHECK-ENCODING: encoding: [0x00,0xd8,0x20,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e20d800 <unknown>
+
+fminmg s31, s31, s31
+// CHECK-INST: fminmg s31, s31, s31
+// CHECK-ENCODING: encoding: [0xff,0xdb,0x3f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e3fdbff <unknown>
+
+fminmg d0, d0, d0
+// CHECK-INST: fminmg d0, d0, d0
+// CHECK-ENCODING: encoding: [0x00,0xd8,0x60,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e60d800 <unknown>
+
+fminmg d31, d31, d31
+// CHECK-INST: fminmg d31, d31, d31
+// CHECK-ENCODING: encoding: [0xff,0xdb,0x7f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e7fdbff <unknown>
+
+
+// FMAXMGINM
+
+fmaxmginm h0, h0, h0
+// CHECK-INST: fmaxmginm h0, h0, h0
+// CHECK-ENCODING: encoding: [0x00,0xe8,0xe0,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1ee0e800 <unknown>
+
+fmaxmginm h31, h31, h31
+// CHECK-INST: fmaxmginm h31, h31, h31
+// CHECK-ENCODING: encoding: [0xff,0xeb,0xff,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1effebff <unknown>
+
+fmaxmginm s0, s0, s0
+// CHECK-INST: fmaxmginm s0, s0, s0
+// CHECK-ENCODING: encoding: [0x00,0xe8,0x20,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e20e800 <unknown>
+
+fmaxmginm s31, s31, s31
+// CHECK-INST: fmaxmginm s31, s31, s31
+// CHECK-ENCODING: encoding: [0xff,0xeb,0x3f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e3febff <unknown>
+
+fmaxmginm d0, d0, d0
+// CHECK-INST: fmaxmginm d0, d0, d0
+// CHECK-ENCODING: encoding: [0x00,0xe8,0x60,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e60e800 <unknown>
+
+fmaxmginm d31, d31, d31
+// CHECK-INST: fmaxmginm d31, d31, d31
+// CHECK-ENCODING: encoding: [0xff,0xeb,0x7f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e7febff <unknown>
+
+
+// FMINMGINM
+
+fminmginm h0, h0, h0
+// CHECK-INST: fminmginm h0, h0, h0
+// CHECK-ENCODING: encoding: [0x00,0xf8,0xe0,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1ee0f800 <unknown>
+
+fminmginm h31, h31, h31
+// CHECK-INST: fminmginm h31, h31, h31
+// CHECK-ENCODING: encoding: [0xff,0xfb,0xff,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1efffbff <unknown>
+
+fminmginm s0, s0, s0
+// CHECK-INST: fminmginm s0, s0, s0
+// CHECK-ENCODING: encoding: [0x00,0xf8,0x20,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e20f800 <unknown>
+
+fminmginm s31, s31, s31
+// CHECK-INST: fminmginm s31, s31, s31
+// CHECK-ENCODING: encoding: [0xff,0xfb,0x3f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e3ffbff <unknown>
+
+fminmginm d0, d0, d0
+// CHECK-INST: fminmginm d0, d0, d0
+// CHECK-ENCODING: encoding: [0x00,0xf8,0x60,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e60f800 <unknown>
+
+fminmginm d31, d31, d31
+// CHECK-INST: fminmginm d31, d31, d31
+// CHECK-ENCODING: encoding: [0xff,0xfb,0x7f,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e7ffbff <unknown>
diff --git a/llvm/test/MC/AArch64/FPv2/total-compare.s b/llvm/test/MC/AArch64/FPv2/total-compare.s
new file mode 100644
index 0000000000000..8ad9bc46b0bcf
--- /dev/null
+++ b/llvm/test/MC/AArch64/FPv2/total-compare.s
@@ -0,0 +1,49 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fpv2 < %s \
+// RUN: | FileCheck %s --ignore-case --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --ignore-case --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+fpv2 < %s \
+// RUN: | llvm-objdump -d --mattr=+fpv2 --no-print-imm-hex - | FileCheck %s --ignore-case --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+fpv2 < %s \
+// RUN: | llvm-objdump -d --mattr=-fpv2 --no-print-imm-hex - | FileCheck %s --ignore-case --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fpv2 < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+fpv2 -disassemble -show-encoding \
+// RUN: | FileCheck %s --ignore-case --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+fcmtl h31, h0
+// CHECK-INST: fcmtl h31, h0
+// CHECK-ENCODING: encoding: [0xe0,0xa3,0xe0,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1ee0a3e0 <unknown>
+
+fcmtl s31, s0
+// CHECK-INST: fcmtl s31, s0
+// CHECK-ENCODING: encoding: [0xe0,0xa3,0x20,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e20a3e0 <unknown>
+
+fcmtl d31, d0
+// CHECK-INST: fcmtl d31, d0
+// CHECK-ENCODING: encoding: [0xe0,0xa3,0x60,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e60a3e0 <unknown>
+
+fcmtlmg h31, h0
+// CHECK-INST: fcmtlmg h31, h0
+// CHECK-ENCODING: encoding: [0xe8,0xa3,0xe0,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1ee0a3e8 <unknown>
+
+fcmtlmg s31, s0
+// CHECK-INST: fcmtlmg s31, s0
+// CHECK-ENCODING: encoding: [0xe8,0xa3,0x20,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e20a3e8 <unknown>
+
+fcmtlmg d31, d0
+// CHECK-INST: fcmtlmg d31, d0
+// CHECK-ENCODING: encoding: [0xe8,0xa3,0x60,0x1e]
+// CHECK-ERROR: instruction requires: fpv2
+// CHECK-UNKNOWN: 1e60a3e8 <unknown>
diff --git a/llvm/test/MC/AArch64/SVE2p3/directive-arch-negative.s b/llvm/test/MC/AArch64/SVE2p3/directive-arch-negative.s
index 0a12cf85cb007..c35ac3f57c55b 100644
--- a/llvm/test/MC/AArch64/SVE2p3/directive-arch-negative.s
+++ b/llvm/test/MC/AArch64/SVE2p3/directive-arch-negative.s
@@ -5,3 +5,9 @@
addqp z0.b, z0.b, z0.b
// CHECK: error: instruction requires: sme2p3 or sve2p3
// CHECK-NEXT: addqp z0.b, z0.b, z0.b
+
+.arch armv9-a+sve2p3+fpv2
+.arch armv9-a+sve2p3+nofpv2
+fcmtl p15.s, z31.s, z31.s
+// CHECK: error: instruction requires: fpv2
+// CHECK-NEXT: fcmtl p15.s, z31.s, z31.s
diff --git a/llvm/test/MC/AArch64/SVE2p3/directive-arch.s b/llvm/test/MC/AArch64/SVE2p3/directive-arch.s
new file mode 100644
index 0000000000000..aa28f241516b3
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p3/directive-arch.s
@@ -0,0 +1,5 @@
+// RUN: llvm-mc -triple=aarch64 < %s | FileCheck %s
+
+.arch armv9-a+sve2p3+fpv2
+fcmtl p15.s, z31.s, z31.s
+// CHECK: fcmtl p15.s, z31.s, z31.s
diff --git a/llvm/test/MC/AArch64/SVE2p3/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SVE2p3/directive-arch_extension-negative.s
index 1af6245abe16d..da38d90470a27 100644
--- a/llvm/test/MC/AArch64/SVE2p3/directive-arch_extension-negative.s
+++ b/llvm/test/MC/AArch64/SVE2p3/directive-arch_extension-negative.s
@@ -5,3 +5,10 @@
addqp z0.b, z0.b, z0.b
// CHECK: error: instruction requires: sme2p3 or sve2p3
// CHECK-NEXT: addqp z0.b, z0.b, z0.b
+
+.arch_extension sve2p3
+.arch_extension fpv2
+.arch_extension nofpv2
+fcmtl p15.s, z31.s, z31.s
+// CHECK: error: instruction requires: fpv2
+// CHECK-NEXT: fcmtl p15.s, z31.s, z31.s
diff --git a/llvm/test/MC/AArch64/SVE2p3/directive-arch_extension.s b/llvm/test/MC/AArch64/SVE2p3/directive-arch_extension.s
new file mode 100644
index 0000000000000..d976a508d3713
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p3/directive-arch_extension.s
@@ -0,0 +1,6 @@
+// RUN: llvm-mc -triple=aarch64 < %s | FileCheck %s
+
+.arch_extension sve2p3
+.arch_extension fpv2
+fcmtl p15.s, z31.s, z31.s
+// CHECK: fcmtl p15.s, z31.s, z31.s
diff --git a/llvm/test/MC/AArch64/SVE2p3/fcmtl-diagnostics.s b/llvm/test/MC/AArch64/SVE2p3/fcmtl-diagnostics.s
new file mode 100644
index 0000000000000..20f3302ba9019
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p3/fcmtl-diagnostics.s
@@ -0,0 +1,64 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3,+fpv2 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid predicate register
+
+fcmtl p0.b, z0.b, z1.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register
+// CHECK-NEXT: fcmtl p0.b, z0.b, z1.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcmtlmg p0.b, z0.b, z1.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register
+// CHECK-NEXT: fcmtlmg p0.b, z0.b, z1.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid element widths
+
+fcmtl p0.h, z0.s, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcmtl p0.h, z0.s, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcmtl p0.s, z0.s, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcmtl p0.s, z0.s, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcmtlmg p0.h, z0.s, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcmtlmg p0.h, z0.s, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fcmtlmg p0.s, z0.s, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fcmtlmg p0.s, z0.s, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.d, p0/z, z7.d
+fcmtl p0.d, z0.d, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcmtl p0.d, z0.d, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+fcmtl p0.d, z0.d, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcmtl p0.d, z0.d, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0.d, p0/z, z7.d
+fcmtlmg p0.d, z0.d, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcmtlmg p0.d, z0.d, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z0, z7
+fcmtlmg p0.d, z0.d, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
+// CHECK-NEXT: fcmtlmg p0.d, z0.d, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE2p3/minmax-diagnostics.s b/llvm/test/MC/AArch64/SVE2p3/minmax-diagnostics.s
new file mode 100644
index 0000000000000..b189506ceb0b0
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p3/minmax-diagnostics.s
@@ -0,0 +1,64 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3,+fpv2 2>&1 < %s | FileCheck %s
+
+fmaxinm z0.h, p0/m, z1.h, z2.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register
+// CHECK-NEXT: fmaxinm z0.h, p0/m, z1.h, z2.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmininm z0.b, p0/m, z0.b, z1.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmininm z0.b, p0/m, z0.b, z1.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmaxmg z0.h, p0/m, z0.h, z1.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmaxmg z0.h, p0/m, z0.h, z1.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fminmg z0.h, p8/m, z0.h, z1.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: fminmg z0.h, p8/m, z0.h, z1.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmaxmginm z0.h, p0/z, z0.h, z1.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmaxmginm z0.h, p0/z, z0.h, z1.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fminmginm z0.s, p0/m, z0.s, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fminmginm z0.s, p0/m, z0.s, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid reduction operands
+
+fmaxinmv h0, p8, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: fmaxinmv h0, p8, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmininmv b0, p0, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmininmv b0, p0, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmaxmgv z0.d, p0, z1.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmaxmgv z0.d, p0, z1.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fminmgv h0, p0, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fminmgv h0, p0, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmaxmginmv h0, p0/m, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmaxmginmv h0, p0/m, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fminmginmv v0.8h, p0, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fminmginmv v0.8h, p0, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE2p3/minmax.s b/llvm/test/MC/AArch64/SVE2p3/minmax.s
new file mode 100644
index 0000000000000..a64d80b4c7a37
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p3/minmax.s
@@ -0,0 +1,514 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3,+fpv2 < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p3,+fpv2 < %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,+fpv2 < %s \
+// RUN: | llvm-objdump -d --mattr=+sve2p3,+fpv2 --no-print-imm-hex - \
+// RUN: | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p3,+fpv2 < %s \
+// RUN: | llvm-objdump -d --mattr=-all --no-print-imm-hex - \
+// RUN: | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3,+fpv2 < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p3,+fpv2 -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// FMAXINM (predicated vectors)
+
+fmaxinm z0.h, p0/m, z0.h, z0.h
+// CHECK-INST: fmaxinm z0.h, p0/m, z0.h, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x40,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6440e000 <unknown>
+
+fmaxinm z31.h, p7/m, z31.h, z31.h
+// CHECK-INST: fmaxinm z31.h, p7/m, z31.h, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x40,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6440ffff <unknown>
+
+fmaxinm z0.s, p0/m, z0.s, z0.s
+// CHECK-INST: fmaxinm z0.s, p0/m, z0.s, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x80,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6480e000 <unknown>
+
+fmaxinm z31.s, p7/m, z31.s, z31.s
+// CHECK-INST: fmaxinm z31.s, p7/m, z31.s, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x80,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6480ffff <unknown>
+
+fmaxinm z0.d, p0/m, z0.d, z0.d
+// CHECK-INST: fmaxinm z0.d, p0/m, z0.d, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xc0,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64c0e000 <unknown>
+
+fmaxinm z31.d, p7/m, z31.d, z31.d
+// CHECK-INST: fmaxinm z31.d, p7/m, z31.d, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xc0,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64c0ffff <unknown>
+
+movprfx z0.h, p0/m, z27.h
+fmaxinm z0.h, p0/m, z0.h, z31.h
+// CHECK-INST: fmaxinm z0.h, p0/m, z0.h, z31.h
+// CHECK-ENCODING: encoding: [0xe0,0xe3,0x40,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6440e3e0 <unknown>
+
+// FMININM (predicated vectors)
+
+fmininm z0.h, p0/m, z0.h, z0.h
+// CHECK-INST: fmininm z0.h, p0/m, z0.h, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x41,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6441e000 <unknown>
+
+fmininm z31.h, p7/m, z31.h, z31.h
+// CHECK-INST: fmininm z31.h, p7/m, z31.h, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x41,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6441ffff <unknown>
+
+fmininm z0.s, p0/m, z0.s, z0.s
+// CHECK-INST: fmininm z0.s, p0/m, z0.s, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x81,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6481e000 <unknown>
+
+fmininm z31.s, p7/m, z31.s, z31.s
+// CHECK-INST: fmininm z31.s, p7/m, z31.s, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x81,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6481ffff <unknown>
+
+fmininm z0.d, p0/m, z0.d, z0.d
+// CHECK-INST: fmininm z0.d, p0/m, z0.d, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xc1,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64c1e000 <unknown>
+
+fmininm z31.d, p7/m, z31.d, z31.d
+// CHECK-INST: fmininm z31.d, p7/m, z31.d, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xc1,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64c1ffff <unknown>
+
+movprfx z0.h, p0/m, z27.h
+fmininm z0.h, p0/m, z0.h, z31.h
+// CHECK-INST: fmininm z0.h, p0/m, z0.h, z31.h
+// CHECK-ENCODING: encoding: [0xe0,0xe3,0x41,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6441e3e0 <unknown>
+
+// FMAXMG (predicated vectors)
+
+fmaxmg z0.h, p0/m, z0.h, z0.h
+// CHECK-INST: fmaxmg z0.h, p0/m, z0.h, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x4a,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 644ae000 <unknown>
+
+fmaxmg z31.h, p7/m, z31.h, z31.h
+// CHECK-INST: fmaxmg z31.h, p7/m, z31.h, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x4a,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 644affff <unknown>
+
+fmaxmg z0.s, p0/m, z0.s, z0.s
+// CHECK-INST: fmaxmg z0.s, p0/m, z0.s, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x8a,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 648ae000 <unknown>
+
+fmaxmg z31.s, p7/m, z31.s, z31.s
+// CHECK-INST: fmaxmg z31.s, p7/m, z31.s, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x8a,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 648affff <unknown>
+
+fmaxmg z0.d, p0/m, z0.d, z0.d
+// CHECK-INST: fmaxmg z0.d, p0/m, z0.d, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xca,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64cae000 <unknown>
+
+fmaxmg z31.d, p7/m, z31.d, z31.d
+// CHECK-INST: fmaxmg z31.d, p7/m, z31.d, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xca,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64caffff <unknown>
+
+movprfx z0.h, p0/m, z27.h
+fmaxmg z0.h, p0/m, z0.h, z31.h
+// CHECK-INST: fmaxmg z0.h, p0/m, z0.h, z31.h
+// CHECK-ENCODING: encoding: [0xe0,0xe3,0x4a,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 644ae3e0 <unknown>
+
+// FMINMG (predicated vectors)
+
+fminmg z0.h, p0/m, z0.h, z0.h
+// CHECK-INST: fminmg z0.h, p0/m, z0.h, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x4b,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 644be000 <unknown>
+
+fminmg z31.h, p7/m, z31.h, z31.h
+// CHECK-INST: fminmg z31.h, p7/m, z31.h, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x4b,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 644bffff <unknown>
+
+fminmg z0.s, p0/m, z0.s, z0.s
+// CHECK-INST: fminmg z0.s, p0/m, z0.s, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x8b,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 648be000 <unknown>
+
+fminmg z31.s, p7/m, z31.s, z31.s
+// CHECK-INST: fminmg z31.s, p7/m, z31.s, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x8b,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 648bffff <unknown>
+
+fminmg z0.d, p0/m, z0.d, z0.d
+// CHECK-INST: fminmg z0.d, p0/m, z0.d, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xcb,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64cbe000 <unknown>
+
+fminmg z31.d, p7/m, z31.d, z31.d
+// CHECK-INST: fminmg z31.d, p7/m, z31.d, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xcb,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64cbffff <unknown>
+
+movprfx z0.h, p0/m, z27.h
+fminmg z0.h, p0/m, z0.h, z31.h
+// CHECK-INST: fminmg z0.h, p0/m, z0.h, z31.h
+// CHECK-ENCODING: encoding: [0xe0,0xe3,0x4b,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 644be3e0 <unknown>
+
+// FMAXMGINM (predicated vectors)
+
+fmaxmginm z0.h, p0/m, z0.h, z0.h
+// CHECK-INST: fmaxmginm z0.h, p0/m, z0.h, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x48,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6448e000 <unknown>
+
+fmaxmginm z31.h, p7/m, z31.h, z31.h
+// CHECK-INST: fmaxmginm z31.h, p7/m, z31.h, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x48,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6448ffff <unknown>
+
+fmaxmginm z0.s, p0/m, z0.s, z0.s
+// CHECK-INST: fmaxmginm z0.s, p0/m, z0.s, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x88,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6488e000 <unknown>
+
+fmaxmginm z31.s, p7/m, z31.s, z31.s
+// CHECK-INST: fmaxmginm z31.s, p7/m, z31.s, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x88,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6488ffff <unknown>
+
+fmaxmginm z0.d, p0/m, z0.d, z0.d
+// CHECK-INST: fmaxmginm z0.d, p0/m, z0.d, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xc8,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64c8e000 <unknown>
+
+fmaxmginm z31.d, p7/m, z31.d, z31.d
+// CHECK-INST: fmaxmginm z31.d, p7/m, z31.d, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xc8,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64c8ffff <unknown>
+
+movprfx z0.h, p0/m, z27.h
+fmaxmginm z0.h, p0/m, z0.h, z31.h
+// CHECK-INST: fmaxmginm z0.h, p0/m, z0.h, z31.h
+// CHECK-ENCODING: encoding: [0xe0,0xe3,0x48,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6448e3e0 <unknown>
+
+// FMINMGINM (predicated vectors)
+
+fminmginm z0.h, p0/m, z0.h, z0.h
+// CHECK-INST: fminmginm z0.h, p0/m, z0.h, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x49,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6449e000 <unknown>
+
+fminmginm z31.h, p7/m, z31.h, z31.h
+// CHECK-INST: fminmginm z31.h, p7/m, z31.h, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x49,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6449ffff <unknown>
+
+fminmginm z0.s, p0/m, z0.s, z0.s
+// CHECK-INST: fminmginm z0.s, p0/m, z0.s, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x89,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6489e000 <unknown>
+
+fminmginm z31.s, p7/m, z31.s, z31.s
+// CHECK-INST: fminmginm z31.s, p7/m, z31.s, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x89,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6489ffff <unknown>
+
+fminmginm z0.d, p0/m, z0.d, z0.d
+// CHECK-INST: fminmginm z0.d, p0/m, z0.d, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xc9,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64c9e000 <unknown>
+
+fminmginm z31.d, p7/m, z31.d, z31.d
+// CHECK-INST: fminmginm z31.d, p7/m, z31.d, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xc9,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64c9ffff <unknown>
+
+movprfx z0.h, p0/m, z27.h
+fminmginm z0.h, p0/m, z0.h, z31.h
+// CHECK-INST: fminmginm z0.h, p0/m, z0.h, z31.h
+// CHECK-ENCODING: encoding: [0xe0,0xe3,0x49,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6449e3e0 <unknown>
+
+// FMAXINMV (reductions)
+
+fmaxinmv h0, p0, z0.h
+// CHECK-INST: fmaxinmv h0, p0, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xc0,0x54,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6454c000 <unknown>
+
+fmaxinmv h31, p7, z31.h
+// CHECK-INST: fmaxinmv h31, p7, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xdf,0x54,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6454dfff <unknown>
+
+fmaxinmv s0, p0, z0.s
+// CHECK-INST: fmaxinmv s0, p0, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xc0,0x94,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6494c000 <unknown>
+
+fmaxinmv s31, p7, z31.s
+// CHECK-INST: fmaxinmv s31, p7, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xdf,0x94,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6494dfff <unknown>
+
+fmaxinmv d0, p0, z0.d
+// CHECK-INST: fmaxinmv d0, p0, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xc0,0xd4,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d4c000 <unknown>
+
+fmaxinmv d31, p7, z31.d
+// CHECK-INST: fmaxinmv d31, p7, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xdf,0xd4,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d4dfff <unknown>
+
+// FMININMV (reductions)
+
+fmininmv h0, p0, z0.h
+// CHECK-INST: fmininmv h0, p0, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xc0,0x55,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6455c000 <unknown>
+
+fmininmv h31, p7, z31.h
+// CHECK-INST: fmininmv h31, p7, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xdf,0x55,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6455dfff <unknown>
+
+fmininmv s0, p0, z0.s
+// CHECK-INST: fmininmv s0, p0, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xc0,0x95,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6495c000 <unknown>
+
+fmininmv s31, p7, z31.s
+// CHECK-INST: fmininmv s31, p7, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xdf,0x95,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6495dfff <unknown>
+
+fmininmv d0, p0, z0.d
+// CHECK-INST: fmininmv d0, p0, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xc0,0xd5,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d5c000 <unknown>
+
+fmininmv d31, p7, z31.d
+// CHECK-INST: fmininmv d31, p7, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xdf,0xd5,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d5dfff <unknown>
+
+// FMAXMGV (reductions)
+
+fmaxmgv h0, p0, z0.h
+// CHECK-INST: fmaxmgv h0, p0, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x56,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6456e000 <unknown>
+
+fmaxmgv h31, p7, z31.h
+// CHECK-INST: fmaxmgv h31, p7, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x56,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6456ffff <unknown>
+
+fmaxmgv s0, p0, z0.s
+// CHECK-INST: fmaxmgv s0, p0, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x96,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6496e000 <unknown>
+
+fmaxmgv s31, p7, z31.s
+// CHECK-INST: fmaxmgv s31, p7, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x96,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6496ffff <unknown>
+
+fmaxmgv d0, p0, z0.d
+// CHECK-INST: fmaxmgv d0, p0, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xd6,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d6e000 <unknown>
+
+fmaxmgv d31, p7, z31.d
+// CHECK-INST: fmaxmgv d31, p7, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xd6,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d6ffff <unknown>
+
+// FMINMGV (reductions)
+
+fminmgv h0, p0, z0.h
+// CHECK-INST: fminmgv h0, p0, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x57,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6457e000 <unknown>
+
+fminmgv h31, p7, z31.h
+// CHECK-INST: fminmgv h31, p7, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x57,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6457ffff <unknown>
+
+fminmgv s0, p0, z0.s
+// CHECK-INST: fminmgv s0, p0, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x97,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6497e000 <unknown>
+
+fminmgv s31, p7, z31.s
+// CHECK-INST: fminmgv s31, p7, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x97,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6497ffff <unknown>
+
+fminmgv d0, p0, z0.d
+// CHECK-INST: fminmgv d0, p0, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xd7,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d7e000 <unknown>
+
+fminmgv d31, p7, z31.d
+// CHECK-INST: fminmgv d31, p7, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xd7,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d7ffff <unknown>
+
+// FMAXMGINMV (reductions)
+
+fmaxmginmv h0, p0, z0.h
+// CHECK-INST: fmaxmginmv h0, p0, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x54,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6454e000 <unknown>
+
+fmaxmginmv h31, p7, z31.h
+// CHECK-INST: fmaxmginmv h31, p7, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x54,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6454ffff <unknown>
+
+fmaxmginmv s0, p0, z0.s
+// CHECK-INST: fmaxmginmv s0, p0, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x94,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6494e000 <unknown>
+
+fmaxmginmv s31, p7, z31.s
+// CHECK-INST: fmaxmginmv s31, p7, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x94,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6494ffff <unknown>
+
+fmaxmginmv d0, p0, z0.d
+// CHECK-INST: fmaxmginmv d0, p0, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xd4,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d4e000 <unknown>
+
+fmaxmginmv d31, p7, z31.d
+// CHECK-INST: fmaxmginmv d31, p7, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xd4,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d4ffff <unknown>
+
+// FMINMGINMV (reductions)
+
+fminmginmv h0, p0, z0.h
+// CHECK-INST: fminmginmv h0, p0, z0.h
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x55,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6455e000 <unknown>
+
+fminmginmv h31, p7, z31.h
+// CHECK-INST: fminmginmv h31, p7, z31.h
+// CHECK-ENCODING: encoding: [0xff,0xff,0x55,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6455ffff <unknown>
+
+fminmginmv s0, p0, z0.s
+// CHECK-INST: fminmginmv s0, p0, z0.s
+// CHECK-ENCODING: encoding: [0x00,0xe0,0x95,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6495e000 <unknown>
+
+fminmginmv s31, p7, z31.s
+// CHECK-INST: fminmginmv s31, p7, z31.s
+// CHECK-ENCODING: encoding: [0xff,0xff,0x95,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 6495ffff <unknown>
+
+fminmginmv d0, p0, z0.d
+// CHECK-INST: fminmginmv d0, p0, z0.d
+// CHECK-ENCODING: encoding: [0x00,0xe0,0xd5,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d5e000 <unknown>
+
+fminmginmv d31, p7, z31.d
+// CHECK-INST: fminmginmv d31, p7, z31.d
+// CHECK-ENCODING: encoding: [0xff,0xff,0xd5,0x64]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 64d5ffff <unknown>
diff --git a/llvm/test/MC/AArch64/SVE2p3/total-compare.s b/llvm/test/MC/AArch64/SVE2p3/total-compare.s
new file mode 100644
index 0000000000000..f14e7df84c80b
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p3/total-compare.s
@@ -0,0 +1,51 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3,+fpv2 < %s \
+// RUN: | FileCheck %s --ignore-case --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p3,+fpv2 < %s \
+// RUN: | FileCheck %s --ignore-case --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --ignore-case --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p3,+fpv2 < %s \
+// RUN: | llvm-objdump -d --mattr=+sve2p3,+fpv2 --no-print-imm-hex - | FileCheck %s --ignore-case --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p3,+fpv2 < %s \
+// RUN: | llvm-objdump -d --mattr=+sve2p3,-fpv2 --no-print-imm-hex - | FileCheck %s --ignore-case --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3,+fpv2 < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p3,+fpv2 -disassemble -show-encoding \
+// RUN: | FileCheck %s --ignore-case --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+fcmtl p15.h, z31.h, z31.h
+// CHECK-INST: fcmtl p15.h, z31.h, z31.h
+// CHECK-ENCODING: encoding: [0xef,0x13,0x5f,0x65]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 655f13ef <unknown>
+
+fcmtl p15.s, z31.s, z31.s
+// CHECK-INST: fcmtl p15.s, z31.s, z31.s
+// CHECK-ENCODING: encoding: [0xef,0x13,0x9f,0x65]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 659f13ef <unknown>
+
+fcmtl p15.d, z31.d, z31.d
+// CHECK-INST: fcmtl p15.d, z31.d, z31.d
+// CHECK-ENCODING: encoding: [0xef,0x13,0xdf,0x65]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 65df13ef <unknown>
+
+fcmtlmg p15.h, z31.h, z31.h
+// CHECK-INST: fcmtlmg p15.h, z31.h, z31.h
+// CHECK-ENCODING: encoding: [0xef,0x17,0x5f,0x65]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 655f17ef <unknown>
+
+fcmtlmg p15.s, z31.s, z31.s
+// CHECK-INST: fcmtlmg p15.s, z31.s, z31.s
+// CHECK-ENCODING: encoding: [0xef,0x17,0x9f,0x65]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 659f17ef <unknown>
+
+fcmtlmg p15.d, z31.d, z31.d
+// CHECK-INST: fcmtlmg p15.d, z31.d, z31.d
+// CHECK-ENCODING: encoding: [0xef,0x17,0xdf,0x65]
+// CHECK-ERROR: instruction requires: fpv2 sme2p3 or sve2p3
+// CHECK-UNKNOWN: 65df17ef <unknown>
diff --git a/llvm/test/MC/AArch64/basic-a64-diagnostics.s b/llvm/test/MC/AArch64/basic-a64-diagnostics.s
index 823a37dc54f2c..5cd8c75d90156 100644
--- a/llvm/test/MC/AArch64/basic-a64-diagnostics.s
+++ b/llvm/test/MC/AArch64/basic-a64-diagnostics.s
@@ -1575,6 +1575,43 @@ cbz w1, lsl
// CHECK-ERROR-NEXT: fcmpe s30, #-0.0
// CHECK-ERROR-NEXT: ^
+//------------------------------------------------------------------------------
+// Floating-point total-order compare
+//------------------------------------------------------------------------------
+
+ fcmtl h0, s1
+ fcmtl s0, d1
+ fcmtl d0, h1
+ fcmtl b0, b1
+ fcmtlmg h0, s1
+ fcmtlmg s0, d1
+ fcmtlmg d0, h1
+ fcmtlmg b0, b1
+// CHECK-ERROR: error: invalid operand for instruction
+// CHECK-ERROR-NEXT: fcmtl h0, s1
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: invalid operand for instruction
+// CHECK-ERROR-NEXT: fcmtl s0, d1
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: invalid operand for instruction
+// CHECK-ERROR-NEXT: fcmtl d0, h1
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: invalid operand for instruction
+// CHECK-ERROR-NEXT: fcmtl b0, b1
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: invalid operand for instruction
+// CHECK-ERROR-NEXT: fcmtlmg h0, s1
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: invalid operand for instruction
+// CHECK-ERROR-NEXT: fcmtlmg s0, d1
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: invalid operand for instruction
+// CHECK-ERROR-NEXT: fcmtlmg d0, h1
+// CHECK-ERROR-NEXT: ^
+// CHECK-ERROR-NEXT: error: invalid operand for instruction
+// CHECK-ERROR-NEXT: fcmtlmg b0, b1
+// CHECK-ERROR-NEXT: ^
+
//------------------------------------------------------------------------------
// Floating-point conditional compare
//------------------------------------------------------------------------------
diff --git a/llvm/test/MC/AArch64/directive-arch-negative.s b/llvm/test/MC/AArch64/directive-arch-negative.s
index 28dfb4017fed4..3154e24dd734e 100644
--- a/llvm/test/MC/AArch64/directive-arch-negative.s
+++ b/llvm/test/MC/AArch64/directive-arch-negative.s
@@ -91,3 +91,9 @@
# CHECK: [[@LINE-2]]:9: error: instruction requires: ls64 lsc64b
# CHECK-NEXT: lda64b x0, [x13]
+
+ .arch armv9-a+fpv2
+ .arch armv9-a+nofpv2
+ fcmtl s31, s0
+# CHECK: error: instruction requires: fpv2
+# CHECK-NEXT: fcmtl s31, s0
diff --git a/llvm/test/MC/AArch64/directive-arch.s b/llvm/test/MC/AArch64/directive-arch.s
index 1af5f1c04e867..42e428c4562e9 100644
--- a/llvm/test/MC/AArch64/directive-arch.s
+++ b/llvm/test/MC/AArch64/directive-arch.s
@@ -46,3 +46,7 @@
.arch armv9-a+ls64+lsc64b
lda64b x0, [x13]
# CHECK: lda64b x0, [x13]
+
+ .arch armv9-a+fpv2
+ fcmtl s31, s0
+# CHECK: fcmtl s31, s0
diff --git a/llvm/test/MC/AArch64/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/directive-arch_extension-negative.s
index 7f4991afe8448..e34c34c7f1358 100644
--- a/llvm/test/MC/AArch64/directive-arch_extension-negative.s
+++ b/llvm/test/MC/AArch64/directive-arch_extension-negative.s
@@ -262,3 +262,9 @@ cfltz #1, w0
lda64b x0, [x13]
// CHECK: [[@LINE-1]]:1: error: instruction requires: ls64 lsc64b
// CHECK-NEXT: lda64b x0, [x13]
+
+.arch_extension fpv2
+.arch_extension nofpv2
+fcmtl s31, s0
+// CHECK: [[@LINE-1]]:1: error: instruction requires: fpv2
+// CHECK-NEXT: fcmtl s31, s0
diff --git a/llvm/test/MC/AArch64/directive-arch_extension.s b/llvm/test/MC/AArch64/directive-arch_extension.s
index bd6a3924e7470..40d1de6e25eab 100644
--- a/llvm/test/MC/AArch64/directive-arch_extension.s
+++ b/llvm/test/MC/AArch64/directive-arch_extension.s
@@ -236,3 +236,7 @@ bti c
.arch_extension cflt
cfltz #1, w0
// CHECK: cflteq #1, w0, #0
+
+.arch_extension fpv2
+fcmtl s31, s0
+// CHECK: fcmtl s31, s0
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 92cff20816353..33631845ecc6d 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -1510,7 +1510,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
AArch64::AEK_MTETC, AArch64::AEK_HINTE,
AArch64::AEK_CFLT, AArch64::AEK_LSC64B,
AArch64::AEK_SVE_LRCPC, AArch64::AEK_SVE_PERM256,
- AArch64::AEK_SME_F16F8F16,
+ AArch64::AEK_SME_F16F8F16, AArch64::AEK_FPV2,
};
std::vector<StringRef> Features;
@@ -1640,6 +1640,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
EXPECT_TRUE(llvm::is_contained(Features, "+sve-lrcpc"));
EXPECT_TRUE(llvm::is_contained(Features, "+sve-perm256"));
EXPECT_TRUE(llvm::is_contained(Features, "+sme-f16f8f16"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+fpv2"));
// Assuming we listed every extension above, this should produce the same
// result.
@@ -1826,6 +1827,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
{"sve-lrcpc", "nosve-lrcpc", "+sve-lrcpc", "-sve-lrcpc"},
{"sve-perm256", "nosve-perm256", "+sve-perm256", "-sve-perm256"},
{"sme-f16f8f16", "nosme-f16f8f16", "+sme-f16f8f16", "-sme-f16f8f16"},
+ {"fpv2", "nofpv2", "+fpv2", "-fpv2"},
};
for (unsigned i = 0; i < std::size(ArchExt); i++) {
@@ -2295,6 +2297,9 @@ AArch64ExtensionDependenciesBaseArchTestParams
{AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}},
{AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}},
+ // fp16 -> fpv2
+ {AArch64::ARMV8A, {"nofp16", "fpv2"}, {"fullfp16", "fpv2"}, {}},
+
// mtetc -> mte
{AArch64::ARMV9_7A, {"nomemtag", "mtetc"}, {"mte"}, {}},
More information about the llvm-branch-commits
mailing list