[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
Wed Oct 14 03:44:53 PDT 2026


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

>From 1b981a1299d00b019e713c4213bc469496c41026 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 1/2] [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 64aabd3cc8c3d1..d61db5bca6d7d4 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 ff569373f2c93e..28fd54ea2c1753 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 4a5d056c906669..5171dadc73ca26 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 3df66fa00fc282..297023ce9449f5 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 57ce1060317f67..255e62df30eb77 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 HasSMEF16F8F16   : Predicate<"Subtarget->isStreaming() && Subtarget->hasSMEF16F8F16()">,
                                  AssemblerPredicateWithAll<(all_of FeatureSMEF16F8F16), "sme-f16f8f16">;
+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 e5332dab0080e8..f12fdbefe5d22d 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 291f78582d94a0..dbc1edc06da197 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 9260379fb5b270..e4a473ce2a80ad 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 8ecfa612af63e3..7f4ed347b89edc 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 269f4ec5e5fb16..d013bc559a305b 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 d77c48126af396..347f0e2444c402 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 7929ede8d099b3..4f5616917742db 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 3644617928dc21..12eaf12e6d28cc 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 e72d91101582ab..5c8ea5788442a1 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 35a787bdd8fc7e..ef8a1afa50bf89 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 778a2621618a70..9d430da4c1c57d 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 06a139bebcbe87..ade92141d0621d 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 eec8f37906fd4c..f4e17f66609f50 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 8847f32a9da9ad..bd3389d215070e 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 60eaf069ca3e1a..b503dce891aec8 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 0e0fcc554f753b..bf407784c5682e 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 eb9f8f8c04bff2..4bd21739dc262a 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 1e16cfbef8bd06..177978b16c5481 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 4fbaba8aa6c73b..c7789c1db2500f 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 3fcef7d7cc31a1..39d545ef284bd0 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 39cda0de137508..c80f56f9526788 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 e113bf45252742..0a44a29d04d666 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 2915b69de47efa..7382250526fea3 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 e9f2d7618e1997..a45308851196b8 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 5d2adb938d6874..1d3a77c282c54b 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 80f37d306a48aa..4cb1d7a8a79f75 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 fc93c92408bbe4..0c3edd63eb0d2f 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-rcpc"}, {AArch64::FeatureSVE_RCPC}},
     {{"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 2ebae0a431f93f..79d85f820fa2f7 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 00000000000000..ebbba316737f4a
--- /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 00000000000000..d6b864453cee0d
--- /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 00000000000000..8ad9bc46b0bcfb
--- /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 0a12cf85cb007d..c35ac3f57c55be 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 00000000000000..aa28f241516b3d
--- /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 1af6245abe16d8..da38d90470a275 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 00000000000000..d976a508d37131
--- /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 00000000000000..20f3302ba90197
--- /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 00000000000000..b189506ceb0b04
--- /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 00000000000000..a64d80b4c7a378
--- /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 00000000000000..f14e7df84c80b7
--- /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 823a37dc54f2c9..5cd8c75d90156d 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 28dfb4017fed4e..3154e24dd734e7 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 1af5f1c04e867e..42e428c4562e91 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 7f4991afe84486..e34c34c7f13580 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 bd6a3924e7470e..40d1de6e25eab2 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 40835817040fa3..e1bd306009a1be 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_RCPC,     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-rcpc"));
   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-rcpc", "nosve-rcpc", "+sve-rcpc", "-sve-rcpc"},
       {"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++) {
@@ -2289,6 +2291,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"}, {}},
 

>From 8f8f32bca3635dca09d93927cae79d9ad7a6b881 Mon Sep 17 00:00:00 2001
From: Martin Wehking <martin.wehking at arm.com>
Date: Wed, 14 Oct 2026 10:39:26 +0000
Subject: [PATCH 2/2] fixup! Remove TwoOperandFPDataFPv2 multiclass

The multiclass can just be replaced with TwoOperandFPData
---
 llvm/lib/Target/AArch64/AArch64InstrFormats.td | 14 --------------
 llvm/lib/Target/AArch64/AArch64InstrInfo.td    | 12 ++++++------
 2 files changed, 6 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 297023ce9449f5..e480b94017a03f 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -5980,20 +5980,6 @@ 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,
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 255e62df30eb77..420979e4cd6152 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -5969,12 +5969,12 @@ 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">;
+defm FMAXINM   : TwoOperandFPData<0b1010, "fmaxinm">;
+defm FMAXMG    : TwoOperandFPData<0b1100, "fmaxmg">;
+defm FMAXMGINM : TwoOperandFPData<0b1110, "fmaxmginm">;
+defm FMININM   : TwoOperandFPData<0b1011, "fmininm">;
+defm FMINMG    : TwoOperandFPData<0b1101, "fminmg">;
+defm FMINMGINM : TwoOperandFPData<0b1111, "fminmginm">;
 }
 
 multiclass FMULScalarFromIndexedLane0Patterns<string inst,



More information about the llvm-branch-commits mailing list