[llvm] 891aaff - [AArch64][SVE2] Add the SVE2.1 pext and ptrue predicate-as-counter instructions

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 27 11:23:41 PDT 2022


Author: David Sherwood
Date: 2022-10-27T18:23:35Z
New Revision: 891aaff9a8a9997582eac1bb1edb8d4b4e117ef1

URL: https://github.com/llvm/llvm-project/commit/891aaff9a8a9997582eac1bb1edb8d4b4e117ef1
DIFF: https://github.com/llvm/llvm-project/commit/891aaff9a8a9997582eac1bb1edb8d4b4e117ef1.diff

LOG: [AArch64][SVE2] Add the SVE2.1 pext and ptrue predicate-as-counter instructions

This patch adds the assembly/disassembly for the following instructions:

pext (predicate) : Set predicate from predicate-as-counter
ptrue (predicate-as-counter) : Initialise predicate-as-counter to all active

This patch also introduces the predicate-as-counter registers pn8, etc.

The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2022-09

Differential Revision: https://reviews.llvm.org/D136678

Added: 
    llvm/test/MC/AArch64/SVE2p1/pext-diagnostics.s
    llvm/test/MC/AArch64/SVE2p1/pext.s
    llvm/test/MC/AArch64/SVE2p1/ptrue-diagnostics.s
    llvm/test/MC/AArch64/SVE2p1/ptrue.s

Modified: 
    llvm/lib/Target/AArch64/AArch64RegisterInfo.td
    llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
    llvm/lib/Target/AArch64/SVEInstrFormats.td
    llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
    llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll
    llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index cd2cc308a5e4d..8a79f10a0f4f9 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -871,15 +871,16 @@ class ZPRRegOp <string Suffix, AsmOperandClass C, ElementSizeEnum Size,
 //******************************************************************************
 
 // SVE predicate register classes.
-class PPRClass<int lastreg> : RegisterClass<
+class PPRClass<int firstreg, int lastreg> : RegisterClass<
                                   "AArch64",
                                   [ nxv16i1, nxv8i1, nxv4i1, nxv2i1, nxv1i1 ], 16,
-                                  (sequence "P%u", 0, lastreg)> {
+                                  (sequence "P%u", firstreg, lastreg)> {
   let Size = 16;
 }
 
-def PPR    : PPRClass<15>;
-def PPR_3b : PPRClass<7>; // Restricted 3 bit SVE predicate register class.
+def PPR    : PPRClass<0, 15>;
+def PPR_3b : PPRClass<0, 7>; // Restricted 3 bit SVE predicate register class.
+def PPR_p8to15 : PPRClass<8, 15>;
 
 class PPRAsmOperand <string name, string RegClass, int Width>: AsmOperandClass {
   let Name = "SVE" # name # "Reg";
@@ -906,6 +907,38 @@ def PPRAsmOp3bAny : PPRAsmOperand<"Predicate3bAny", "PPR_3b",  0>;
 
 def PPR3bAny : PPRRegOp<"",  PPRAsmOp3bAny, ElementSizeNone, PPR_3b>;
 
+
+// SVE predicate-as-counter operand
+class PNRAsmOperand<string name, string RegClass, int Width>
+    : PPRAsmOperand<name, RegClass, Width> {
+  let PredicateMethod = "isSVEPredicateAsCounterRegOfWidth<"
+                            # Width # ", " # "AArch64::"
+                            # RegClass # "RegClassID>";
+  let DiagnosticType = "InvalidSVE" # name # "Reg";
+  let ParserMethod   = "tryParseSVEPredicateAsCounter";
+}
+
+class PNRP8to15RegOp<string Suffix, AsmOperandClass C, int EltSize, RegisterClass RC>
+    : PPRRegOp<Suffix, C, ElementSizeNone, RC> {
+  let PrintMethod   = "printPredicateAsCounter<" # EltSize # ">";
+  let EncoderMethod = "EncodePPR_p8to15";
+  let DecoderMethod = "DecodePPR_p8to15RegisterClass";
+}
+
+def PNRAsmAny_p8to15  : PNRAsmOperand<"PNPredicateAny_p8to15", "PPR_p8to15", 0>;
+def PNRAsmOp8_p8to15  : PNRAsmOperand<"PNPredicateB_p8to15",   "PPR_p8to15", 8>;
+def PNRAsmOp16_p8to15 : PNRAsmOperand<"PNPredicateH_p8to15",   "PPR_p8to15", 16>;
+def PNRAsmOp32_p8to15 : PNRAsmOperand<"PNPredicateS_p8to15",   "PPR_p8to15", 32>;
+def PNRAsmOp64_p8to15 : PNRAsmOperand<"PNPredicateD_p8to15",   "PPR_p8to15", 64>;
+
+def PNRAny_p8to15 : PNRP8to15RegOp<"",  PNRAsmAny_p8to15,  0,  PPR_p8to15>;
+def PNR8_p8to15   : PNRP8to15RegOp<"b", PNRAsmOp8_p8to15,  8,  PPR_p8to15>;
+def PNR16_p8to15  : PNRP8to15RegOp<"h", PNRAsmOp16_p8to15, 16, PPR_p8to15>;
+def PNR32_p8to15  : PNRP8to15RegOp<"s", PNRAsmOp32_p8to15, 32, PPR_p8to15>;
+def PNR64_p8to15  : PNRP8to15RegOp<"d", PNRAsmOp64_p8to15, 64, PPR_p8to15>;
+
+
+
 //******************************************************************************
 
 // SVE vector register classes

diff  --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 40208188b0339..54be2d504ce3f 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -3586,4 +3586,7 @@ def SDOT_ZZZ_HtoS  : sve2p1_two_way_dot_vv<"sdot", 0b0>;
 def UDOT_ZZZ_HtoS  : sve2p1_two_way_dot_vv<"udot", 0b1>;
 def SDOT_ZZZI_HtoS : sve2p1_two_way_dot_vvi<"sdot", 0b0>;
 def UDOT_ZZZI_HtoS : sve2p1_two_way_dot_vvi<"udot", 0b1>;
+
+defm PEXT_PCI : sve2p1_pred_as_ctr_to_mask<"pext">;
+defm PTRUE_C  : sve2p1_ptrue_pn<"ptrue">;
 } // End HasSVE2p1_or_HasSME2

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 84f0f79e5a92b..bf838f2d2128e 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -1,3 +1,4 @@
+
 //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -68,6 +69,7 @@ enum class RegKind {
   Scalar,
   NeonVector,
   SVEDataVector,
+  SVEPredicateAsCounter,
   SVEPredicateVector,
   Matrix
 };
@@ -266,6 +268,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
   template <bool ParseShiftExtend, bool ParseSuffix>
   OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands);
   OperandMatchResultTy tryParseSVEPredicateVector(OperandVector &Operands);
+  OperandMatchResultTy tryParseSVEPredicateAsCounter(OperandVector &Operands);
   template <RegKind VectorKind>
   OperandMatchResultTy tryParseVectorList(OperandVector &Operands,
                                           bool ExpectMatch = false);
@@ -1198,6 +1201,22 @@ class AArch64Operand : public MCParsedAsmOperand {
   bool isMatrix() const { return Kind == k_MatrixRegister; }
   bool isMatrixTileList() const { return Kind == k_MatrixTileList; }
 
+  template <unsigned Class> bool isSVEPredicateAsCounterReg() const {
+    RegKind RK;
+    switch (Class) {
+    case AArch64::PPRRegClassID:
+    case AArch64::PPR_3bRegClassID:
+    case AArch64::PPR_p8to15RegClassID:
+      RK = RegKind::SVEPredicateAsCounter;
+      break;
+    default:
+      llvm_unreachable("Unsupport register class");
+    }
+
+    return (Kind == k_Register && Reg.Kind == RK) &&
+           AArch64MCRegisterClasses[Class].contains(getReg());
+  }
+
   template <unsigned Class> bool isSVEVectorReg() const {
     RegKind RK;
     switch (Class) {
@@ -1234,6 +1253,17 @@ class AArch64Operand : public MCParsedAsmOperand {
     return DiagnosticPredicateTy::NearMatch;
   }
 
+  template <int ElementWidth, unsigned Class>
+  DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth() const {
+    if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateAsCounter)
+      return DiagnosticPredicateTy::NoMatch;
+
+    if (isSVEPredicateAsCounterReg<Class>() && (Reg.ElementWidth == ElementWidth))
+      return DiagnosticPredicateTy::Match;
+
+    return DiagnosticPredicateTy::NearMatch;
+  }
+
   template <int ElementWidth, unsigned Class>
   DiagnosticPredicate isSVEDataVectorRegOfWidth() const {
     if (Kind != k_Register || Reg.Kind != RegKind::SVEDataVector)
@@ -2059,7 +2089,8 @@ class AArch64Operand : public MCParsedAsmOperand {
                   unsigned ShiftAmount = 0,
                   unsigned HasExplicitAmount = false) {
     assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
-            Kind == RegKind::SVEPredicateVector) &&
+            Kind == RegKind::SVEPredicateVector ||
+            Kind == RegKind::SVEPredicateAsCounter) &&
            "Invalid vector kind");
     auto Op = CreateReg(RegNum, Kind, S, E, Ctx, EqualsReg, ExtTy, ShiftAmount,
                         HasExplicitAmount);
@@ -2478,6 +2509,7 @@ static Optional<std::pair<int, int>> parseVectorKind(StringRef Suffix,
             .Case(".d", {0, 64})
             .Default({-1, -1});
     break;
+  case RegKind::SVEPredicateAsCounter:
   case RegKind::SVEPredicateVector:
   case RegKind::SVEDataVector:
   case RegKind::Matrix:
@@ -2562,6 +2594,27 @@ static unsigned matchSVEPredicateVectorRegName(StringRef Name) {
       .Default(0);
 }
 
+static unsigned matchSVEPredicateAsCounterRegName(StringRef Name) {
+  return StringSwitch<unsigned>(Name.lower())
+      .Case("pn0", AArch64::P0)
+      .Case("pn1", AArch64::P1)
+      .Case("pn2", AArch64::P2)
+      .Case("pn3", AArch64::P3)
+      .Case("pn4", AArch64::P4)
+      .Case("pn5", AArch64::P5)
+      .Case("pn6", AArch64::P6)
+      .Case("pn7", AArch64::P7)
+      .Case("pn8", AArch64::P8)
+      .Case("pn9", AArch64::P9)
+      .Case("pn10", AArch64::P10)
+      .Case("pn11", AArch64::P11)
+      .Case("pn12", AArch64::P12)
+      .Case("pn13", AArch64::P13)
+      .Case("pn14", AArch64::P14)
+      .Case("pn15", AArch64::P15)
+      .Default(0);
+}
+
 static unsigned matchMatrixTileListRegName(StringRef Name) {
   return StringSwitch<unsigned>(Name.lower())
       .Case("za0.d", AArch64::ZAD0)
@@ -2705,6 +2758,9 @@ unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
   if ((RegNum = matchSVEPredicateVectorRegName(Name)))
     return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
 
+  if ((RegNum = matchSVEPredicateAsCounterRegName(Name)))
+    return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
+
   if ((RegNum = MatchNeonVectorRegName(Name)))
     return Kind == RegKind::NeonVector ? RegNum : 0;
 
@@ -3803,6 +3859,32 @@ AArch64AsmParser::tryParseVectorRegister(unsigned &Reg, StringRef &Kind,
   return MatchOperand_NoMatch;
 }
 
+OperandMatchResultTy
+AArch64AsmParser::tryParseSVEPredicateAsCounter(OperandVector &Operands) {
+  const SMLoc S = getLoc();
+  StringRef Kind;
+  unsigned RegNum;
+  auto Res =
+      tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateAsCounter);
+  if (Res != MatchOperand_Success)
+    return Res;
+
+  const auto &KindRes = parseVectorKind(Kind, RegKind::SVEPredicateAsCounter);
+  if (!KindRes)
+    return MatchOperand_NoMatch;
+
+  unsigned ElementWidth = KindRes->second;
+  Operands.push_back(
+      AArch64Operand::CreateVectorReg(RegNum, RegKind::SVEPredicateAsCounter,
+                                      ElementWidth, S, getLoc(), getContext()));
+
+  // Check if register is followed by an index
+  OperandMatchResultTy ResIndex = tryParseVectorIndex(Operands);
+  if (ResIndex == MatchOperand_ParseFail)
+    return ResIndex;
+
+  return MatchOperand_Success;
+}
 /// tryParseSVEPredicateVector - Parse a SVE predicate register operand.
 OperandMatchResultTy
 AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) {
@@ -5573,6 +5655,15 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
     return Error(Loc, "invalid predicate register.");
   case Match_InvalidSVEPredicate3bAnyReg:
     return Error(Loc, "invalid restricted predicate register, expected p0..p7 (without element suffix)");
+  case Match_InvalidSVEPNPredicateB_p8to15Reg:
+  case Match_InvalidSVEPNPredicateH_p8to15Reg:
+  case Match_InvalidSVEPNPredicateS_p8to15Reg:
+  case Match_InvalidSVEPNPredicateD_p8to15Reg:
+    return Error(Loc, "Invalid predicate register, expected PN in range "
+                      "pn8..pn15 with element suffix.");
+  case Match_InvalidSVEPNPredicateAny_p8to15Reg:
+    return Error(Loc, "invalid restricted predicate-as-counter register "
+                      "expected pn8..pn15");
   case Match_InvalidSVEExactFPImmOperandHalfOne:
     return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0.");
   case Match_InvalidSVEExactFPImmOperandHalfTwo:
@@ -6145,6 +6236,11 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidSVEPredicateSReg:
   case Match_InvalidSVEPredicateDReg:
   case Match_InvalidSVEPredicate3bAnyReg:
+  case Match_InvalidSVEPNPredicateB_p8to15Reg:
+  case Match_InvalidSVEPNPredicateH_p8to15Reg:
+  case Match_InvalidSVEPNPredicateS_p8to15Reg:
+  case Match_InvalidSVEPNPredicateD_p8to15Reg:
+  case Match_InvalidSVEPNPredicateAny_p8to15Reg:
   case Match_InvalidSVEExactFPImmOperandHalfOne:
   case Match_InvalidSVEExactFPImmOperandHalfTwo:
   case Match_InvalidSVEExactFPImmOperandZeroOne:

diff  --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index 42f614c2b5546..951f24998084b 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -137,6 +137,9 @@ static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
 static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);
+static DecodeStatus
+DecodePPR_p8to15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
+                              const MCDisassembler *Decoder);
 
 static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
                                                uint64_t Address,
@@ -709,6 +712,16 @@ static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
   return DecodePPRRegisterClass(Inst, RegNo, Addr, Decoder);
 }
 
+static DecodeStatus
+DecodePPR_p8to15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
+                              const MCDisassembler *Decoder) {
+  if (RegNo > 7)
+    return Fail;
+
+  // Just reuse the PPR decode table
+  return DecodePPRRegisterClass(Inst, RegNo + 8, Addr, Decoder);
+}
+
 static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
                                           uint64_t Addr,
                                           const MCDisassembler *Decoder) {

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 358acbaf40f63..a88d6de1e0d3d 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1193,6 +1193,35 @@ void AArch64InstPrinter::printRegWithShiftExtend(const MCInst *MI,
   }
 }
 
+template <int EltSize>
+void AArch64InstPrinter::printPredicateAsCounter(const MCInst *MI,
+                                                 unsigned OpNum,
+                                                 const MCSubtargetInfo &STI,
+                                                 raw_ostream &O) {
+  unsigned Reg = MI->getOperand(OpNum).getReg();
+
+  assert(Reg <= AArch64::P15 && "Unsupported predicate register");
+  O << "pn" << (Reg - AArch64::P0);
+  switch (EltSize) {
+  case 0:
+    break;
+  case 8:
+    O << ".b";
+    break;
+  case 16:
+    O << ".h";
+    break;
+  case 32:
+    O << ".s";
+    break;
+  case 64:
+    O << ".d";
+    break;
+  default:
+    llvm_unreachable("Unsupported element size");
+  }
+}
+
 void AArch64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
index 1168c584ef070..ab58ac98f929e 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
@@ -182,6 +182,10 @@ class AArch64InstPrinter : public MCInstPrinter {
                               const MCSubtargetInfo &STI, raw_ostream &O);
   void printSIMDType10Operand(const MCInst *MI, unsigned OpNum,
                               const MCSubtargetInfo &STI, raw_ostream &O);
+  template <int EltSize>
+  void printPredicateAsCounter(const MCInst *MI, unsigned OpNum,
+                               const MCSubtargetInfo &STI, raw_ostream &O);
+
   template<int64_t Angle, int64_t Remainder>
   void printComplexRotationOp(const MCInst *MI, unsigned OpNo,
                             const MCSubtargetInfo &STI, raw_ostream &O);

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
index 228e244d934b6..c6ef362cf10fb 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
@@ -189,6 +189,9 @@ class AArch64MCCodeEmitter : public MCCodeEmitter {
   uint32_t EncodeRegAsMultipleOf(const MCInst &MI, unsigned OpIdx,
                                  SmallVectorImpl<MCFixup> &Fixups,
                                  const MCSubtargetInfo &STI) const;
+  uint32_t EncodePPR_p8to15(const MCInst &MI, unsigned OpIdx,
+                            SmallVectorImpl<MCFixup> &Fixups,
+                            const MCSubtargetInfo &STI) const;
 
   uint32_t EncodeMatrixTileListRegisterClass(const MCInst &MI, unsigned OpIdx,
                                              SmallVectorImpl<MCFixup> &Fixups,
@@ -533,6 +536,14 @@ AArch64MCCodeEmitter::EncodeRegAsMultipleOf(const MCInst &MI, unsigned OpIdx,
   return RegVal / Multiple;
 }
 
+uint32_t
+AArch64MCCodeEmitter::EncodePPR_p8to15(const MCInst &MI, unsigned OpIdx,
+                                       SmallVectorImpl<MCFixup> &Fixups,
+                                       const MCSubtargetInfo &STI) const {
+  auto RegOpnd = MI.getOperand(OpIdx).getReg();
+  return RegOpnd - AArch64::P8;
+}
+
 uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
     const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
     const MCSubtargetInfo &STI) const {

diff  --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 391ef42bd2d2b..44a4865c0b4e2 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -8695,3 +8695,47 @@ class sve2p1_two_way_dot_vvi<string mnemonic, bit u>
   let Constraints = "$Zda = $_Zda";
   let DestructiveInstType = DestructiveOther;
 }
+
+
+class sve2p1_ptrue_pn<string mnemonic, bits<2> sz, PNRP8to15RegOp pnrty>
+    : I<(outs pnrty:$PNd), (ins ), mnemonic, "\t$PNd",
+        "", []>, Sched<[]> {
+  bits<3> PNd;
+  let Inst{31-24}  = 0b00100101;
+  let Inst{23-22} = sz;
+  let Inst{21-3}  = 0b1000000111100000010;
+  let Inst{2-0}   = PNd;
+}
+
+
+multiclass sve2p1_ptrue_pn<string mnemonic> {
+ def _B : sve2p1_ptrue_pn<mnemonic, 0b00, PNR8_p8to15>;
+ def _H : sve2p1_ptrue_pn<mnemonic, 0b01, PNR16_p8to15>;
+ def _S : sve2p1_ptrue_pn<mnemonic, 0b10, PNR32_p8to15>;
+ def _D : sve2p1_ptrue_pn<mnemonic, 0b11, PNR64_p8to15>;
+}
+
+
+class sve2p1_pred_as_ctr_to_mask<string mnemonic, bits<2> sz, PPRRegOp pprty>
+    : I<(outs pprty:$Pd), (ins PNRAny_p8to15:$PNn, VectorIndexS:$imm2),
+        mnemonic, "\t$Pd, $PNn$imm2",
+        "", []>, Sched<[]> {
+  bits<4> Pd;
+  bits<3> PNn;
+  bits<2> imm2;
+  let Inst{31-24} = 0b00100101;
+  let Inst{23-22} = sz;
+  let Inst{21-10} = 0b100000011100;
+  let Inst{9-8}   = imm2;
+  let Inst{7-5}   = PNn;
+  let Inst{4}     = 0b1;
+  let Inst{3-0}   = Pd;
+}
+
+
+multiclass sve2p1_pred_as_ctr_to_mask<string mnemonic> {
+ def _B : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b00, PPR8>;
+ def _H : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b01, PPR16>;
+ def _S : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b10, PPR32>;
+ def _D : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b11, PPR64>;
+}

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
index 0f1432c354544..9c27dfca7df76 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
@@ -4,9 +4,9 @@
 define void @asm_simple_memory_clobber() {
   ; CHECK-LABEL: name: asm_simple_memory_clobber
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   INLINEASM &"", 25 /* sideeffect mayload maystore attdialect */, !0
-  ; CHECK:   INLINEASM &"", 1 /* sideeffect attdialect */, !0
-  ; CHECK:   RET_ReallyLR
+  ; CHECK-NEXT:   INLINEASM &"", 25 /* sideeffect mayload maystore attdialect */, !0
+  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, !0
+  ; CHECK-NEXT:   RET_ReallyLR
   call void asm sideeffect "", "~{memory}"(), !srcloc !0
   call void asm sideeffect "", ""(), !srcloc !0
   ret void
@@ -17,8 +17,8 @@ define void @asm_simple_memory_clobber() {
 define void @asm_simple_register_clobber() {
   ; CHECK-LABEL: name: asm_simple_register_clobber
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   INLINEASM &"mov x0, 7", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $x0, !0
-  ; CHECK:   RET_ReallyLR
+  ; CHECK-NEXT:   INLINEASM &"mov x0, 7", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $x0, !0
+  ; CHECK-NEXT:   RET_ReallyLR
   call void asm sideeffect "mov x0, 7", "~{x0}"(), !srcloc !0
   ret void
 }
@@ -26,12 +26,12 @@ define void @asm_simple_register_clobber() {
 define i64 @asm_register_early_clobber() {
   ; CHECK-LABEL: name: asm_register_early_clobber
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   INLINEASM &"mov $0, 7; mov $1, 7", 1 /* sideeffect attdialect */, 1703947 /* regdef-ec:GPR64common */, def early-clobber %0, 1703947 /* regdef-ec:GPR64common */, def early-clobber %1, !0
-  ; CHECK:   [[COPY:%[0-9]+]]:_(s64) = COPY %0
-  ; CHECK:   [[COPY1:%[0-9]+]]:_(s64) = COPY %1
-  ; CHECK:   [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]]
-  ; CHECK:   $x0 = COPY [[ADD]](s64)
-  ; CHECK:   RET_ReallyLR implicit $x0
+  ; CHECK-NEXT:   INLINEASM &"mov $0, 7; mov $1, 7", 1 /* sideeffect attdialect */, 1769483 /* regdef-ec:GPR64common */, def early-clobber %0, 1769483 /* regdef-ec:GPR64common */, def early-clobber %1, !0
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY %0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY %1
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   $x0 = COPY [[ADD]](s64)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $x0
   call { i64, i64 } asm sideeffect "mov $0, 7; mov $1, 7", "=&r,=&r"(), !srcloc !0
   %asmresult = extractvalue { i64, i64 } %1, 0
   %asmresult1 = extractvalue { i64, i64 } %1, 1
@@ -42,10 +42,10 @@ define i64 @asm_register_early_clobber() {
 define i32 @test_specific_register_output() nounwind ssp {
   ; CHECK-LABEL: name: test_specific_register_output
   ; CHECK: bb.1.entry:
-  ; CHECK:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 10 /* regdef */, implicit-def $w0
-  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $w0
-  ; CHECK:   $w0 = COPY [[COPY]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 10 /* regdef */, implicit-def $w0
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+  ; CHECK-NEXT:   $w0 = COPY [[COPY]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
 entry:
   %0 = tail call i32 asm "mov ${0:w}, 7", "={w0}"() nounwind
   ret i32 %0
@@ -54,10 +54,10 @@ entry:
 define i32 @test_single_register_output() nounwind ssp {
   ; CHECK-LABEL: name: test_single_register_output
   ; CHECK: bb.1.entry:
-  ; CHECK:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %0
-  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
-  ; CHECK:   $w0 = COPY [[COPY]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %0
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
+  ; CHECK-NEXT:   $w0 = COPY [[COPY]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
 entry:
   %0 = tail call i32 asm "mov ${0:w}, 7", "=r"() nounwind
   ret i32 %0
@@ -66,10 +66,10 @@ entry:
 define i64 @test_single_register_output_s64() nounwind ssp {
   ; CHECK-LABEL: name: test_single_register_output_s64
   ; CHECK: bb.1.entry:
-  ; CHECK:   INLINEASM &"mov $0, 7", 0 /* attdialect */, 1703946 /* regdef:GPR64common */, def %0
-  ; CHECK:   [[COPY:%[0-9]+]]:_(s64) = COPY %0
-  ; CHECK:   $x0 = COPY [[COPY]](s64)
-  ; CHECK:   RET_ReallyLR implicit $x0
+  ; CHECK-NEXT:   INLINEASM &"mov $0, 7", 0 /* attdialect */, 1769482 /* regdef:GPR64common */, def %0
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY %0
+  ; CHECK-NEXT:   $x0 = COPY [[COPY]](s64)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $x0
 entry:
   %0 = tail call i64 asm "mov $0, 7", "=r"() nounwind
   ret i64 %0
@@ -79,12 +79,12 @@ entry:
 define float @test_multiple_register_outputs_same() #0 {
   ; CHECK-LABEL: name: test_multiple_register_outputs_same
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %0, 655370 /* regdef:GPR32common */, def %1
-  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
-  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
-  ; CHECK:   [[FADD:%[0-9]+]]:_(s32) = G_FADD [[COPY]], [[COPY1]]
-  ; CHECK:   $s0 = COPY [[FADD]](s32)
-  ; CHECK:   RET_ReallyLR implicit $s0
+  ; CHECK-NEXT:   INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %0, 720906 /* regdef:GPR32common */, def %1
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
+  ; CHECK-NEXT:   [[FADD:%[0-9]+]]:_(s32) = G_FADD [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   $s0 = COPY [[FADD]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
   %1 = call { float, float } asm "mov $0, #0; mov $1, #0", "=r,=r"()
   %asmresult = extractvalue { float, float } %1, 0
   %asmresult1 = extractvalue { float, float } %1, 1
@@ -96,11 +96,11 @@ define float @test_multiple_register_outputs_same() #0 {
 define double @test_multiple_register_outputs_mixed() #0 {
   ; CHECK-LABEL: name: test_multiple_register_outputs_mixed
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %0, 1507338 /* regdef:FPR64 */, def %1
-  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
-  ; CHECK:   [[COPY1:%[0-9]+]]:_(s64) = COPY %1
-  ; CHECK:   $d0 = COPY [[COPY1]](s64)
-  ; CHECK:   RET_ReallyLR implicit $d0
+  ; CHECK-NEXT:   INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %0, 1572874 /* regdef:FPR64 */, def %1
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY %1
+  ; CHECK-NEXT:   $d0 = COPY [[COPY1]](s64)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $d0
   %1 = call { float, double } asm "mov $0, #0; mov $1, #0", "=r,=w"()
   %asmresult = extractvalue { float, double } %1, 1
   ret double %asmresult
@@ -109,28 +109,29 @@ define double @test_multiple_register_outputs_mixed() #0 {
 define i32 @test_specific_register_output_trunc() nounwind ssp {
   ; CHECK-LABEL: name: test_specific_register_output_trunc
   ; CHECK: bb.1.entry:
-  ; CHECK:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 10 /* regdef */, implicit-def $x0
-  ; CHECK:   [[COPY:%[0-9]+]]:_(s64) = COPY $x0
-  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
-  ; CHECK:   $w0 = COPY [[TRUNC]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 10 /* regdef */, implicit-def $x0
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+  ; CHECK-NEXT:   $w0 = COPY [[TRUNC]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
 entry:
   %0 = tail call i32 asm "mov ${0:w}, 7", "={x0}"() nounwind
   ret i32 %0
 }
 
 define zeroext i8 @test_register_output_trunc(i8* %src) nounwind {
+  ;
   ; CHECK-LABEL: name: test_register_output_trunc
   ; CHECK: bb.1.entry:
-  ; CHECK:   liveins: $x0
-  ; 
-  ; CHECK:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
-  ; CHECK:   INLINEASM &"mov ${0:w}, 32", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %1
-  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
-  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
-  ; CHECK:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
-  ; CHECK:   $w0 = COPY [[ZEXT]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   liveins: $x0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+  ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 32", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %1
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+  ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
+  ; CHECK-NEXT:   $w0 = COPY [[ZEXT]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
 entry:
   %0 = tail call i8 asm "mov ${0:w}, 32", "=r"() nounwind
   ret i8 %0
@@ -139,12 +140,12 @@ entry:
 define float @test_vector_output() nounwind {
   ; CHECK-LABEL: name: test_vector_output
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
-  ; CHECK:   INLINEASM &"fmov ${0}.2s, #1.0", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $d14
-  ; CHECK:   [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d14
-  ; CHECK:   [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](s64)
-  ; CHECK:   $s0 = COPY [[EVEC]](s32)
-  ; CHECK:   RET_ReallyLR implicit $s0
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+  ; CHECK-NEXT:   INLINEASM &"fmov ${0}.2s, #1.0", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $d14
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d14
+  ; CHECK-NEXT:   [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](s64)
+  ; CHECK-NEXT:   $s0 = COPY [[EVEC]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
   %1 = tail call <2 x float> asm sideeffect "fmov ${0}.2s, #1.0", "={v14}"() nounwind
   %2 = extractelement <2 x float> %1, i32 0
   ret float %2
@@ -153,10 +154,10 @@ define float @test_vector_output() nounwind {
 define void @test_input_register_imm() {
   ; CHECK-LABEL: name: test_input_register_imm
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 42
-  ; CHECK:   [[COPY:%[0-9]+]]:gpr64common = COPY [[C]](s64)
-  ; CHECK:   INLINEASM &"mov x0, $0", 1 /* sideeffect attdialect */, 1703945 /* reguse:GPR64common */, [[COPY]]
-  ; CHECK:   RET_ReallyLR
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 42
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64common = COPY [[C]](s64)
+  ; CHECK-NEXT:   INLINEASM &"mov x0, $0", 1 /* sideeffect attdialect */, 1769481 /* reguse:GPR64common */, [[COPY]]
+  ; CHECK-NEXT:   RET_ReallyLR
   call void asm sideeffect "mov x0, $0", "r"(i64 42)
   ret void
 }
@@ -165,10 +166,10 @@ define void @test_input_register_imm() {
 define i32 @test_boolean_imm_ext() {
   ; CHECK-LABEL: name: test_boolean_imm_ext
   ; CHECK: bb.1.entry:
-  ; CHECK:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
-  ; CHECK:   INLINEASM &"#TEST 42 + ${0:c} - .\0A\09", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 1
-  ; CHECK:   $w0 = COPY [[C]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+  ; CHECK-NEXT:   INLINEASM &"#TEST 42 + ${0:c} - .\0A\09", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 1
+  ; CHECK-NEXT:   $w0 = COPY [[C]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
 entry:
   tail call void asm sideeffect "#TEST 42 + ${0:c} - .\0A\09", "i"(i1 true)
   ret i32 1
@@ -177,8 +178,8 @@ entry:
 define void @test_input_imm() {
   ; CHECK-LABEL: name: test_input_imm
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   INLINEASM &"mov x0, $0", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 42
-  ; CHECK:   RET_ReallyLR
+  ; CHECK-NEXT:   INLINEASM &"mov x0, $0", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 42
+  ; CHECK-NEXT:   RET_ReallyLR
   call void asm sideeffect "mov x0, $0", "i"(i64 42)
   ret void
 }
@@ -186,15 +187,16 @@ define void @test_input_imm() {
 define zeroext i8 @test_input_register(i8* %src) nounwind {
   ; CHECK-LABEL: name: test_input_register
   ; CHECK: bb.1.entry:
-  ; CHECK:   liveins: $x0
-  ; CHECK:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
-  ; CHECK:   [[COPY1:%[0-9]+]]:gpr64common = COPY [[COPY]](p0)
-  ; CHECK:   INLINEASM &"ldtrb ${0:w}, [$1]", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %1, 1703945 /* reguse:GPR64common */, [[COPY1]]
-  ; CHECK:   [[COPY2:%[0-9]+]]:_(s32) = COPY %1
-  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY2]](s32)
-  ; CHECK:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
-  ; CHECK:   $w0 = COPY [[ZEXT]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   liveins: $x0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr64common = COPY [[COPY]](p0)
+  ; CHECK-NEXT:   INLINEASM &"ldtrb ${0:w}, [$1]", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %1, 1769481 /* reguse:GPR64common */, [[COPY1]]
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:_(s32) = COPY %1
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY2]](s32)
+  ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
+  ; CHECK-NEXT:   $w0 = COPY [[ZEXT]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
 entry:
   %0 = tail call i8 asm "ldtrb ${0:w}, [$1]", "=r,r"(i8* %src) nounwind
   ret i8 %0
@@ -203,12 +205,13 @@ entry:
 define i32 @test_memory_constraint(i32* %a) nounwind {
   ; CHECK-LABEL: name: test_memory_constraint
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   liveins: $x0
-  ; CHECK:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
-  ; CHECK:   INLINEASM &"ldr $0, $1", 8 /* mayload attdialect */, 655370 /* regdef:GPR32common */, def %1, 262158 /* mem:m */, [[COPY]](p0)
-  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
-  ; CHECK:   $w0 = COPY [[COPY1]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   liveins: $x0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+  ; CHECK-NEXT:   INLINEASM &"ldr $0, $1", 8 /* mayload attdialect */, 720906 /* regdef:GPR32common */, def %1, 262158 /* mem:m */, [[COPY]](p0)
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
+  ; CHECK-NEXT:   $w0 = COPY [[COPY1]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
   %1 = tail call i32 asm "ldr $0, $1", "=r,*m"(i32* elementtype(i32) %a)
   ret i32 %1
 }
@@ -216,15 +219,15 @@ define i32 @test_memory_constraint(i32* %a) nounwind {
 define i16 @test_anyext_input() {
   ; CHECK-LABEL: name: test_anyext_input
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
-  ; CHECK:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16)
-  ; CHECK:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
-  ; CHECK:   INLINEASM &"", 1 /* sideeffect attdialect */, 655370 /* regdef:GPR32common */, def %0, 655369 /* reguse:GPR32common */, [[COPY]]
-  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY %0
-  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
-  ; CHECK:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
-  ; CHECK:   $w0 = COPY [[ANYEXT1]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
+  ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16)
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
+  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 720906 /* regdef:GPR32common */, def %0, 720905 /* reguse:GPR32common */, [[COPY]]
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %0
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
+  ; CHECK-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
+  ; CHECK-NEXT:   $w0 = COPY [[ANYEXT1]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
   %1 = call i16 asm sideeffect "", "=r,r"(i16 1)
   ret i16 %1
 }
@@ -232,15 +235,15 @@ define i16 @test_anyext_input() {
 define i16 @test_anyext_input_with_matching_constraint() {
   ; CHECK-LABEL: name: test_anyext_input_with_matching_constraint
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
-  ; CHECK:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16)
-  ; CHECK:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
-  ; CHECK:   INLINEASM &"", 1 /* sideeffect attdialect */, 655370 /* regdef:GPR32common */, def %0, 2147483657 /* reguse tiedto:$0 */, [[COPY]](tied-def 3)
-  ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY %0
-  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
-  ; CHECK:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
-  ; CHECK:   $w0 = COPY [[ANYEXT1]](s32)
-  ; CHECK:   RET_ReallyLR implicit $w0
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
+  ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16)
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
+  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 720906 /* regdef:GPR32common */, def %0, 2147483657 /* reguse tiedto:$0 */, [[COPY]](tied-def 3)
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %0
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
+  ; CHECK-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
+  ; CHECK-NEXT:   $w0 = COPY [[ANYEXT1]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
   %1 = call i16 asm sideeffect "", "=r,0"(i16 1)
   ret i16 %1
 }
@@ -248,11 +251,11 @@ define i16 @test_anyext_input_with_matching_constraint() {
 define i64 @test_input_with_matching_constraint_to_physical_register() {
   ; CHECK-LABEL: name: test_input_with_matching_constraint_to_physical_register
   ; CHECK: bb.1 (%ir-block.0):
-  ; CHECK:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
-  ; CHECK:   INLINEASM &"", 0 /* attdialect */, 10 /* regdef */, implicit-def $x2, 2147483657 /* reguse tiedto:$0 */, [[C]](tied-def 3)(s64)
-  ; CHECK:   [[COPY:%[0-9]+]]:_(s64) = COPY $x2
-  ; CHECK:   $x0 = COPY [[COPY]](s64)
-  ; CHECK:   RET_ReallyLR implicit $x0
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+  ; CHECK-NEXT:   INLINEASM &"", 0 /* attdialect */, 10 /* regdef */, implicit-def $x2, 2147483657 /* reguse tiedto:$0 */, [[C]](tied-def 3)(s64)
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x2
+  ; CHECK-NEXT:   $x0 = COPY [[COPY]](s64)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $x0
   %1 = tail call i64 asm "", "={x2},0"(i64 0)
   ret i64 %1
 }

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll
index 444f791c7b695..39970e116960e 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll
@@ -69,7 +69,7 @@ define void @test2() #0 personality i32 (...)* @__gcc_personality_v0 {
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64common = COPY [[DEF]](p0)
-  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 1703945 /* reguse:GPR64common */, [[COPY]]
+  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 1769481 /* reguse:GPR64common */, [[COPY]]
   ; CHECK-NEXT:   G_BR %bb.2
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT: bb.2.a:

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir
index cef2635aacaf2..95a3c46a752c3 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir
@@ -10,8 +10,8 @@ body:             |
   bb.1:
     ; CHECK-LABEL: name: inlineasm_memory_clobber
     ; CHECK: INLINEASM &"", 25 /* sideeffect mayload maystore attdialect */
-    ; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
-    ; CHECK: RET_ReallyLR
+    ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */
+    ; CHECK-NEXT: RET_ReallyLR
     INLINEASM &"", 25
     INLINEASM &"", 1
     RET_ReallyLR
@@ -26,7 +26,7 @@ body:             |
   bb.1:
     ; CHECK-LABEL: name: inlineasm_register_clobber
     ; CHECK: INLINEASM &"", 25 /* sideeffect mayload maystore attdialect */, 12 /* clobber */, implicit-def early-clobber $d0
-    ; CHECK: RET_ReallyLR
+    ; CHECK-NEXT: RET_ReallyLR
     INLINEASM &"", 25, 12, implicit-def early-clobber $d0
     RET_ReallyLR
 ...
@@ -40,9 +40,9 @@ body:             |
   bb.1:
     ; CHECK-LABEL: name: inlineasm_phys_reg_output
     ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 10 /* regdef */, implicit-def $w0
-    ; CHECK: [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
-    ; CHECK: $w0 = COPY [[COPY]](s32)
-    ; CHECK: RET_ReallyLR implicit $w0
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+    ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
     INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 10 /* regdef */, implicit-def $w0
     %0:_(s32) = COPY $w0
     $w0 = COPY %0(s32)
@@ -57,10 +57,10 @@ tracksRegLiveness: true
 body:             |
   bb.1:
     ; CHECK-LABEL: name: inlineasm_virt_reg_output
-    ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1310730 /* regdef:WSeqPairsClass_with_sube32_in_MatrixIndexGPR32_12_15 */, def %0
-    ; CHECK: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0
-    ; CHECK: $w0 = COPY [[COPY]](s32)
-    ; CHECK: RET_ReallyLR implicit $w0
+    ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1310730 /* regdef:WSeqPairsClass_with_sube32_in_GPR32arg */, def %0
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0
+    ; CHECK-NEXT: $w0 = COPY [[COPY]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
     INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1310730 /* regdef:GPR32common */, def %0:gpr32common
     %1:_(s32) = COPY %0
     $w0 = COPY %1(s32)
@@ -75,11 +75,11 @@ tracksRegLiveness: true
 body:             |
   bb.1:
     ; CHECK-LABEL: name: inlineasm_virt_mixed_types
-    ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1310730 /* regdef:WSeqPairsClass_with_sube32_in_MatrixIndexGPR32_12_15 */, def %0, 2162698 /* regdef:FIXED_REGS */, def %1
-    ; CHECK: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0
-    ; CHECK: [[COPY1:%[0-9]+]]:fpr(s64) = COPY %1
-    ; CHECK: $d0 = COPY [[COPY1]](s64)
-    ; CHECK: RET_ReallyLR implicit $d0
+    ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1310730 /* regdef:WSeqPairsClass_with_sube32_in_GPR32arg */, def %0, 2162698 /* regdef:GPR64arg */, def %1
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr(s64) = COPY %1
+    ; CHECK-NEXT: $d0 = COPY [[COPY1]](s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit $d0
     INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1310730 /* regdef:GPR32common */, def %0:gpr32common, 2162698 /* regdef:FPR64 */, def %1:fpr64
     %3:_(s32) = COPY %0
     %4:_(s64) = COPY %1

diff  --git a/llvm/test/MC/AArch64/SVE2p1/pext-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/pext-diagnostics.s
new file mode 100644
index 0000000000000..97a3e6cc9f7b9
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/pext-diagnostics.s
@@ -0,0 +1,22 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid predicate as counter register
+
+pext    p0.h, pn3[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate-as-counter register expected pn8..pn15
+// CHECK-NEXT: pext    p0.h, pn3[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid lane index
+
+pext    p0.d, pn8[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: pext    p0.d, pn8[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+pext    p0.b, pn8[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: pext    p0.b, pn8[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/SVE2p1/pext.s b/llvm/test/MC/AArch64/SVE2p1/pext.s
new file mode 100644
index 0000000000000..5e9ac6d1b2ae6
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/pext.s
@@ -0,0 +1,110 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %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=+sme2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \
+// RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+pext    p0.h, pn8[0]  // 00100101-01100000-01110000-00010000
+// CHECK-INST: pext    p0.h, pn8[0]
+// CHECK-ENCODING: [0x10,0x70,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25607010 <unknown>
+
+pext    p5.h, pn10[1]  // 00100101-01100000-01110001-01010101
+// CHECK-INST: pext    p5.h, pn10[1]
+// CHECK-ENCODING: [0x55,0x71,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25607155 <unknown>
+
+pext    p7.h, pn13[1]  // 00100101-01100000-01110001-10110111
+// CHECK-INST: pext    p7.h, pn13[1]
+// CHECK-ENCODING: [0xb7,0x71,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 256071b7 <unknown>
+
+pext    p15.h, pn15[3]  // 00100101-01100000-01110011-11111111
+// CHECK-INST: pext    p15.h, pn15[3]
+// CHECK-ENCODING: [0xff,0x73,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 256073ff <unknown>
+
+pext    p0.s, pn8[0]  // 00100101-10100000-01110000-00010000
+// CHECK-INST: pext    p0.s, pn8[0]
+// CHECK-ENCODING: [0x10,0x70,0xa0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25a07010 <unknown>
+
+pext    p5.s, pn10[1]  // 00100101-10100000-01110001-01010101
+// CHECK-INST: pext    p5.s, pn10[1]
+// CHECK-ENCODING: [0x55,0x71,0xa0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25a07155 <unknown>
+
+pext    p7.s, pn13[1]  // 00100101-10100000-01110001-10110111
+// CHECK-INST: pext    p7.s, pn13[1]
+// CHECK-ENCODING: [0xb7,0x71,0xa0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25a071b7 <unknown>
+
+pext    p15.s, pn15[3]  // 00100101-10100000-01110011-11111111
+// CHECK-INST: pext    p15.s, pn15[3]
+// CHECK-ENCODING: [0xff,0x73,0xa0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25a073ff <unknown>
+
+pext    p0.d, pn8[0]  // 00100101-11100000-01110000-00010000
+// CHECK-INST: pext    p0.d, pn8[0]
+// CHECK-ENCODING: [0x10,0x70,0xe0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25e07010 <unknown>
+
+pext    p5.d, pn10[1]  // 00100101-11100000-01110001-01010101
+// CHECK-INST: pext    p5.d, pn10[1]
+// CHECK-ENCODING: [0x55,0x71,0xe0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25e07155 <unknown>
+
+pext    p7.d, pn13[1]  // 00100101-11100000-01110001-10110111
+// CHECK-INST: pext    p7.d, pn13[1]
+// CHECK-ENCODING: [0xb7,0x71,0xe0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25e071b7 <unknown>
+
+pext    p15.d, pn15[3]  // 00100101-11100000-01110011-11111111
+// CHECK-INST: pext    p15.d, pn15[3]
+// CHECK-ENCODING: [0xff,0x73,0xe0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25e073ff <unknown>
+
+pext    p0.b, pn8[0]  // 00100101-00100000-01110000-00010000
+// CHECK-INST: pext    p0.b, pn8[0]
+// CHECK-ENCODING: [0x10,0x70,0x20,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25207010 <unknown>
+
+pext    p5.b, pn10[1]  // 00100101-00100000-01110001-01010101
+// CHECK-INST: pext    p5.b, pn10[1]
+// CHECK-ENCODING: [0x55,0x71,0x20,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25207155 <unknown>
+
+pext    p7.b, pn13[1]  // 00100101-00100000-01110001-10110111
+// CHECK-INST: pext    p7.b, pn13[1]
+// CHECK-ENCODING: [0xb7,0x71,0x20,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 252071b7 <unknown>
+
+pext    p15.b, pn15[3]  // 00100101-00100000-01110011-11111111
+// CHECK-INST: pext    p15.b, pn15[3]
+// CHECK-ENCODING: [0xff,0x73,0x20,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 252073ff <unknown>

diff  --git a/llvm/test/MC/AArch64/SVE2p1/ptrue-diagnostics.s b/llvm/test/MC/AArch64/SVE2p1/ptrue-diagnostics.s
new file mode 100644
index 0000000000000..b91bc88c5e7d4
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/ptrue-diagnostics.s
@@ -0,0 +1,18 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid use of predicate as counter register
+
+ptrue   pn7.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid predicate register, expected PN in range pn8..pn15 with element suffix.
+// CHECK-NEXT: ptrue   pn7.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid use of predicate as counter without suffix
+
+ptrue   pn8
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid predicate register, expected PN in range pn8..pn15 with element suffix.
+// CHECK-NEXT: ptrue   pn8
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+

diff  --git a/llvm/test/MC/AArch64/SVE2p1/ptrue.s b/llvm/test/MC/AArch64/SVE2p1/ptrue.s
new file mode 100644
index 0000000000000..ae2a3456ff3cb
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE2p1/ptrue.s
@@ -0,0 +1,110 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %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=+sme2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \
+// RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+ptrue   pn8.h  // 00100101-01100000-01111000-00010000
+// CHECK-INST: ptrue   pn8.h
+// CHECK-ENCODING: [0x10,0x78,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25607810 <unknown>
+
+ptrue   pn13.h  // 00100101-01100000-01111000-00010101
+// CHECK-INST: ptrue   pn13.h
+// CHECK-ENCODING: [0x15,0x78,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25607815 <unknown>
+
+ptrue   pn15.h  // 00100101-01100000-01111000-00010111
+// CHECK-INST: ptrue   pn15.h
+// CHECK-ENCODING: [0x17,0x78,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25607817 <unknown>
+
+ptrue   pn9.h  // 00100101-01100000-01111000-00010001
+// CHECK-INST: ptrue   pn9.h
+// CHECK-ENCODING: [0x11,0x78,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25607811 <unknown>
+
+ptrue   pn8.s  // 00100101-10100000-01111000-00010000
+// CHECK-INST: ptrue   pn8.s
+// CHECK-ENCODING: [0x10,0x78,0xa0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25a07810 <unknown>
+
+ptrue   pn13.s  // 00100101-10100000-01111000-00010101
+// CHECK-INST: ptrue   pn13.s
+// CHECK-ENCODING: [0x15,0x78,0xa0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25a07815 <unknown>
+
+ptrue   pn15.s  // 00100101-10100000-01111000-00010111
+// CHECK-INST: ptrue   pn15.s
+// CHECK-ENCODING: [0x17,0x78,0xa0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25a07817 <unknown>
+
+ptrue   pn9.s  // 00100101-10100000-01111000-00010001
+// CHECK-INST: ptrue   pn9.s
+// CHECK-ENCODING: [0x11,0x78,0xa0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25a07811 <unknown>
+
+ptrue   pn8.d  // 00100101-11100000-01111000-00010000
+// CHECK-INST: ptrue   pn8.d
+// CHECK-ENCODING: [0x10,0x78,0xe0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25e07810 <unknown>
+
+ptrue   pn13.d  // 00100101-11100000-01111000-00010101
+// CHECK-INST: ptrue   pn13.d
+// CHECK-ENCODING: [0x15,0x78,0xe0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25e07815 <unknown>
+
+ptrue   pn15.d  // 00100101-11100000-01111000-00010111
+// CHECK-INST: ptrue   pn15.d
+// CHECK-ENCODING: [0x17,0x78,0xe0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25e07817 <unknown>
+
+ptrue   pn9.d  // 00100101-11100000-01111000-00010001
+// CHECK-INST: ptrue   pn9.d
+// CHECK-ENCODING: [0x11,0x78,0xe0,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25e07811 <unknown>
+
+ptrue   pn8.b  // 00100101-00100000-01111000-00010000
+// CHECK-INST: ptrue   pn8.b
+// CHECK-ENCODING: [0x10,0x78,0x20,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25207810 <unknown>
+
+ptrue   pn13.b  // 00100101-00100000-01111000-00010101
+// CHECK-INST: ptrue   pn13.b
+// CHECK-ENCODING: [0x15,0x78,0x20,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25207815 <unknown>
+
+ptrue   pn15.b  // 00100101-00100000-01111000-00010111
+// CHECK-INST: ptrue   pn15.b
+// CHECK-ENCODING: [0x17,0x78,0x20,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25207817 <unknown>
+
+ptrue   pn9.b  // 00100101-00100000-01111000-00010001
+// CHECK-INST: ptrue   pn9.b
+// CHECK-ENCODING: [0x11,0x78,0x20,0x25]
+// CHECK-ERROR: instruction requires: sme2 or sve2p1
+// CHECK-UNKNOWN: 25207811 <unknown>


        


More information about the llvm-commits mailing list