[llvm] [LLVM][AArch64]Add assembly/disassembly for compare-and-branch instr… (PR #113461)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 23 07:14:17 PDT 2024


https://github.com/CarolineConcatto created https://github.com/llvm/llvm-project/pull/113461

…uctions (#112726)

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

CBB<cc>, CBH<cc>,
CB<cc>(immediate), CB<cc>(register)
CBBLE, CBBLO, CBBLS, CBBLT
CBHLE, CBHLO, CBHLS, CBHLT
CBGE, CBHS, CBLE, CBLS (immediate)
CBLE, CBLO, CBLS, CBLT(register)

According to [1]

[1]https://developer.arm.com/documentation/ddi0602

Co-authored-by: Momchil Velikov momchil.velikov at arm.com
Co-authored-by: Spencer Abson spencer.abson at arm.com

This patch was reverted(git commit 83c6e2f8f4d3) and is being submitted again with the fix for buildbot failure in:
https://lab.llvm.org/buildbot/#/builders/25/builds/3493

>From 0e436c0b5fd7533bc9b644942d9e97cb0b5fa887 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Tue, 22 Oct 2024 08:16:22 +0100
Subject: [PATCH] [LLVM][AArch64]Add assembly/disassembly for
 compare-and-branch  instructions (#112726)

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

CBB<cc>, CBH<cc>,
CB<cc>(immediate), CB<cc>(register)
CBBLE, CBBLO, CBBLS, CBBLT
CBHLE, CBHLO, CBHLS, CBHLT
CBGE, CBHS, CBLE, CBLS (immediate)
CBLE, CBLO, CBLS, CBLT(register)

According to [1]

[1]https://developer.arm.com/documentation/ddi0602

Co-authored-by: Momchil Velikov momchil.velikov at arm.com
Co-authored-by: Spencer Abson spencer.abson at arm.com

This patch was reverted(git commit 83c6e2f8f4d3) and is being submitted again
with the fix for buildbot failure in:
https://lab.llvm.org/buildbot/#/builders/25/builds/3493
---
 .../lib/Target/AArch64/AArch64InstrFormats.td | 135 +++++
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  51 ++
 .../AArch64/AsmParser/AArch64AsmParser.cpp    |  51 ++
 .../Disassembler/AArch64Disassembler.cpp      |  17 +
 .../MCTargetDesc/AArch64AsmBackend.cpp        |  11 +
 .../MCTargetDesc/AArch64ELFObjectWriter.cpp   |   5 +
 .../AArch64/MCTargetDesc/AArch64FixupKinds.h  |   3 +
 .../MCTargetDesc/AArch64MCCodeEmitter.cpp     |  27 +
 .../test/MC/AArch64/CMPBR/cmpbr-diagnostics.s | 507 ++++++++++++++++++
 llvm/test/MC/AArch64/CMPBR/cmpbr.s            | 282 ++++++++++
 .../AArch64/CMPBR/cmpbr_aliases-diagnostics.s |  25 +
 llvm/test/MC/AArch64/CMPBR/cmpbr_aliases.s    |  74 +++
 llvm/test/MC/AArch64/CMPBR/cmpbr_lbl.s        | 320 +++++++++++
 .../test/MC/AArch64/directive-arch-negative.s |   5 +
 llvm/test/MC/AArch64/directive-arch.s         |   5 +
 .../directive-arch_extension-negative.s       |  10 +-
 16 files changed, 1527 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/MC/AArch64/CMPBR/cmpbr-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/CMPBR/cmpbr.s
 create mode 100644 llvm/test/MC/AArch64/CMPBR/cmpbr_aliases-diagnostics.s
 create mode 100644 llvm/test/MC/AArch64/CMPBR/cmpbr_aliases.s
 create mode 100644 llvm/test/MC/AArch64/CMPBR/cmpbr_lbl.s

diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index b690a41621f10d..9dd417314fbb86 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -388,6 +388,46 @@ def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
   let ParserMatchClass = AsmImmRange<0, 65535>;
 }
 
+def uimm6_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
+    let ParserMatchClass = UImm6Operand;
+}
+
+def uimm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 64; }]> {
+   let ParserMatchClass = UImm6Operand;
+}
+
+def UImm6Plus1Operand : AsmOperandClass {
+  let Name = "UImm6P1";
+  let DiagnosticType = "InvalidImm1_64";
+  let RenderMethod = "addImmOperands";
+  let ParserMethod = "tryParseAdjImm0_63<-1>";
+  let PredicateMethod = "isImmInRange<0,63>";
+}
+
+def UImm6Minus1Operand : AsmOperandClass {
+  let Name = "UImm6M1";
+  let DiagnosticType = "InvalidImmM1_62";
+  let RenderMethod = "addImmOperands";
+  let ParserMethod = "tryParseAdjImm0_63<1>";
+  let PredicateMethod = "isImmInRange<0,63>";
+}
+
+def uimm6p1_32b : Operand<i32> {
+  let ParserMatchClass = UImm6Plus1Operand;
+}
+
+def uimm6p1_64b : Operand<i64> {
+  let ParserMatchClass = UImm6Plus1Operand;
+}
+
+def uimm6m1_32b : Operand<i32> {
+  let ParserMatchClass = UImm6Minus1Operand;
+}
+
+def uimm6m1_64b : Operand<i64> {
+  let ParserMatchClass = UImm6Minus1Operand;
+}
+
 def SImm9Operand : SImmOperand<9>;
 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
   let ParserMatchClass = SImm9Operand;
@@ -657,6 +697,7 @@ class PCRelLabel<int N> : BranchTarget<N> {
 def BranchTarget14Operand : BranchTarget<14>;
 def BranchTarget26Operand : BranchTarget<26>;
 def PCRelLabel19Operand   : PCRelLabel<19>;
+def PCRelLabel9Operand    : PCRelLabel<9>;
 
 def MovWSymbolG3AsmOperand : AsmOperandClass {
   let Name = "MovWSymbolG3";
@@ -2158,6 +2199,17 @@ def am_brcond : Operand<OtherVT> {
   let OperandType = "OPERAND_PCREL";
 }
 
+// Conditional branch target. 9-bit immediate. The low two bits of the target
+// offset are implied zero and so are not part of the immediate.
+def am_brcmpcond : Operand<OtherVT> {
+  let EncoderMethod = "getCondCompBranchTargetOpValue";
+  let DecoderMethod = "DecodePCRelLabel9";
+  let PrintMethod   = "printAlignedLabel";
+  let ParserMatchClass = PCRelLabel9Operand;
+  let OperandType = "OPERAND_PCREL";
+}
+
+
 class BranchCond<bit bit4, string mnemonic>
    : I<(outs), (ins ccode:$cond, am_brcond:$target),
        mnemonic, ".$cond\t$target", "",
@@ -12911,6 +12963,89 @@ class MulAccumCPA<bit isSub, string asm>
   let Inst{31} = 0b1;
 }
 
+
+//----------------------------------------------------------------------------
+// 2024 Armv9.6 Extensions
+//----------------------------------------------------------------------------
+
+//---
+// Compare-and-branch instructions.
+//---
+
+class BaseCmpBranchRegister<RegisterClass regtype, bit sf, bits<3> cc,
+                            bits<2>sz, string asm>
+    : I<(outs), (ins regtype:$Rt, regtype:$Rm, am_brcmpcond:$target),
+         asm, "\t$Rt, $Rm, $target", "",
+         []>,
+      Sched<[WriteBr]> {
+  let isBranch = 1;
+  let isTerminator = 1;
+
+  bits<5> Rm;
+  bits<5> Rt;
+  bits<9> target;
+  let Inst{31}    = sf;
+  let Inst{30-24} = 0b1110100;
+  let Inst{23-21} = cc;
+  let Inst{20-16} = Rm;
+  let Inst{15-14} = sz;
+  let Inst{13-5}  = target;
+  let Inst{4-0}   = Rt;
+}
+
+multiclass CmpBranchRegister<bits<3> cc, string asm> {
+  def Wrr : BaseCmpBranchRegister<GPR32, 0b0, cc, 0b00, asm>;
+  def Xrr : BaseCmpBranchRegister<GPR64, 0b1, cc, 0b00, asm>;
+}
+
+class BaseCmpBranchImmediate<RegisterClass regtype, bit sf, bits<3> cc,
+                             Operand imm_ty, string asm>
+    : I<(outs), (ins regtype:$Rt, imm_ty:$imm, am_brcmpcond:$target),
+         asm, "\t$Rt, $imm, $target", "",
+         []>,
+      Sched<[WriteBr]> {
+  let isBranch = 1;
+  let isTerminator = 1;
+
+  bits<5> Rt;
+  bits<6> imm;
+  bits<9> target;
+  let Inst{31}    = sf;
+  let Inst{30-24} = 0b1110101;
+  let Inst{23-21} = cc;
+  let Inst{20-15} = imm;
+  let Inst{14}    = 0b0;
+  let Inst{13-5}  = target;
+  let Inst{4-0}   = Rt;
+}
+
+multiclass CmpBranchImmediate<bits<3> cc, string imm_ty, string asm> {
+  def Wri : BaseCmpBranchImmediate<GPR32, 0b0, cc, !cast<Operand>(imm_ty # "_32b"), asm>;
+  def Xri : BaseCmpBranchImmediate<GPR64, 0b1, cc, !cast<Operand>(imm_ty # "_64b"), asm>;
+}
+
+multiclass CmpBranchImmediateAlias<string mnemonic, string insn, string imm_ty> {
+ def : InstAlias<mnemonic # "\t$Rt, $imm, $target",
+                 (!cast<Instruction>(insn # "Wri") GPR32:$Rt,
+                  !cast<Operand>(imm_ty # "_32b"):$imm,
+                  am_brcmpcond:$target), 0>;
+ def : InstAlias<mnemonic # "\t$Rt, $imm, $target",
+                 (!cast<Instruction>(insn # "Xri") GPR64:$Rt,
+                  !cast<Operand>(imm_ty # "_64b"):$imm,
+                  am_brcmpcond:$target), 0>;
+}
+
+multiclass CmpBranchWRegisterAlias<string mnemonic, string insn> {
+  def : InstAlias<mnemonic # "\t$Rt, $Rm, $target",
+                 (!cast<Instruction>(insn # "Wrr") GPR32:$Rm, GPR32:$Rt, am_brcmpcond:$target), 0>;
+}
+
+multiclass CmpBranchRegisterAlias<string mnemonic, string insn> {
+  defm : CmpBranchWRegisterAlias<mnemonic, insn>;
+
+  def : InstAlias<mnemonic # "\t$Rt, $Rm, $target",
+                 (!cast<Instruction>(insn # "Xrr") GPR64:$Rm, GPR64:$Rt, am_brcmpcond:$target), 0>;
+}
 //----------------------------------------------------------------------------
 // Allow the size specifier tokens to be upper case, not just lower.
 def : TokenAlias<".4B", ".4b">;  // Add dot product
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 63f239020179b2..99e3ed31643b6e 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -10423,6 +10423,57 @@ defm : PromoteBinaryv8f16Tov4f32<any_fdiv, FDIVv4f32>;
 defm : PromoteBinaryv8f16Tov4f32<any_fmul, FMULv4f32>;
 defm : PromoteBinaryv8f16Tov4f32<any_fsub, FSUBv4f32>;
 
+let Predicates = [HasCMPBR] in {
+ defm CBGT : CmpBranchRegister<0b000, "cbgt">;
+ defm CBGE : CmpBranchRegister<0b001, "cbge">;
+ defm CBHI : CmpBranchRegister<0b010, "cbhi">;
+ defm CBHS : CmpBranchRegister<0b011, "cbhs">;
+ defm CBEQ : CmpBranchRegister<0b110, "cbeq">;
+ defm CBNE : CmpBranchRegister<0b111, "cbne">;
+
+ def CBHGTWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b000, 0b11, "cbhgt">;
+ def CBHGEWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b001, 0b11, "cbhge">;
+ def CBHHIWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b010, 0b11, "cbhhi">;
+ def CBHHSWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b011, 0b11, "cbhhs">;
+ def CBHEQWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b110, 0b11, "cbheq">;
+ def CBHNEWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b111, 0b11, "cbhne">;
+
+ def CBBGTWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b000, 0b10, "cbbgt">;
+ def CBBGEWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b001, 0b10, "cbbge">;
+ def CBBHIWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b010, 0b10, "cbbhi">;
+ def CBBHSWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b011, 0b10, "cbbhs">;
+ def CBBEQWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b110, 0b10, "cbbeq">;
+ def CBBNEWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b111, 0b10, "cbbne">;
+
+ defm CBGT : CmpBranchImmediate<0b000, "uimm6", "cbgt">;
+ defm CBLT : CmpBranchImmediate<0b001, "uimm6", "cblt">;
+ defm CBHI : CmpBranchImmediate<0b010, "uimm6", "cbhi">;
+ defm CBLO : CmpBranchImmediate<0b011, "uimm6", "cblo">;
+ defm CBEQ : CmpBranchImmediate<0b110, "uimm6", "cbeq">;
+ defm CBNE : CmpBranchImmediate<0b111, "uimm6", "cbne">;
+
+ defm : CmpBranchImmediateAlias<"cbge", "CBGT", "uimm6p1">;
+ defm : CmpBranchImmediateAlias<"cbhs", "CBHI", "uimm6p1">;
+ defm : CmpBranchImmediateAlias<"cble", "CBLT", "uimm6m1">;
+ defm : CmpBranchImmediateAlias<"cbls", "CBLO", "uimm6m1">;
+
+ defm : CmpBranchRegisterAlias<"cble", "CBGE">;
+ defm : CmpBranchRegisterAlias<"cblo", "CBHI">;
+ defm : CmpBranchRegisterAlias<"cbls", "CBHS">;
+ defm : CmpBranchRegisterAlias<"cblt", "CBGT">;
+
+ defm : CmpBranchWRegisterAlias<"cbble", "CBBGE">;
+ defm : CmpBranchWRegisterAlias<"cbblo", "CBBHI">;
+ defm : CmpBranchWRegisterAlias<"cbbls", "CBBHS">;
+ defm : CmpBranchWRegisterAlias<"cbblt", "CBBGT">;
+
+ defm : CmpBranchWRegisterAlias<"cbhle", "CBHGE">;
+ defm : CmpBranchWRegisterAlias<"cbhlo", "CBHHI">;
+ defm : CmpBranchWRegisterAlias<"cbhls", "CBHHS">;
+ defm : CmpBranchWRegisterAlias<"cbhlt", "CBHGT">;
+} // HasCMPBR
+
+
 //===-----------------------------------------------------===//
 // Atomic floating-point in-memory instructions (FEAT_LSFE)
 //===-----------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 9fb3501286e531..a46c7b3aef6e48 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -2092,6 +2092,20 @@ class AArch64Operand : public MCParsedAsmOperand {
     Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
   }
 
+  void addPCRelLabel9Operands(MCInst &Inst, unsigned N) const {
+    // Branch operands don't encode the low bits, so shift them off
+    // here. If it's a label, however, just put it on directly as there's
+    // not enough information now to do anything.
+    assert(N == 1 && "Invalid number of operands!");
+    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
+    if (!MCE) {
+      addExpr(Inst, getImm());
+      return;
+    }
+    assert(MCE && "Invalid constant immediate operand!");
+    Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
+  }
+
   void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
     // Branch operands don't encode the low bits, so shift them off
     // here. If it's a label, however, just put it on directly as there's
@@ -5987,6 +6001,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
     return Error(Loc, "immediate must be an integer in range [1, 32].");
   case Match_InvalidImm1_64:
     return Error(Loc, "immediate must be an integer in range [1, 64].");
+  case Match_InvalidImmM1_62:
+    return Error(Loc, "immediate must be an integer in range [-1, 62].");
   case Match_InvalidMemoryIndexedRange2UImm0:
     return Error(Loc, "vector select offset must be the immediate range 0:1.");
   case Match_InvalidMemoryIndexedRange2UImm1:
@@ -6757,6 +6773,7 @@ bool AArch64AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidImm1_16:
   case Match_InvalidImm1_32:
   case Match_InvalidImm1_64:
+  case Match_InvalidImmM1_62:
   case Match_InvalidMemoryIndexedRange2UImm0:
   case Match_InvalidMemoryIndexedRange2UImm1:
   case Match_InvalidMemoryIndexedRange2UImm2:
@@ -8224,3 +8241,37 @@ ParseStatus AArch64AsmParser::tryParseImmRange(OperandVector &Operands) {
       AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S, E, getContext()));
   return ParseStatus::Success;
 }
+
+template <int Adj>
+ParseStatus AArch64AsmParser::tryParseAdjImm0_63(OperandVector &Operands) {
+  SMLoc S = getLoc();
+
+  parseOptionalToken(AsmToken::Hash);
+  bool IsNegative = parseOptionalToken(AsmToken::Minus);
+
+  if (getTok().isNot(AsmToken::Integer))
+    return ParseStatus::NoMatch;
+
+  const MCExpr *Ex;
+  if (getParser().parseExpression(Ex))
+    return ParseStatus::NoMatch;
+
+  int64_t Imm = dyn_cast<MCConstantExpr>(Ex)->getValue();
+  if (IsNegative)
+    Imm = -Imm;
+
+  // We want an adjusted immediate in the range [0, 63]. If we don't have one,
+  // return a value, which is certain to trigger a error message about invalid
+  // immediate range instead of a non-descriptive invalid operand error.
+  static_assert(Adj == 1 || Adj == -1, "Unsafe immediate adjustment");
+  if (Imm == INT64_MIN || Imm == INT64_MAX || Imm + Adj < 0 || Imm + Adj > 63)
+    Imm = -2;
+  else
+    Imm += Adj;
+
+  SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
+  Operands.push_back(AArch64Operand::CreateImm(
+      MCConstantExpr::create(Imm, getContext()), S, E, getContext()));
+
+  return ParseStatus::Success;
+}
diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index 8e2dc3d217cb9f..2fe02f546629e8 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -80,6 +80,9 @@ static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
 static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
                                        uint64_t Address,
                                        const MCDisassembler *Decoder);
+static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm,
+                                      uint64_t Address,
+                                      const MCDisassembler *Decoder);
 static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder);
@@ -488,6 +491,20 @@ static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
   return Success;
 }
 
+static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm, uint64_t Addr,
+                                      const MCDisassembler *Decoder) {
+  int64_t ImmVal = Imm;
+
+  // Sign-extend 9-bit immediate.
+  if (ImmVal & (1 << (9 - 1)))
+    ImmVal |= ~((1LL << 9) - 1);
+
+  if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal * 4), Addr,
+                                         /*IsBranch=*/true, 0, 0, 4))
+    Inst.addOperand(MCOperand::createImm(ImmVal));
+  return Success;
+}
+
 static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index adc6c5bf4ed171..1fdd2b08c904cc 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -66,6 +66,7 @@ class AArch64AsmBackend : public MCAsmBackend {
         {"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
         {"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal},
         {"fixup_aarch64_movw", 5, 16, 0},
+        {"fixup_aarch64_pcrel_branch9", 5, 9,  PCRelFlagVal},
         {"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
         {"fixup_aarch64_pcrel_branch16", 5, 16, PCRelFlagVal},
         {"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal},
@@ -120,6 +121,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
     return 2;
 
   case AArch64::fixup_aarch64_movw:
+  case AArch64::fixup_aarch64_pcrel_branch9:
   case AArch64::fixup_aarch64_pcrel_branch14:
   case AArch64::fixup_aarch64_pcrel_branch16:
   case AArch64::fixup_aarch64_add_imm12:
@@ -307,6 +309,14 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
     }
     return Value;
   }
+  case AArch64::fixup_aarch64_pcrel_branch9:
+    // Signed 11-bit(9bits + 2 shifts) label
+    if (!isInt<11>(SignedValue))
+      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+    // Low two bits are not encoded (4-byte alignment assumed).
+    if (Value & 0b11)
+      Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
+    return (Value >> 2) & 0x1ff;
   case AArch64::fixup_aarch64_pcrel_branch14:
     // Signed 16-bit immediate
     if (!isInt<16>(SignedValue))
@@ -391,6 +401,7 @@ unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) con
     return 8;
 
   case AArch64::fixup_aarch64_movw:
+  case AArch64::fixup_aarch64_pcrel_branch9:
   case AArch64::fixup_aarch64_pcrel_branch14:
   case AArch64::fixup_aarch64_pcrel_branch16:
   case AArch64::fixup_aarch64_add_imm12:
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 1a7a175404a64b..83aac6fdae7290 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -188,6 +188,11 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
       Ctx.reportError(Fixup.getLoc(),
                       "relocation of PAC/AUT instructions is not supported");
       return ELF::R_AARCH64_NONE;
+    case AArch64::fixup_aarch64_pcrel_branch9:
+      Ctx.reportError(
+          Fixup.getLoc(),
+          "relocation of compare-and-branch instructions not supported");
+      return ELF::R_AARCH64_NONE;
     case AArch64::fixup_aarch64_pcrel_branch19:
       return R_CLS(CONDBR19);
     default:
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h
index fdee2d5ad2bf30..113dbe1634e765 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h
@@ -40,6 +40,9 @@ enum Fixups {
   // FIXME: comment
   fixup_aarch64_movw,
 
+  // The high 9 bits of a 11-bit pc-relative immediate.
+  fixup_aarch64_pcrel_branch9,
+
   // The high 14 bits of a 21-bit pc-relative immediate.
   fixup_aarch64_pcrel_branch14,
 
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
index 61b83847666908..760e09dc6fdac9 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
@@ -88,6 +88,12 @@ class AArch64MCCodeEmitter : public MCCodeEmitter {
                                       SmallVectorImpl<MCFixup> &Fixups,
                                       const MCSubtargetInfo &STI) const;
 
+  /// getCondCompBranchTargetOpValue - Return the encoded value for a
+  /// conditional compare-and-branch target.
+  uint32_t getCondCompBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
+                                          SmallVectorImpl<MCFixup> &Fixups,
+                                          const MCSubtargetInfo &STI) const;
+
   /// getPAuthPCRelOpValue - Return the encoded value for a pointer
   /// authentication pc-relative operand.
   uint32_t getPAuthPCRelOpValue(const MCInst &MI, unsigned OpIdx,
@@ -333,6 +339,27 @@ uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
   return 0;
 }
 
+/// getCondCompBranchTargetOpValue - Return the encoded value for a conditional
+/// compare-and-branch target.
+uint32_t AArch64MCCodeEmitter::getCondCompBranchTargetOpValue(
+    const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
+    const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpIdx);
+
+  // If the destination is an immediate, we have nothing to do.
+  if (MO.isImm())
+    return MO.getImm();
+  assert(MO.isExpr() && "Unexpected target type!");
+
+  MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch9);
+  Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
+
+  ++MCNumFixups;
+
+  // All of the information is in the fixup.
+  return 0;
+}
+
 /// getPAuthPCRelOpValue - Return the encoded value for a pointer
 /// authentication pc-relative operand.
 uint32_t
diff --git a/llvm/test/MC/AArch64/CMPBR/cmpbr-diagnostics.s b/llvm/test/MC/AArch64/CMPBR/cmpbr-diagnostics.s
new file mode 100644
index 00000000000000..f8a6c165c5c323
--- /dev/null
+++ b/llvm/test/MC/AArch64/CMPBR/cmpbr-diagnostics.s
@@ -0,0 +1,507 @@
+// RUN: not llvm-mc -triple=aarch64 -filetype=obj -show-encoding -mattr=+cmpbr 2>&1 < %s | FileCheck %s
+
+//------------------------------------------------------------------------------
+// Incorrect label
+
+// -- cbgt
+
+cbgt x5, x5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbgt x5, x5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbgt w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbgt w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbgt w5, #20, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbgt w5, #20, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbgt x5, #20, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbgt x5, #20, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cblt
+
+cblt x5, #20, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cblt x5, #20, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cblt w5, #20, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cblt w5, #20, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbge
+
+cbge x5, x5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbge x5, x5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbge w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbge w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhi
+
+cbhi x2, x2, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhi x2, x2, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhi w2, w2, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhi w2, w2, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhi w2, #20, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhi w2, #20, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhi x2, #20, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhi x2, #20, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cblo
+
+cblo w5, #20, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cblo w5, #20, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cblo x5, #20, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cblo x5, #20, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhs
+
+cbhs x2, x2, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhs x2, x2, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhs w2, w2, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhs w2, w2, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbeq
+
+cbeq x5, x5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbeq x5, x5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}
+
+cbeq w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbeq w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}
+
+cbeq w5, #20, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbeq w5, #20, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}
+
+cbeq x5, #20, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbeq x5, #20, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}
+
+// -- cbne
+
+cbne w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbne w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}
+
+cbne x5, x5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbne x5, x5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}
+
+cbne x5, #20, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbne x5, #20, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}
+
+cbne w5, #20, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbne w5, #20, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}
+
+// -- cbhgt
+
+cbhgt w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhgt w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhgt w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhgt w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhge
+
+cbhge w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhge w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhge w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhge w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhhi
+
+cbhhi w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhhi w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhhi w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhhi w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhhs
+
+cbhhs w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhhs w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhhs w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhhs w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbheq
+
+cbheq w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbheq w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbheq w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbheq w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhne
+
+cbhne w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhne w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhne w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbhne w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbgt
+
+cbbgt w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbgt w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbgt w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbgt w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbge
+
+cbbge w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbge w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbge w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbge w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbhi
+
+cbbhi w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbhi w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbhi w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbhi w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbhs
+
+cbbhs w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbhs w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbhs w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbhs w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbeq
+
+cbbeq w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbeq w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbeq w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbeq w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbne
+
+cbbne w5, w5, #-1025
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbne w5, w5, #-1025
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbne w5, w5, #1021
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset
+// CHECK-NEXT: cbbne w5, w5, #1021
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+
+//------------------------------------------------------------------------------
+// Incorrect Operands
+
+// -- cbhgt
+
+cbhgt w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhgt w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhgt x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhgt x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhge
+
+cbhge w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhge w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhge x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhge x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhhi
+
+cbhhi w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhhi w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhhi x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhhi x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhhs
+
+cbhhs w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhhs w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhhs x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhhs x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbneq
+
+cbheq w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbheq w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbheq x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbheq x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhne
+
+cbhne w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhne w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhne x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbhne x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbgt
+
+cbbgt w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbgt w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbgt x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbgt x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbge
+
+cbbge w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbge w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbge x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbge x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbhi
+
+cbbhi w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbhi w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbhi x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbhi x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbhs
+
+cbbhs w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbhs w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbhs x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbhs x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbeq
+
+cbbeq w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbeq w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbeq x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: cbbeq x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbbne
+
+cbbne w5, #20, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: bbne w5, #20, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbbne x5, x5, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: bbne x5, x5, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+//------------------------------------------------------------------------------
+// (Immediate) compare value out-of-range
+
+// -- cbgt
+
+cbgt w5, #-1, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cbgt w5, #-1, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbgt w5, #64, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cbgt w5, #64, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cblt
+
+cblt w5, #-1, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cblt w5, #-1, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cblt w5, #64, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cblt w5, #64, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbhi
+
+cbhi w5, #-1, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cbhi w5, #-1, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbhi w5, #64, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cbhi w5, #64, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cblo
+
+cblo w5, #-1, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cblo w5, #-1, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cblo w5, #64, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cblo w5, #64, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbeq
+
+cbeq w5, #-1, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cbeq w5, #-1, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbeq x5, #64, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cbeq x5, #64, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+// -- cbne
+
+cbne x5, #-1, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cbne x5, #-1, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
+
+cbne w5, #64, #1020
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 63].
+// CHECK-NEXT: cbne w5, #64, #1020
+// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/CMPBR/cmpbr.s b/llvm/test/MC/AArch64/CMPBR/cmpbr.s
new file mode 100644
index 00000000000000..b9f8f60d35e42e
--- /dev/null
+++ b/llvm/test/MC/AArch64/CMPBR/cmpbr.s
@@ -0,0 +1,282 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+cmpbr < %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=+cmpbr < %s \
+// RUN:        | llvm-objdump -d  --no-print-imm-hex --mattr=+cmpbr - | FileCheck %s --check-prefix=CHECK-DISASS
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+cmpbr < %s \
+// RUN:        | llvm-objdump -d  --no-print-imm-hex --mattr=-cmpbr - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+cmpbr < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+cmpbr -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+//------------------------------------------------------------------------------
+// Compare & branch (Register)
+//------------------------------------------------------------------------------
+
+cbgt w5, w5, #-1024
+// CHECK-INST: cbgt w5, w5, #-1024
+// CHECK-DISASS: cbgt w5, w5,  0xfffffffffffffc00 <.text+0xfffffffffffffc00
+// CHECK-ENCODING: [0x05,0x20,0x05,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74052005 <unknown>
+
+cbgt x5, x5, #1020
+// CHECK-INST: cbgt x5, x5, #1020
+// CHECK-DISASS: cbgt x5, x5, 0x400 <.text+0x400>
+// CHECK-ENCODING: [0xe5,0x1f,0x05,0xf4]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4051fe5 <unknown>
+
+cbge x2, x2, #-1024
+// CHECK-INST: cbge x2, x2, #-1024
+// CHECK-DISASS: cbge x2, x2, 0xfffffffffffffc08 <.text+0xfffffffffffffc08
+// CHECK-ENCODING: [0x02,0x20,0x22,0xf4]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4222002 <unknown>
+
+cbge w5, w5, #1020
+// CHECK-INST: cbge w5, w5, #1020
+// CHECK-DISASS: cbge w5, w5, 0x408 <.text+0x408>
+// CHECK-ENCODING: [0xe5,0x1f,0x25,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74251fe5 <unknown>
+
+
+cbhi w5, w5, #-1024
+// CHECK-INST: cbhi w5, w5, #-1024
+// CHECK-DISASS: cbhi w5, w5, 0xfffffffffffffc10 <.text+0xfffffffffffffc10>
+// CHECK-ENCODING: [0x05,0x20,0x45,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74452005 <unknown>
+
+cbhi x5, x5, #1020
+// CHECK-INST: cbhi x5, x5, #1020
+// CHECK-DISASS: cbhi x5, x5, 0x410 <.text+0x410>
+// CHECK-ENCODING: [0xe5,0x1f,0x45,0xf4]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4451fe5 <unknown>
+
+cbhs x2, x2, #1020
+// CHECK-INST: cbhs x2, x2, #1020
+// CHECK-DISASS: cbhs x2, x2, 0x414 <.text+0x414>
+// CHECK-ENCODING: [0xe2,0x1f,0x62,0xf4]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4621fe2 <unknown>
+
+cbhs w5, w5, #1020
+// CHECK-INST: cbhs w5, w5, #1020
+// CHECK-DISASS: cbhs w5, w5, 0x418 <.text+0x418>
+// CHECK-ENCODING: [0xe5,0x1f,0x65,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74651fe5 <unknown>
+
+cbeq w5, w5, #-1024
+// CHECK-INST: cbeq w5, w5, #-1024
+// CHECK-DISASS: cbeq w5, w5, 0xfffffffffffffc20 <.text+0xfffffffffffffc20>
+// CHECK-ENCODING: [0x05,0x20,0xc5,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74c52005 <unknown>
+
+cbeq x5, x5, #1020
+// CHECK-INST: cbeq x5, x5, #1020
+// CHECK-DISASS: cbeq x5, x5, 0x420 <.text+0x420>
+// CHECK-ENCODING: [0xe5,0x1f,0xc5,0xf4]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4c51fe5 <unknown>
+
+cbne x2, x2, #-1024
+// CHECK-INST: cbne x2, x2, #-1024
+// CHECK-DISASS: cbne x2, x2, 0xfffffffffffffc28 <.text+0xfffffffffffffc28>
+// CHECK-ENCODING: [0x02,0x20,0xe2,0xf4]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4e22002 <unknown>
+
+cbne w5, w5, #-1024
+// CHECK-INST: cbne w5, w5, #-1024
+// CHECK-DISASS: cbne w5, w5, 0xfffffffffffffc2c <.text+0xfffffffffffffc2c>
+// CHECK-ENCODING: [0x05,0x20,0xe5,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74e52005 <unknown>
+
+///
+// CBH<XX>
+///
+
+cbhgt w5, w5, #-1024
+// CHECK-INST: cbhgt w5, w5, #-1024
+// CHECK-DISASS: cbhgt w5, w5, 0xfffffffffffffc30 <.text+0xfffffffffffffc30>
+// CHECK-ENCODING: [0x05,0xe0,0x05,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7405e005 <unknown>
+
+cbhge w5, w5, #-1024
+// CHECK-INST: cbhge w5, w5, #-1024
+// CHECK-DISASS: cbhge w5, w5, 0xfffffffffffffc34 <.text+0xfffffffffffffc34>
+// CHECK-ENCODING: [0x05,0xe0,0x25,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7425e005 <unknown>
+
+cbhhi w5, w5, #-1024
+// CHECK-INST: cbhhi w5, w5, #-1024
+// CHECK-DISASS: cbhhi w5, w5, 0xfffffffffffffc38 <.text+0xfffffffffffffc38>
+// CHECK-ENCODING: [0x05,0xe0,0x45,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7445e005 <unknown>
+
+cbhhs w5, w5, #-1024
+// CHECK-INST: cbhhs w5, w5, #-1024
+// CHECK-DISASS: cbhhs w5, w5, 0xfffffffffffffc3c <.text+0xfffffffffffffc3c>
+// CHECK-ENCODING: [0x05,0xe0,0x65,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7465e005 <unknown>
+
+cbheq w5, w5, #-1024
+// CHECK-INST: cbheq w5, w5, #-1024
+// CHECK-DISASS: cbheq w5, w5, 0xfffffffffffffc40 <.text+0xfffffffffffffc40>
+// CHECK-ENCODING: [0x05,0xe0,0xc5,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74c5e005 <unknown>
+
+cbhne w5, w5, #-1024
+// CHECK-INST: cbhne w5, w5, #-1024
+// CHECK-DISASS: cbhne w5, w5, 0xfffffffffffffc44 <.text+0xfffffffffffffc44>
+// CHECK-ENCODING: [0x05,0xe0,0xe5,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74e5e005 <unknown>
+
+
+///
+// CBB<XX>
+///
+cbbgt w5, w5, #-1024
+// CHECK-INST: cbbgt w5, w5, #-1024
+// CHECK-DISASS: cbbgt w5, w5, 0xfffffffffffffc48 <.text+0xfffffffffffffc48>
+// CHECK-ENCODING: [0x05,0xa0,0x05,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7405a005 <unknown>
+
+cbbge w5, w5, #-1024
+// CHECK-INST: cbbge w5, w5, #-1024
+// CHECK-DISASS: cbbge w5, w5, 0xfffffffffffffc4c <.text+0xfffffffffffffc4c>
+// CHECK-ENCODING: [0x05,0xa0,0x25,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7425a005 <unknown>
+
+cbbhi w5, w5, #-1024
+// CHECK-INST: cbbhi w5, w5, #-1024
+// CHECK-DISASS: cbbhi w5, w5, 0xfffffffffffffc50 <.text+0xfffffffffffffc50>
+// CHECK-ENCODING: [0x05,0xa0,0x45,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7445a005 <unknown>
+
+cbbhs w5, w5, #-1024
+// CHECK-INST: cbbhs w5, w5, #-1024
+// CHECK-DISASS: cbbhs w5, w5, 0xfffffffffffffc54 <.text+0xfffffffffffffc54>
+// CHECK-ENCODING: [0x05,0xa0,0x65,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7465a005 <unknown>
+
+cbbeq w5, w5, #-1024
+// CHECK-INST: cbbeq w5, w5, #-1024
+// CHECK-DISASS: cbbeq w5, w5, 0xfffffffffffffc58 <.text+0xfffffffffffffc58>
+// CHECK-ENCODING: [0x05,0xa0,0xc5,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74c5a005 <unknown>
+
+cbbne w5, w5, #-1024
+// CHECK-INST: cbbne w5, w5, #-1024
+// CHECK-DISASS: cbbne w5, w5, 0xfffffffffffffc5c <.text+0xfffffffffffffc5c>
+// CHECK-ENCODING: [0x05,0xa0,0xe5,0x74]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74e5a005 <unknown>
+
+//------------------------------------------------------------------------------
+// Compare & branch (Immediate)
+//------------------------------------------------------------------------------
+
+cbgt w5, #63, #1020
+// CHECK-INST: cbgt w5, #63, #1020
+// CHECK-DISASS: cbgt w5,  #63, 0x45c <.text+0x45c>
+// CHECK-ENCODING: [0xe5,0x9f,0x1f,0x75]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 751f9fe5 <unknown>
+
+cbgt x5, #0, #-1024
+// CHECK-INST: cbgt x5, #0, #-1024
+// CHECK-DISASS: cbgt x5, #0, 0xfffffffffffffc64 <.text+0xfffffffffffffc64>
+// CHECK-ENCODING: [0x05,0x20,0x00,0xf5]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f5002005 <unknown>
+
+cbhi w5, #31, #1020
+// CHECK-INST: cbhi w5, #31, #1020
+// CHECK-DISASS: cbhi w5, #31, 0x464 <.text+0x464>
+// CHECK-ENCODING: [0xe5,0x9f,0x4f,0x75]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 754f9fe5 <unknown>
+
+cbhi x5, #63, #-1024
+// CHECK-INST: cbhi x5, #63, #-1024
+// CHECK-DISASS: cbhi x5, #63, 0xfffffffffffffc6c <.text+0xfffffffffffffc6c>
+// CHECK-ENCODING: [0x05,0xa0,0x5f,0xf5]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f55fa005 <unknown>
+
+cblt w5, #63, #1020
+// CHECK-INST: cblt w5, #63, #1020
+// CHECK-DISASS: cblt w5, #63, 0x46c <.text+0x46c>
+// CHECK-ENCODING: [0xe5,0x9f,0x3f,0x75]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 753f9fe5 <unknown>
+
+cblt x5, #0, #-1024
+// CHECK-INST: cblt x5, #0, #-1024
+// CHECK-DISASS: cblt x5, #0, 0xfffffffffffffc74 <.text+0xfffffffffffffc74>
+// CHECK-ENCODING: [0x05,0x20,0x20,0xf5]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f5202005 <unknown>
+
+cblo w5, #31, #1020
+// CHECK-INST: cblo w5, #31, #1020
+// CHECK-DISASS: cblo w5, #31, 0x474 <.text+0x474>
+// CHECK-ENCODING: [0xe5,0x9f,0x6f,0x75]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 756f9fe5 <unknown>
+
+cblo x5, #31, #-1024
+// CHECK-INST: cblo x5, #31, #-1024
+// CHECK-DISASS: cblo x5, #31, 0xfffffffffffffc7c <.text+0xfffffffffffffc7c>
+// CHECK-ENCODING: [0x05,0xa0,0x6f,0xf5]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f56fa005 <unknown>
+
+cbeq w5, #31, #1020
+// CHECK-INST: cbeq w5, #31, #1020
+// CHECK-DISASS: cbeq w5, #31, 0x47c <.text+0x47c>
+// CHECK-ENCODING: [0xe5,0x9f,0xcf,0x75]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 75cf9fe5 <unknown>
+
+cbeq x5, #31, #-1024
+// CHECK-INST: cbeq x5, #31, #-1024
+// CHECK-DISASS: cbeq x5, #31, 0xfffffffffffffc84 <.text+0xfffffffffffffc84>
+// CHECK-ENCODING: [0x05,0xa0,0xcf,0xf5]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f5cfa005 <unknown>
+
+cbne w5, #31, #1020
+// CHECK-INST: cbne w5, #31, #1020
+// CHECK-DISASS: cbne w5, #31, 0x484 <.text+0x484>
+// CHECK-ENCODING: [0xe5,0x9f,0xef,0x75]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 75ef9fe5 <unknown>
+
+cbne x5, #31, #-1024
+// CHECK-INST: cbne x5, #31, #-1024
+// CHECK-DISASS: cbne x5, #31, 0xfffffffffffffc8c <.text+0xfffffffffffffc8c>
+// CHECK-ENCODING: [0x05,0xa0,0xef,0xf5]
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f5efa005 <unknown>
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/CMPBR/cmpbr_aliases-diagnostics.s b/llvm/test/MC/AArch64/CMPBR/cmpbr_aliases-diagnostics.s
new file mode 100644
index 00000000000000..c4135d0fadfc09
--- /dev/null
+++ b/llvm/test/MC/AArch64/CMPBR/cmpbr_aliases-diagnostics.s
@@ -0,0 +1,25 @@
+// RUN: not llvm-mc -triple=aarch64 -filetype=obj -mattr=+cmpbr 2>&1 < %s | FileCheck %s
+
+L:
+    cbge w5, #0, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 64]
+    cbge x5, #65, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 64]
+
+    cbhs w5, #0, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 64]
+    cbhs x5, #65, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 64]
+
+    cble w5, #-2, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-1, 62]
+    cble x5, #63, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-1, 62]
+
+    cbls w5, #-2, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-1, 62]
+    cbls x5, #63, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-1, 62]
+
+   cbls x3, w5, L
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-1, 62]
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/CMPBR/cmpbr_aliases.s b/llvm/test/MC/AArch64/CMPBR/cmpbr_aliases.s
new file mode 100644
index 00000000000000..b7ec31d51a4263
--- /dev/null
+++ b/llvm/test/MC/AArch64/CMPBR/cmpbr_aliases.s
@@ -0,0 +1,74 @@
+// RUN: llvm-mc --triple=aarch64-linux -mattr=+cmpbr --show-encoding --show-inst < %s | FileCheck %s
+ .text
+
+// CHECK: cbbge w5, w3, #-1024                  // encoding: [0x05,0xa0,0x23,0x74]
+    cbble w3, w5, #-1024
+
+// CHECK: cbbhi w5, w3, #-1024                  // encoding: [0x05,0xa0,0x43,0x74]
+    cbblo w3, w5, #-1024
+
+// CHECK: cbbhs w5, w3, #-1024                  // encoding: [0x05,0xa0,0x63,0x74]
+    cbbls w3, w5, #-1024
+
+// CHECK: cbbgt w5, w3, #-1024                  // encoding: [0x05,0xa0,0x03,0x74]
+    cbblt w3, w5, #-1024
+
+// CHECK: cbhge w5, w3, #-1024                  // encoding: [0x05,0xe0,0x23,0x74]
+    cbhle w3, w5, #-1024
+
+// CHECK: cbhhi w5, w3, #-1024                  // encoding: [0x05,0xe0,0x43,0x74]
+    cbhlo w3, w5, #-1024
+
+// CHECK: cbhhs w5, w3, #-1024                  // encoding: [0x05,0xe0,0x63,0x74]
+    cbhls w3, w5, #-1024
+
+// CHECK: cbhgt w5, w3, #-1024                  // encoding: [0x05,0xe0,0x03,0x74]
+    cbhlt w3, w5, #-1024
+
+// CHECK: cbgt w5, #0, #-1024                  // encoding: [0x05,0x20,0x00,0x75]
+    cbge w5, #1, #-1024
+
+// CHECK: cbgt x5, #63, #-1024                 // encoding: [0x05,0xa0,0x1f,0xf5]
+    cbge x5, #64, #-1024
+
+// CHECK: cbhi w5, #0, #-1024                  // encoding: [0x05,0x20,0x40,0x75]
+    cbhs w5, #1, #-1024
+
+// CHECK: cbhi x5, #63, #-1024                 // encoding: [0x05,0xa0,0x5f,0xf5]
+    cbhs x5, #64, #-1024
+
+// CHECK: cblt w5, #0, #-1024                  // encoding: [0x05,0x20,0x20,0x75]
+    cble w5, #-1, #-1024
+
+// CHECK: cblt x5, #63, #-1024                 // encoding: [0x05,0xa0,0x3f,0xf5]
+    cble x5, #62, #-1024
+
+// CHECK: cblo w5, #0, #-1024                  // encoding: [0x05,0x20,0x60,0x75]
+    cbls w5, #-1, #-1024
+
+// CHECK: cblo x5, #63, #-1024                 // encoding: [0x05,0xa0,0x7f,0xf5]
+    cbls x5, #62, #-1024
+
+// CHECK: cbge w5, w3, #-1024                  // encoding: [0x05,0x20,0x23,0x74]
+    cble w3, w5, #-1024
+
+// CHECK: cbge x5, x3, #-1024                  // encoding: [0x05,0x20,0x23,0xf4]
+    cble x3, x5, #-1024
+
+// CHECK: cbhi w5, w3, #-1024                  // encoding: [0x05,0x20,0x43,0x74]
+    cblo w3, w5, #-1024
+
+// CHECK: cbhi x5, x3, #-1024                  // encoding: [0x05,0x20,0x43,0xf4]
+    cblo x3, x5, #-1024
+
+// CHECK: cbhs w5, w3, #-1024                  // encoding: [0x05,0x20,0x63,0x74]
+    cbls w3, w5, #-1024
+
+// CHECK: cbhs x5, x3, #-1024                  // encoding: [0x05,0x20,0x63,0xf4]
+    cbls x3, x5, #-1024
+
+// CHECK: cbgt w5, w3, #-1024                  // encoding: [0x05,0x20,0x03,0x74]
+    cblt w3, w5, #-1024
+
+// CHECK: cbgt x5, x3, #-1024                  // encoding: [0x05,0x20,0x03,0xf4]
+    cblt x3, x5, #-1024
diff --git a/llvm/test/MC/AArch64/CMPBR/cmpbr_lbl.s b/llvm/test/MC/AArch64/CMPBR/cmpbr_lbl.s
new file mode 100644
index 00000000000000..26d3b5391f5d43
--- /dev/null
+++ b/llvm/test/MC/AArch64/CMPBR/cmpbr_lbl.s
@@ -0,0 +1,320 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+cmpbr < %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=+cmpbr < %s \
+// RUN:        | llvm-objdump -d --no-print-imm-hex --mattr=+cmpbr - | FileCheck %s --check-prefix=CHECK-DISASS
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+cmpbr < %s \
+// RUN:        | llvm-objdump -d --no-print-imm-hex --mattr=-cmpbr - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+// Label at address 4, so we can test that the address shows up in the
+// disassembly.
+  nop
+
+lbl:
+
+//------------------------------------------------------------------------------
+// Compare & branch (Register)
+//------------------------------------------------------------------------------
+///
+// CB<XX>
+///
+cbgt w5, w5, lbl
+// CHECK-INST: cbgt w5, w5, lbl
+// CHECK-DISASS: cbgt w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0x05,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74050005  <unknown>
+
+cbgt x5, x5, lbl
+// CHECK-INST: cbgt x5, x5, lbl
+// CHECK-DISASS: cbgt x5, x5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0x05,0xf4]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4053fe5
+
+cbge x2, x2, lbl
+// CHECK-INST: cbge x2, x2, lbl
+// CHECK-DISASS: cbge x2, x2, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00010,0b00AAAAAA,0x22,0xf4]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4223fc2
+
+cbge w5, w5, lbl
+// CHECK-INST: cbge w5, w5, lbl
+// CHECK-DISASS: cbge w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0x25,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74253fa5
+
+cbhi w5, w5, lbl
+// CHECK-INST: cbhi w5, w5, lbl
+// CHECK-DISASS: cbhi w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0x45,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74453f85
+
+cbhi x5, x5, lbl
+// CHECK-INST: cbhi x5, x5, lbl
+// CHECK-DISASS: cbhi x5, x5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0x45,0xf4]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4453f65
+
+cbhs x2, x2, lbl
+// CHECK-INST: cbhs x2, x2, lbl
+// CHECK-DISASS: cbhs x2, x2, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00010,0b00AAAAAA,0x62,0xf4]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4623f42
+
+cbhs w5, w5, lbl
+// CHECK-INST: cbhs w5, w5, lbl
+// CHECK-DISASS: cbhs w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0x65,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74653f25
+
+cbeq w5, w5, lbl
+// CHECK-INST: cbeq w5, w5, lbl
+// CHECK-DISASS: cbeq w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0xc5,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74c53f05
+
+cbeq x5, x5, lbl
+// CHECK-INST: cbeq x5, x5, lbl
+// CHECK-DISASS: cbeq x5, x5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0xc5,0xf4]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4c53ee5
+
+cbne x2, x2, lbl
+// CHECK-INST: cbne x2, x2, lbl
+// CHECK-DISASS: cbne x2, x2, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00010,0b00AAAAAA,0xe2,0xf4]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f4e23ec2
+
+cbne w5, w5, lbl
+// CHECK-INST: cbne w5, w5, lbl
+// CHECK-DISASS: cbne w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0xe5,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74e53ea5
+
+///
+// CBH<XX>
+///
+
+cbhgt w5, w5, lbl
+// CHECK-INST: cbhgt w5, w5, lbl
+// CHECK-DISASS: cbhgt w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b11AAAAAA,0x05,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7405fe85
+
+cbhge w5, w5, lbl
+// CHECK-INST: cbhge w5, w5, lbl
+// CHECK-DISASS: cbhge w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b11AAAAAA,0x25,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7425fe65
+
+cbhhi w5, w5, lbl
+// CHECK-INST: cbhhi w5, w5, lbl
+// CHECK-DISASS: cbhhi w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b11AAAAAA,0x45,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7445fe45
+
+cbhhs w5, w5, lbl
+// CHECK-INST: cbhhs w5, w5, lbl
+// CHECK-DISASS: cbhhs w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b11AAAAAA,0x65,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7465fe25
+
+cbheq w5, w5, lbl
+// CHECK-INST: cbheq w5, w5, lbl
+// CHECK-DISASS: cbheq w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b11AAAAAA,0xc5,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74c5fe05
+
+cbhne w5, w5, lbl
+// CHECK-INST: cbhne w5, w5, lbl
+// CHECK-DISASS: cbhne w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b11AAAAAA,0xe5,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74e5fde5
+
+
+///
+// CBB<XX>
+///
+cbbgt w5, w5, lbl
+// CHECK-INST: cbbgt w5, w5, lbl
+// CHECK-DISASS: cbbgt w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x05,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7405bdc5
+
+cbbge w5, w5, lbl
+// CHECK-INST: cbbge w5, w5, lbl
+// CHECK-DISASS: cbbge w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x25,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7425bda5
+
+cbbhi w5, w5, lbl
+// CHECK-INST: cbbhi w5, w5, lbl
+// CHECK-DISASS: cbbhi w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x45,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7445bd85
+
+cbbhs w5, w5, lbl
+// CHECK-INST: cbbhs w5, w5, lbl
+// CHECK-DISASS: cbbhs w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x65,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 7465bd65
+
+cbbeq w5, w5, lbl
+// CHECK-INST: cbbeq w5, w5, lbl
+// CHECK-DISASS: cbbeq w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0xc5,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74c5bd45
+
+cbbne w5, w5, lbl
+// CHECK-INST: cbbne w5, w5, lbl
+// CHECK-DISASS: cbbne w5, w5, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0xe5,0x74]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 74e5bd25
+
+//------------------------------------------------------------------------------
+// Compare & branch (Immediate)
+//------------------------------------------------------------------------------
+
+cbgt w5, #63, lbl
+// CHECK-INST: cbgt w5, #63, lbl
+// CHECK-DISASS: cbgt w5, #63, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x1f,0x75]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 751fbd05
+
+cbgt x5, #0, lbl
+// CHECK-INST: cbgt x5, #0, lbl
+// CHECK-DISASS: cbgt x5, #0, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0x00,0xf5]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f5003ce5
+
+cbhi w5, #31, lbl
+// CHECK-INST: cbhi w5, #31, lbl
+// CHECK-DISASS: cbhi w5, #31, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x4f,0x75]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 754fbcc5
+
+cbhi x5, #31, lbl
+// CHECK-INST: cbhi x5, #31, lbl
+// CHECK-DISASS: cbhi x5, #31, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x4f,0xf5]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f54fbca5
+
+cblt w5, #63, lbl
+// CHECK-INST: cblt w5, #63, lbl
+// CHECK-DISASS: cblt w5, #63, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x3f,0x75]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 753fbc85
+
+cblt x5, #0, lbl
+// CHECK-INST: cblt x5, #0, lbl
+// CHECK-DISASS: cblt x5, #0, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b00AAAAAA,0x20,0xf5]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f5203c65
+
+cblo w5, #31, lbl
+// CHECK-INST: cblo w5, #31, lbl
+// CHECK-DISASS: cblo w5, #31, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x6f,0x75]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 756fbc45
+
+cblo x5, #31, lbl
+// CHECK-INST: cblo x5, #31, lbl
+// CHECK-DISASS: cblo x5, #31, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0x6f,0xf5]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f56fbc25
+
+cbeq w5, #31, lbl
+// CHECK-INST: cbeq w5, #31, lbl
+// CHECK-DISASS: cbeq w5, #31, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0xcf,0x75]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 75cfbc05
+
+cbeq x5, #31, lbl
+// CHECK-INST: cbeq x5, #31, lbl
+// CHECK-DISASS: cbeq x5, #31, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0xcf,0xf5]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f5cfbbe5
+
+cbne w5, #31, lbl
+// CHECK-INST: cbne w5, #31, lbl
+// CHECK-DISASS: cbne w5, #31, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0xef,0x75]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: 75efbbc5
+
+cbne x5, #31, lbl
+// CHECK-INST: cbne x5, #31, lbl
+// CHECK-DISASS: cbne x5, #31, 0x4 <lbl>
+// CHECK-ENCODING: [0bAAA00101,0b10AAAAAA,0xef,0xf5]
+// CHECK-ENCODING: fixup A - offset: 0, value: lbl, kind: fixup_aarch64_pcrel_branch9
+// CHECK-ERROR: instruction requires: cmpbr
+// CHECK-UNKNOWN: f5efbba5
diff --git a/llvm/test/MC/AArch64/directive-arch-negative.s b/llvm/test/MC/AArch64/directive-arch-negative.s
index d037387a2cb77a..19b48ea66bfe6a 100644
--- a/llvm/test/MC/AArch64/directive-arch-negative.s
+++ b/llvm/test/MC/AArch64/directive-arch-negative.s
@@ -56,3 +56,8 @@
 
 # CHECK: error: instruction requires: lse
 # CHECK-NEXT:   casa  w5, w7, [x20]
+
+	.arch arm9.6-a-nocmpbr
+        cbhi x5, x5, #1020
+# CHECK: error: instruction requires: cmpbr
+# CHECK-NEXT:   cbhi x5, x5, #1020
diff --git a/llvm/test/MC/AArch64/directive-arch.s b/llvm/test/MC/AArch64/directive-arch.s
index 32840b4cd14222..8d9c0cef7536d3 100644
--- a/llvm/test/MC/AArch64/directive-arch.s
+++ b/llvm/test/MC/AArch64/directive-arch.s
@@ -21,3 +21,8 @@
 	mrs   x0, rndrrs
 # CHECK:        mrs     x0, RNDR
 # CHECK:        mrs     x0, RNDRRS
+
+	.arch armv9-a+cmpbr
+	cbne x5, #31, lbl
+# CHECK:        cbne x5, #31, lbl
+
diff --git a/llvm/test/MC/AArch64/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/directive-arch_extension-negative.s
index 1843af56555461..363989d7b9b260 100644
--- a/llvm/test/MC/AArch64/directive-arch_extension-negative.s
+++ b/llvm/test/MC/AArch64/directive-arch_extension-negative.s
@@ -1,6 +1,6 @@
 // RUN: not llvm-mc -triple aarch64 \
 // RUN: -mattr=+crc,+sm4,+sha3,+sha2,+aes,+fp,+neon,+ras,+lse,+predres,+ccdp,+mte,+tlb-rmi,+pan-rwv,+ccpp,+rcpc,+ls64,+flagm,+hbc,+mops \
-// RUN: -mattr=+rcpc3,+lse128,+d128,+the,+rasv2,+ite,+cssc,+specres2,+gcs \
+// RUN: -mattr=+rcpc3,+lse128,+d128,+the,+rasv2,+ite,+cssc,+specres2,+gcs,+cmpbr \
 // RUN: -filetype asm -o - %s 2>&1 | FileCheck %s
 
 .arch_extension axp64
@@ -229,3 +229,11 @@ gcspushm x0
 gcspushm x0
 // CHECK: [[@LINE-1]]:1: error: instruction requires: gcs
 // CHECK-NEXT: gcspushm x0
+
+cbhi x5, x5, #1020
+// CHECK-NOT: [[@LINE-1]]:1: error: instruction requires: cmpbr
+.arch_extension nocmpbr
+cbhi x5, x5, #1020
+// CHECK: [[@LINE-1]]:1: error: instruction requires: cmpbr
+// CHECK-NEXT: cbhi x5, x5, #1020
+



More information about the llvm-commits mailing list