[llvm] [AArch64][FEAT_CMPBR] Codegen for Armv9.6-a CBB and CBH (PR #164899)
    David Tellenbach via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Thu Oct 23 14:30:16 PDT 2025
    
    
  
https://github.com/dtellenbach created https://github.com/llvm/llvm-project/pull/164899
This patch adds codegen for CBB and CBH, CB variants operating on bytes and half-words, allowing to fold sign- and zero-extensions.
Since if-conversion needs to be able to undo conditional branches, we remember possibly folded sign- and zero-extensions as additional arguments of the CBB and CBH pseudos during codegen.
>From 93de4a075eea4f1c8c8b33ad3076ba2a48eee805 Mon Sep 17 00:00:00 2001
From: David Tellenbach <dtellenbach at apple.com>
Date: Wed, 22 Oct 2025 18:41:05 -0700
Subject: [PATCH] [AArch64][FEAT_CMPBR] Codegen for Armv9.6-a CBB and CBH
This patch adds codegen for CBB and CBH, CB variants operating on bytes
and half-words, allowing to fold sign- and zero-extensions.
Since if-conversion needs to be able to undo conditional branches, we
remember possibly folded sign- and zero-extensions as additional
arguments of the CBB and CBH pseudos during codegen.
---
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp |  61 +-
 .../Target/AArch64/AArch64ISelDAGToDAG.cpp    |  28 +
 .../lib/Target/AArch64/AArch64InstrFormats.td |  22 +-
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  | 129 ++-
 llvm/lib/Target/AArch64/AArch64InstrInfo.h    |   2 +
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  48 +-
 .../CodeGen/AArch64/cmpbr-early-ifcvt.mir     | 435 +++++++++-
 llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll    | 761 ++++++++++++++++--
 llvm/test/CodeGen/AArch64/cmpbr-zext-sext.ll  | 230 ++++++
 9 files changed, 1577 insertions(+), 139 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/cmpbr-zext-sext.ll
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index c31a090bba77f..ca8ac4c21e4e5 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -2677,23 +2677,32 @@ AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
 
 void AArch64AsmPrinter::emitCBPseudoExpansion(const MachineInstr *MI) {
   bool IsImm = false;
-  bool Is32Bit = false;
+  unsigned Width = 0;
 
   switch (MI->getOpcode()) {
   default:
     llvm_unreachable("This is not a CB pseudo instruction");
+  case AArch64::CBBPrr:
+    IsImm = false;
+    Width = 8;
+    break;
+  case AArch64::CBHPrr:
+    IsImm = false;
+    Width = 16;
+    break;
   case AArch64::CBWPrr:
-    Is32Bit = true;
+    Width = 32;
     break;
   case AArch64::CBXPrr:
-    Is32Bit = false;
+    Width = 64;
     break;
   case AArch64::CBWPri:
     IsImm = true;
-    Is32Bit = true;
+    Width = 32;
     break;
   case AArch64::CBXPri:
     IsImm = true;
+    Width = 64;
     break;
   }
 
@@ -2703,61 +2712,61 @@ void AArch64AsmPrinter::emitCBPseudoExpansion(const MachineInstr *MI) {
   bool NeedsImmDec = false;
   bool NeedsImmInc = false;
 
+#define GET_CB_OPC(IsImm, Width, ImmCond, RegCond)                             \
+  (IsImm                                                                       \
+       ? (Width == 32 ? AArch64::CB##ImmCond##Wri : AArch64::CB##ImmCond##Xri) \
+       : (Width == 8                                                           \
+              ? AArch64::CBB##RegCond##Wrr                                     \
+              : (Width == 16 ? AArch64::CBH##RegCond##Wrr                      \
+                             : (Width == 32 ? AArch64::CB##RegCond##Wrr        \
+                                            : AArch64::CB##RegCond##Xrr))))
+  unsigned MCOpC;
+
   // Decide if we need to either swap register operands or increment/decrement
   // immediate operands
-  unsigned MCOpC;
   switch (CC) {
   default:
     llvm_unreachable("Invalid CB condition code");
   case AArch64CC::EQ:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBEQWri : AArch64::CBEQXri)
-                  : (Is32Bit ? AArch64::CBEQWrr : AArch64::CBEQXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ EQ, /* Reg-Reg */ EQ);
     break;
   case AArch64CC::NE:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBNEWri : AArch64::CBNEXri)
-                  : (Is32Bit ? AArch64::CBNEWrr : AArch64::CBNEXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ NE, /* Reg-Reg */ NE);
     break;
   case AArch64CC::HS:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
-                  : (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ HI, /* Reg-Reg */ HS);
     NeedsImmDec = IsImm;
     break;
   case AArch64CC::LO:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
-                  : (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ LO, /* Reg-Reg */ HI);
     NeedsRegSwap = !IsImm;
     break;
   case AArch64CC::HI:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
-                  : (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ HI, /* Reg-Reg */ HI);
     break;
   case AArch64CC::LS:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
-                  : (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ LO, /* Reg-Reg */ HS);
     NeedsRegSwap = !IsImm;
     NeedsImmInc = IsImm;
     break;
   case AArch64CC::GE:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
-                  : (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ GT, /* Reg-Reg */ GE);
     NeedsImmDec = IsImm;
     break;
   case AArch64CC::LT:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
-                  : (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ LT, /* Reg-Reg */ GT);
     NeedsRegSwap = !IsImm;
     break;
   case AArch64CC::GT:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
-                  : (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ GT, /* Reg-Reg */ GT);
     break;
   case AArch64CC::LE:
-    MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
-                  : (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
+    MCOpC = GET_CB_OPC(IsImm, Width, /* Reg-Imm */ LT, /* Reg-Reg */ GE);
     NeedsRegSwap = !IsImm;
     NeedsImmInc = IsImm;
     break;
   }
+#undef GET_CB_OPC
 
   MCInst Inst;
   Inst.setOpcode(MCOpC);
@@ -3422,6 +3431,8 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
   }
   case AArch64::CBWPri:
   case AArch64::CBXPri:
+  case AArch64::CBBPrr:
+  case AArch64::CBHPrr:
   case AArch64::CBWPrr:
   case AArch64::CBXPrr:
     emitCBPseudoExpansion(MI);
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index e7b2d20e2a6cb..56ab4fa7364b8 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -513,6 +513,9 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
   bool SelectAnyPredicate(SDValue N);
 
   bool SelectCmpBranchUImm6Operand(SDNode *P, SDValue N, SDValue &Imm);
+
+  template <bool MatchCBB>
+  bool SelectCmpBranchExtOperand(SDValue N, SDValue &Reg, SDValue &ExtType);
 };
 
 class AArch64DAGToDAGISelLegacy : public SelectionDAGISelLegacy {
@@ -7697,3 +7700,28 @@ bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *P, SDValue N,
 
   return false;
 }
+
+template <bool MatchCBB>
+bool AArch64DAGToDAGISel::SelectCmpBranchExtOperand(SDValue N, SDValue &Reg,
+                                                    SDValue &ExtType) {
+
+  // Use an invalid shift-extend value to indicate we don't need to extend later
+  if (N.getOpcode() == ISD::AssertZext || N.getOpcode() == ISD::AssertSext) {
+    Reg = N.getOperand(0);
+    ExtType = CurDAG->getSignedTargetConstant(AArch64_AM::InvalidShiftExtend,
+                                              SDLoc(N), MVT::i32);
+    return true;
+  }
+
+  AArch64_AM::ShiftExtendType ET = getExtendTypeForNode(N);
+
+  if ((MatchCBB && (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB)) ||
+      (!MatchCBB && (ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH))) {
+    Reg = N.getOperand(0);
+    ExtType =
+        CurDAG->getTargetConstant(getExtendEncoding(ET), SDLoc(N), MVT::i32);
+    return true;
+  }
+
+  return false;
+}
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 09ce713ea862c..941df069ec3e1 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -415,6 +415,12 @@ def CmpBranchUImm6Operand_64b
   let WantsParent = true;
 }
 
+def CmpBranchBExtOperand
+    : ComplexPattern<i32, 2, "SelectCmpBranchExtOperand<true>", []> {}
+
+def CmpBranchHExtOperand
+    : ComplexPattern<i32, 2, "SelectCmpBranchExtOperand<false>", []> {}
+
 def UImm6Plus1Operand : AsmOperandClass {
   let Name = "UImm6P1";
   let DiagnosticType = "InvalidImm1_64";
@@ -13118,8 +13124,20 @@ multiclass CmpBranchRegisterAlias<string mnemonic, string insn> {
 }
 
 class CmpBranchRegisterPseudo<RegisterClass regtype>
-  : Pseudo<(outs), (ins ccode:$Cond, regtype:$Rt, regtype:$Rm, am_brcmpcond:$Target), []>,
-    Sched<[WriteBr]> {
+    : Pseudo<(outs),
+             (ins ccode:$Cond, regtype:$Rt, regtype:$Rm, am_brcmpcond:$Target),
+             []>,
+      Sched<[WriteBr]> {
+  let isBranch = 1;
+  let isTerminator = 1;
+}
+
+class CmpBranchExtRegisterPseudo
+    : Pseudo<(outs),
+             (ins ccode:$Cond, GPR32:$Rt, GPR32:$Rm, am_brcmpcond:$Target,
+                 simm8_32b:$ExtRt, simm8_32b:$ExtRm),
+             []>,
+      Sched<[WriteBr]> {
   let isBranch = 1;
   let isTerminator = 1;
 }
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index d5117da524231..5cd66098826fa 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -241,6 +241,17 @@ static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
     Cond.push_back(LastInst->getOperand(1));
     Cond.push_back(LastInst->getOperand(2));
     break;
+  case AArch64::CBBPrr:
+  case AArch64::CBHPrr:
+    Target = LastInst->getOperand(3).getMBB();
+    Cond.push_back(MachineOperand::CreateImm(-1));                    // -1
+    Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); // Opc
+    Cond.push_back(LastInst->getOperand(0));                          // Cond
+    Cond.push_back(LastInst->getOperand(1));                          // Op0
+    Cond.push_back(LastInst->getOperand(2));                          // Op1
+    Cond.push_back(LastInst->getOperand(4));                          // Ext0
+    Cond.push_back(LastInst->getOperand(5));                          // Ext1
+    break;
   }
 }
 
@@ -264,6 +275,8 @@ static unsigned getBranchDisplacementBits(unsigned Opc) {
     return BCCDisplacementBits;
   case AArch64::CBWPri:
   case AArch64::CBXPri:
+  case AArch64::CBBPrr:
+  case AArch64::CBHPrr:
   case AArch64::CBWPrr:
   case AArch64::CBXPrr:
     return CBDisplacementBits;
@@ -298,6 +311,8 @@ AArch64InstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
     return MI.getOperand(1).getMBB();
   case AArch64::CBWPri:
   case AArch64::CBXPri:
+  case AArch64::CBBPrr:
+  case AArch64::CBHPrr:
   case AArch64::CBWPrr:
   case AArch64::CBXPrr:
     return MI.getOperand(3).getMBB();
@@ -580,9 +595,11 @@ bool AArch64InstrInfo::reverseBranchCondition(
       Cond[1].setImm(AArch64::TBZX);
       break;
 
-    // Cond is { -1, Opcode, CC, Op0, Op1 }
+    // Cond is { -1, Opcode, CC, Op0, Op1, ... }
     case AArch64::CBWPri:
     case AArch64::CBXPri:
+    case AArch64::CBBPrr:
+    case AArch64::CBHPrr:
     case AArch64::CBWPrr:
     case AArch64::CBXPrr: {
       // Pseudos using standard 4bit Arm condition codes
@@ -654,6 +671,12 @@ void AArch64InstrInfo::instantiateCondBranch(
       MIB.add(Cond[4]);
 
     MIB.addMBB(TBB);
+
+    // cb[b,h]
+    if (Cond.size() > 5) {
+      MIB.addImm(Cond[5].getImm());
+      MIB.addImm(Cond[6].getImm());
+    }
   }
 }
 
@@ -931,44 +954,122 @@ void AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB,
     // We must insert a cmp, that is a subs
     //            0       1   2    3    4
     // Cond is { -1, Opcode, CC, Op0, Op1 }
-    unsigned SUBSOpC, SUBSDestReg;
+
+    unsigned SubsOpc, SubsDestReg;
     bool IsImm = false;
     CC = static_cast<AArch64CC::CondCode>(Cond[2].getImm());
     switch (Cond[1].getImm()) {
     default:
       llvm_unreachable("Unknown branch opcode in Cond");
     case AArch64::CBWPri:
-      SUBSOpC = AArch64::SUBSWri;
-      SUBSDestReg = AArch64::WZR;
+      SubsOpc = AArch64::SUBSWri;
+      SubsDestReg = AArch64::WZR;
       IsImm = true;
       break;
     case AArch64::CBXPri:
-      SUBSOpC = AArch64::SUBSXri;
-      SUBSDestReg = AArch64::XZR;
+      SubsOpc = AArch64::SUBSXri;
+      SubsDestReg = AArch64::XZR;
       IsImm = true;
       break;
     case AArch64::CBWPrr:
-      SUBSOpC = AArch64::SUBSWrr;
-      SUBSDestReg = AArch64::WZR;
+      SubsOpc = AArch64::SUBSWrr;
+      SubsDestReg = AArch64::WZR;
       IsImm = false;
       break;
     case AArch64::CBXPrr:
-      SUBSOpC = AArch64::SUBSXrr;
-      SUBSDestReg = AArch64::XZR;
+      SubsOpc = AArch64::SUBSXrr;
+      SubsDestReg = AArch64::XZR;
       IsImm = false;
       break;
     }
 
     if (IsImm)
-      BuildMI(MBB, I, DL, get(SUBSOpC), SUBSDestReg)
+      BuildMI(MBB, I, DL, get(SubsOpc), SubsDestReg)
           .addReg(Cond[3].getReg())
           .addImm(Cond[4].getImm())
           .addImm(0);
     else
-      BuildMI(MBB, I, DL, get(SUBSOpC), SUBSDestReg)
+      BuildMI(MBB, I, DL, get(SubsOpc), SubsDestReg)
           .addReg(Cond[3].getReg())
           .addReg(Cond[4].getReg());
-  }
+  } break;
+  case 7: { // cb[b,h]
+    // We must insert a cmp, that is a subs, but also zero- or sign-extensions
+    // that have been folded. For the first operand we codegen an explicit
+    // extension, for the second operand we fold the extension into cmp.
+    //            0       1   2    3    4    5      6
+    // Cond is { -1, Opcode, CC, Op0, Op1, Ext0, Ext1 }
+
+    // We need a new register for the now explicitly extended register
+    Register Reg = Cond[4].getReg();
+    if (Cond[5].getImm() != AArch64_AM::InvalidShiftExtend) {
+      unsigned ExtOpc;
+      unsigned ExtBits;
+      AArch64_AM::ShiftExtendType ExtendType =
+          AArch64_AM::getExtendType(Cond[5].getImm());
+      switch (ExtendType) {
+      default:
+        llvm_unreachable("Unkown shift-extend for CB instruction");
+      case AArch64_AM::SXTB:
+        assert(
+            Cond[1].getImm() == AArch64::CBBPrr &&
+            "Unexpected compare-and-branch instruction for SXTB shift-extend");
+        ExtOpc = AArch64::SBFMWri;
+        ExtBits = AArch64_AM::encodeLogicalImmediate(0xff, 32);
+        break;
+      case AArch64_AM::SXTH:
+        assert(
+            Cond[1].getImm() == AArch64::CBHPrr &&
+            "Unexpected compare-and-branch instruction for SXTH shift-extend");
+        ExtOpc = AArch64::SBFMWri;
+        ExtBits = AArch64_AM::encodeLogicalImmediate(0xffff, 32);
+        break;
+      case AArch64_AM::UXTB:
+        assert(
+            Cond[1].getImm() == AArch64::CBBPrr &&
+            "Unexpected compare-and-branch instruction for UXTB shift-extend");
+        ExtOpc = AArch64::ANDWri;
+        ExtBits = AArch64_AM::encodeLogicalImmediate(0xff, 32);
+        break;
+      case AArch64_AM::UXTH:
+        assert(
+            Cond[1].getImm() == AArch64::CBHPrr &&
+            "Unexpected compare-and-branch instruction for UXTH shift-extend");
+        ExtOpc = AArch64::ANDWri;
+        ExtBits = AArch64_AM::encodeLogicalImmediate(0xffff, 32);
+        break;
+      }
+
+      // Build the explicit extension of the first operand
+      Reg = MRI.createVirtualRegister(&AArch64::GPR32spRegClass);
+      MachineInstrBuilder MBBI =
+          BuildMI(MBB, I, DL, get(ExtOpc), Reg).addReg(Cond[4].getReg());
+      if (ExtOpc != AArch64::ANDWri)
+        MBBI.addImm(0);
+      MBBI.addImm(ExtBits);
+    }
+
+    // Now, subs with an extended second operand
+    if (Cond[6].getImm() != AArch64_AM::InvalidShiftExtend) {
+      AArch64_AM::ShiftExtendType ExtendType =
+          AArch64_AM::getExtendType(Cond[6].getImm());
+      MRI.constrainRegClass(Reg, MRI.getRegClass(Cond[3].getReg()));
+      MRI.constrainRegClass(Cond[3].getReg(), &AArch64::GPR32spRegClass);
+      BuildMI(MBB, I, DL, get(AArch64::SUBSWrx), AArch64::WZR)
+          .addReg(Cond[3].getReg())
+          .addReg(Reg)
+          .addImm(ExtendType);
+    } // If no extension is needed, just a regular subs
+    else {
+      MRI.constrainRegClass(Reg, MRI.getRegClass(Cond[3].getReg()));
+      MRI.constrainRegClass(Cond[3].getReg(), &AArch64::GPR32spRegClass);
+      BuildMI(MBB, I, DL, get(AArch64::SUBSWrr), AArch64::WZR)
+          .addReg(Cond[3].getReg())
+          .addReg(Reg);
+    }
+
+    CC = static_cast<AArch64CC::CondCode>(Cond[2].getImm());
+  } break;
   }
 
   unsigned Opc = 0;
@@ -9251,6 +9352,8 @@ bool AArch64InstrInfo::optimizeCondBranch(MachineInstr &MI) const {
   case AArch64::Bcc:
   case AArch64::CBWPri:
   case AArch64::CBXPri:
+  case AArch64::CBBPrr:
+  case AArch64::CBHPrr:
   case AArch64::CBWPrr:
   case AArch64::CBXPrr:
     return false;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 179574a73aa01..13d022a288a83 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -712,6 +712,8 @@ static inline bool isCondBranchOpcode(int Opc) {
   case AArch64::TBNZX:
   case AArch64::CBWPri:
   case AArch64::CBXPri:
+  case AArch64::CBBPrr:
+  case AArch64::CBHPrr:
   case AArch64::CBWPrr:
   case AArch64::CBXPrr:
     return true;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 92f260f408674..7abf359a3ac8c 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -11152,23 +11152,37 @@ let Predicates = [HasCMPBR] in {
  defm : CmpBranchWRegisterAlias<"cbhlt", "CBHGT">;
 
   // Pseudos for codegen
-  def CBWPrr : CmpBranchRegisterPseudo<GPR32>;
-  def CBXPrr : CmpBranchRegisterPseudo<GPR64>;
-  def CBWPri : CmpBranchImmediatePseudo<GPR32, uimm6_32b>;
-  def CBXPri : CmpBranchImmediatePseudo<GPR64, uimm6_64b>;
-
-  def : Pat<(AArch64CB i32:$Cond, GPR32:$Rn, CmpBranchUImm6Operand_32b:$Imm,
-                bb:$Target),
-            (CBWPri i32:$Cond, GPR32:$Rn, uimm6_32b:$Imm,
-                am_brcmpcond:$Target)>;
-  def : Pat<(AArch64CB i32:$Cond, GPR64:$Rn, CmpBranchUImm6Operand_64b:$Imm,
-                bb:$Target),
-            (CBXPri i32:$Cond, GPR64:$Rn, uimm6_64b:$Imm,
-                am_brcmpcond:$Target)>;
-  def : Pat<(AArch64CB i32:$Cond, GPR32:$Rn, GPR32:$Rt, bb:$Target),
-            (CBWPrr ccode:$Cond, GPR32:$Rn, GPR32:$Rt, am_brcmpcond:$Target)>;
-  def : Pat<(AArch64CB i32:$Cond, GPR64:$Rn, GPR64:$Rt, bb:$Target),
-            (CBXPrr ccode:$Cond, GPR64:$Rn, GPR64:$Rt, am_brcmpcond:$Target)>;
+ def CBBPrr : CmpBranchExtRegisterPseudo;
+ def CBHPrr : CmpBranchExtRegisterPseudo;
+ def CBWPrr : CmpBranchRegisterPseudo<GPR32>;
+ def CBXPrr : CmpBranchRegisterPseudo<GPR64>;
+ def CBWPri : CmpBranchImmediatePseudo<GPR32, uimm6_32b>;
+ def CBXPri : CmpBranchImmediatePseudo<GPR64, uimm6_64b>;
+
+ def : Pat<(AArch64CB i32:$Cond, GPR32:$Rn, CmpBranchUImm6Operand_32b:$Imm,
+               bb:$Target),
+           (CBWPri i32:$Cond, GPR32:$Rn, uimm6_32b:$Imm, am_brcmpcond:$Target)>;
+ def : Pat<(AArch64CB i32:$Cond, GPR64:$Rn, CmpBranchUImm6Operand_64b:$Imm,
+               bb:$Target),
+           (CBXPri i32:$Cond, GPR64:$Rn, uimm6_64b:$Imm, am_brcmpcond:$Target)>;
+ def : Pat<(AArch64CB i32:$Cond, GPR32:$Rn, GPR32:$Rt, bb:$Target),
+           (CBWPrr ccode:$Cond, GPR32:$Rn, GPR32:$Rt, am_brcmpcond:$Target)>;
+ def : Pat<(AArch64CB i32:$Cond, GPR64:$Rn, GPR64:$Rt, bb:$Target),
+           (CBXPrr ccode:$Cond, GPR64:$Rn, GPR64:$Rt, am_brcmpcond:$Target)>;
+
+ def : Pat<(AArch64CB i32:$Cond,
+               (CmpBranchBExtOperand GPR32:$Rn, simm8_32b:$ExtTypeRn),
+               (CmpBranchBExtOperand GPR32:$Rt, simm8_32b:$ExtTypeRt),
+               bb:$Target),
+           (CBBPrr ccode:$Cond, GPR32:$Rn, GPR32:$Rt, bb:$Target,
+               simm8_32b:$ExtTypeRn, simm8_32b:$ExtTypeRt)>;
+
+ def : Pat<(AArch64CB i32:$Cond,
+               (CmpBranchHExtOperand GPR32:$Rn, simm8_32b:$ExtTypeRn),
+               (CmpBranchHExtOperand GPR32:$Rt, simm8_32b:$ExtTypeRt),
+               bb:$Target),
+           (CBHPrr ccode:$Cond, GPR32:$Rn, GPR32:$Rt, bb:$Target,
+               simm8_32b:$ExtTypeRn, simm8_32b:$ExtTypeRt)>;
 } // HasCMPBR
 
 
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir b/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
index c3377164f357e..fc6a2a55d4bfd 100644
--- a/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
+++ b/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
@@ -1,6 +1,5 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -mtriple=arm64-apple-ios -mattr +cmpbr -run-pass=early-ifcvt -simplify-mir -o - %s | FileCheck %s
-# CHECK: cb_diamond
+# RUN: llc -mtriple=arm64-apple-ios -mattr +cmpbr -run-pass=early-ifcvt -verify-machineinstrs -simplify-mir -o - %s | FileCheck %s
 ---
 name:            cb_diamond
 alignment:       4
@@ -114,3 +113,435 @@ body:             |
     $x0 = COPY %4
     RET_ReallyLR implicit $x0
 ...
+---
+name:            cbb_diamond_no_ext
+alignment:       4
+tracksRegLiveness: true
+noPhis:          false
+isSSA:           true
+noVRegs:         false
+hasFakeUses:     false
+registers:
+  - { id: 0, class: gpr32 }
+  - { id: 1, class: gpr32 }
+  - { id: 2, class: gpr32 }
+  - { id: 3, class: gpr32 }
+  - { id: 4, class: gpr32 }
+  - { id: 5, class: gpr32 }
+liveins:
+  - { reg: '$w0', virtual-reg: '%0' }
+  - { reg: '$w1', virtual-reg: '%1' }
+frameInfo:
+  maxAlignment:    1
+  maxCallFrameSize: 0
+machineFunctionInfo: {}
+body:             |
+  ; CHECK-LABEL: name: cbb_diamond_no_ext
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   [[MADDWrrr:%[0-9]+]]:gpr32 = MADDWrrr [[COPY]], [[COPY1]], $wzr
+  ; CHECK-NEXT:   $wzr = SUBSWrr [[COPY]], [[COPY1]], implicit-def $nzcv
+  ; CHECK-NEXT:   [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[ADDWrr]], [[MADDWrrr]], 11, implicit $nzcv
+  ; CHECK-NEXT:   [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr killed [[CSELWr]], [[COPY]]
+  ; CHECK-NEXT:   $w0 = COPY [[ADDWrr1]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+  bb.0:
+    successors: %bb.1, %bb.2
+    liveins: $w0, $w1
+
+    %0:gpr32 = COPY $w0
+    %1:gpr32 = COPY $w1
+    CBBPrr 11, %0, %1, %bb.1, -1, -1
+    B %bb.2
+
+  bb.1:
+    successors: %bb.3
+    %2:gpr32 = ADDWrr %0, %1
+    B %bb.3
+
+  bb.2:
+    successors: %bb.3
+    %3:gpr32 = MADDWrrr %0, %1, $wzr
+    B %bb.3
+
+  bb.3:
+    %4:gpr32 = PHI %2, %bb.1, %3, %bb.2
+    %5:gpr32 = ADDWrr killed %4, %0
+    $w0 = COPY %5
+    RET_ReallyLR implicit $w0
+...
+---
+name:            cbb_diamond_zext
+alignment:       4
+tracksRegLiveness: true
+noPhis:          false
+isSSA:           true
+noVRegs:         false
+hasFakeUses:     false
+registers:
+  - { id: 0, class: gpr32 }
+  - { id: 1, class: gpr32 }
+  - { id: 2, class: gpr32 }
+  - { id: 3, class: gpr32 }
+  - { id: 4, class: gpr32 }
+  - { id: 5, class: gpr32 }
+liveins:
+  - { reg: '$w0', virtual-reg: '%0' }
+  - { reg: '$w1', virtual-reg: '%1' }
+frameInfo:
+  maxAlignment:    1
+  maxCallFrameSize: 0
+machineFunctionInfo: {}
+body:             |
+  ; CHECK-LABEL: name: cbb_diamond_zext
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   [[MADDWrrr:%[0-9]+]]:gpr32 = MADDWrrr [[COPY]], [[COPY1]], $wzr
+  ; CHECK-NEXT:   [[ANDWri:%[0-9]+]]:gpr32common = ANDWri [[COPY1]], 7
+  ; CHECK-NEXT:   $wzr = SUBSWrx [[COPY]], [[ANDWri]], 5, implicit-def $nzcv
+  ; CHECK-NEXT:   [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[ADDWrr]], [[MADDWrrr]], 11, implicit $nzcv
+  ; CHECK-NEXT:   [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr killed [[CSELWr]], [[COPY]]
+  ; CHECK-NEXT:   $w0 = COPY [[ADDWrr1]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+  bb.0:
+    successors: %bb.1, %bb.2
+    liveins: $w0, $w1
+
+    %0:gpr32 = COPY $w0
+    %1:gpr32 = COPY $w1
+    CBBPrr 11, %0, %1, %bb.1, 0, 0
+    B %bb.2
+
+  bb.1:
+    successors: %bb.3
+    %2:gpr32 = ADDWrr %0, %1
+    B %bb.3
+
+  bb.2:
+    successors: %bb.3
+    %3:gpr32 = MADDWrrr %0, %1, $wzr
+    B %bb.3
+
+  bb.3:
+    %4:gpr32 = PHI %2, %bb.1, %3, %bb.2
+    %5:gpr32 = ADDWrr killed %4, %0
+    $w0 = COPY %5
+    RET_ReallyLR implicit $w0
+...
+---
+name:            cbb_diamond_sext
+alignment:       4
+tracksRegLiveness: true
+noPhis:          false
+isSSA:           true
+noVRegs:         false
+hasFakeUses:     false
+registers:
+  - { id: 0, class: gpr32 }
+  - { id: 1, class: gpr32 }
+  - { id: 2, class: gpr32 }
+  - { id: 3, class: gpr32 }
+  - { id: 4, class: gpr32 }
+  - { id: 5, class: gpr32 }
+liveins:
+  - { reg: '$w0', virtual-reg: '%0' }
+  - { reg: '$w1', virtual-reg: '%1' }
+frameInfo:
+  maxAlignment:    1
+  maxCallFrameSize: 0
+machineFunctionInfo: {}
+body:             |
+  ; CHECK-LABEL: name: cbb_diamond_sext
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   [[MADDWrrr:%[0-9]+]]:gpr32 = MADDWrrr [[COPY]], [[COPY1]], $wzr
+  ; CHECK-NEXT:   [[SBFMWri:%[0-9]+]]:gpr32common = SBFMWri [[COPY1]], 0, 7
+  ; CHECK-NEXT:   $wzr = SUBSWrx [[COPY]], [[SBFMWri]], 9, implicit-def $nzcv
+  ; CHECK-NEXT:   [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[ADDWrr]], [[MADDWrrr]], 11, implicit $nzcv
+  ; CHECK-NEXT:   [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr killed [[CSELWr]], [[COPY]]
+  ; CHECK-NEXT:   $w0 = COPY [[ADDWrr1]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+  bb.0:
+    successors: %bb.1, %bb.2
+    liveins: $w0, $w1
+
+    %0:gpr32 = COPY $w0
+    %1:gpr32 = COPY $w1
+    CBBPrr 11, %0, %1, %bb.1, 4, 4
+    B %bb.2
+
+  bb.1:
+    successors: %bb.3
+    %2:gpr32 = ADDWrr %0, %1
+    B %bb.3
+
+  bb.2:
+    successors: %bb.3
+    %3:gpr32 = MADDWrrr %0, %1, $wzr
+    B %bb.3
+
+  bb.3:
+    %4:gpr32 = PHI %2, %bb.1, %3, %bb.2
+    %5:gpr32 = ADDWrr killed %4, %0
+    $w0 = COPY %5
+    RET_ReallyLR implicit $w0
+...
+---
+name:            cbh_diamond_zext
+alignment:       4
+tracksRegLiveness: true
+noPhis:          false
+isSSA:           true
+noVRegs:         false
+hasFakeUses:     false
+registers:
+  - { id: 0, class: gpr32 }
+  - { id: 1, class: gpr32 }
+  - { id: 2, class: gpr32 }
+  - { id: 3, class: gpr32 }
+  - { id: 4, class: gpr32 }
+  - { id: 5, class: gpr32 }
+liveins:
+  - { reg: '$w0', virtual-reg: '%0' }
+  - { reg: '$w1', virtual-reg: '%1' }
+frameInfo:
+  maxAlignment:    1
+  maxCallFrameSize: 0
+machineFunctionInfo: {}
+body:             |
+  ; CHECK-LABEL: name: cbh_diamond_zext
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   [[MADDWrrr:%[0-9]+]]:gpr32 = MADDWrrr [[COPY]], [[COPY1]], $wzr
+  ; CHECK-NEXT:   [[ANDWri:%[0-9]+]]:gpr32common = ANDWri [[COPY1]], 15
+  ; CHECK-NEXT:   $wzr = SUBSWrx [[COPY]], [[ANDWri]], 6, implicit-def $nzcv
+  ; CHECK-NEXT:   [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[ADDWrr]], [[MADDWrrr]], 11, implicit $nzcv
+  ; CHECK-NEXT:   [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr killed [[CSELWr]], [[COPY]]
+  ; CHECK-NEXT:   $w0 = COPY [[ADDWrr1]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+  bb.0:
+    successors: %bb.1, %bb.2
+    liveins: $w0, $w1
+
+    %0:gpr32 = COPY $w0
+    %1:gpr32 = COPY $w1
+    CBHPrr 11, %0, %1, %bb.1, 1, 1
+    B %bb.2
+
+  bb.1:
+    successors: %bb.3
+    %2:gpr32 = ADDWrr %0, %1
+    B %bb.3
+
+  bb.2:
+    successors: %bb.3
+    %3:gpr32 = MADDWrrr %0, %1, $wzr
+    B %bb.3
+
+  bb.3:
+    %4:gpr32 = PHI %2, %bb.1, %3, %bb.2
+    %5:gpr32 = ADDWrr killed %4, %0
+    $w0 = COPY %5
+    RET_ReallyLR implicit $w0
+...
+---
+name:            cbh_diamond_sext
+alignment:       4
+tracksRegLiveness: true
+noPhis:          false
+isSSA:           true
+noVRegs:         false
+hasFakeUses:     false
+registers:
+  - { id: 0, class: gpr32 }
+  - { id: 1, class: gpr32 }
+  - { id: 2, class: gpr32 }
+  - { id: 3, class: gpr32 }
+  - { id: 4, class: gpr32 }
+  - { id: 5, class: gpr32 }
+liveins:
+  - { reg: '$w0', virtual-reg: '%0' }
+  - { reg: '$w1', virtual-reg: '%1' }
+frameInfo:
+  maxAlignment:    1
+  maxCallFrameSize: 0
+machineFunctionInfo: {}
+body:             |
+  ; CHECK-LABEL: name: cbh_diamond_sext
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   [[MADDWrrr:%[0-9]+]]:gpr32 = MADDWrrr [[COPY]], [[COPY1]], $wzr
+  ; CHECK-NEXT:   [[SBFMWri:%[0-9]+]]:gpr32common = SBFMWri [[COPY1]], 0, 15
+  ; CHECK-NEXT:   $wzr = SUBSWrx [[COPY]], [[SBFMWri]], 10, implicit-def $nzcv
+  ; CHECK-NEXT:   [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[ADDWrr]], [[MADDWrrr]], 11, implicit $nzcv
+  ; CHECK-NEXT:   [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr killed [[CSELWr]], [[COPY]]
+  ; CHECK-NEXT:   $w0 = COPY [[ADDWrr1]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+  bb.0:
+    successors: %bb.1, %bb.2
+    liveins: $w0, $w1
+
+    %0:gpr32 = COPY $w0
+    %1:gpr32 = COPY $w1
+    CBHPrr 11, %0, %1, %bb.1, 5, 5
+    B %bb.2
+
+  bb.1:
+    successors: %bb.3
+    %2:gpr32 = ADDWrr %0, %1
+    B %bb.3
+
+  bb.2:
+    successors: %bb.3
+    %3:gpr32 = MADDWrrr %0, %1, $wzr
+    B %bb.3
+
+  bb.3:
+    %4:gpr32 = PHI %2, %bb.1, %3, %bb.2
+    %5:gpr32 = ADDWrr killed %4, %0
+    $w0 = COPY %5
+    RET_ReallyLR implicit $w0
+...
+---
+name:            cbh_diamond_lhs_sext
+alignment:       4
+tracksRegLiveness: true
+noPhis:          false
+isSSA:           true
+noVRegs:         false
+hasFakeUses:     false
+registers:
+  - { id: 0, class: gpr32 }
+  - { id: 1, class: gpr32 }
+  - { id: 2, class: gpr32 }
+  - { id: 3, class: gpr32 }
+  - { id: 4, class: gpr32 }
+  - { id: 5, class: gpr32 }
+liveins:
+  - { reg: '$w0', virtual-reg: '%0' }
+  - { reg: '$w1', virtual-reg: '%1' }
+frameInfo:
+  maxAlignment:    1
+  maxCallFrameSize: 0
+machineFunctionInfo: {}
+body:             |
+  ; CHECK-LABEL: name: cbh_diamond_lhs_sext
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   [[MADDWrrr:%[0-9]+]]:gpr32 = MADDWrrr [[COPY]], [[COPY1]], $wzr
+  ; CHECK-NEXT:   [[SBFMWri:%[0-9]+]]:gpr32common = SBFMWri [[COPY1]], 0, 15
+  ; CHECK-NEXT:   $wzr = SUBSWrr [[COPY]], [[SBFMWri]], implicit-def $nzcv
+  ; CHECK-NEXT:   [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[ADDWrr]], [[MADDWrrr]], 11, implicit $nzcv
+  ; CHECK-NEXT:   [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr killed [[CSELWr]], [[COPY]]
+  ; CHECK-NEXT:   $w0 = COPY [[ADDWrr1]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+  bb.0:
+    successors: %bb.1, %bb.2
+    liveins: $w0, $w1
+
+    %0:gpr32 = COPY $w0
+    %1:gpr32 = COPY $w1
+    CBHPrr 11, %0, %1, %bb.1, 5, -1
+    B %bb.2
+
+  bb.1:
+    successors: %bb.3
+    %2:gpr32 = ADDWrr %0, %1
+    B %bb.3
+
+  bb.2:
+    successors: %bb.3
+    %3:gpr32 = MADDWrrr %0, %1, $wzr
+    B %bb.3
+
+  bb.3:
+    %4:gpr32 = PHI %2, %bb.1, %3, %bb.2
+    %5:gpr32 = ADDWrr killed %4, %0
+    $w0 = COPY %5
+    RET_ReallyLR implicit $w0
+...
+---
+name:            cbh_diamond_rhs_sext
+alignment:       4
+tracksRegLiveness: true
+noPhis:          false
+isSSA:           true
+noVRegs:         false
+hasFakeUses:     false
+registers:
+  - { id: 0, class: gpr32 }
+  - { id: 1, class: gpr32 }
+  - { id: 2, class: gpr32 }
+  - { id: 3, class: gpr32 }
+  - { id: 4, class: gpr32 }
+  - { id: 5, class: gpr32 }
+liveins:
+  - { reg: '$w0', virtual-reg: '%0' }
+  - { reg: '$w1', virtual-reg: '%1' }
+frameInfo:
+  maxAlignment:    1
+  maxCallFrameSize: 0
+machineFunctionInfo: {}
+body:             |
+  ; CHECK-LABEL: name: cbh_diamond_rhs_sext
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   [[MADDWrrr:%[0-9]+]]:gpr32 = MADDWrrr [[COPY]], [[COPY1]], $wzr
+  ; CHECK-NEXT:   $wzr = SUBSWrx [[COPY]], [[COPY1]], 10, implicit-def $nzcv
+  ; CHECK-NEXT:   [[CSELWr:%[0-9]+]]:gpr32 = CSELWr [[ADDWrr]], [[MADDWrrr]], 11, implicit $nzcv
+  ; CHECK-NEXT:   [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr killed [[CSELWr]], [[COPY]]
+  ; CHECK-NEXT:   $w0 = COPY [[ADDWrr1]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+  bb.0:
+    successors: %bb.1, %bb.2
+    liveins: $w0, $w1
+
+    %0:gpr32 = COPY $w0
+    %1:gpr32 = COPY $w1
+    CBHPrr 11, %0, %1, %bb.1, -1, 5
+    B %bb.2
+
+  bb.1:
+    successors: %bb.3
+    %2:gpr32 = ADDWrr %0, %1
+    B %bb.3
+
+  bb.2:
+    successors: %bb.3
+    %3:gpr32 = MADDWrrr %0, %1, $wzr
+    B %bb.3
+
+  bb.3:
+    %4:gpr32 = PHI %2, %bb.1, %3, %bb.2
+    %5:gpr32 = ADDWrr killed %4, %0
+    $w0 = COPY %5
+    RET_ReallyLR implicit $w0
+...
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll b/llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll
index 9e95434564f02..f520456235147 100644
--- a/llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll
+++ b/llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll
@@ -2,23 +2,624 @@
 ; RUN: llc -mtriple arm64-apple-ios -mattr +cmpbr -verify-machineinstrs -o - < %s | FileCheck %s --check-prefix=CHECK-CMPBR
 ; RUN: llc -mtriple arm64-apple-ios -mattr -cmpbr -verify-machineinstrs -o - < %s | FileCheck %s --check-prefix=CHECK-NO-CMPBR
 
+define void @cbgt_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cbgt_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbgt w0, w1, LBB0_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB0_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbgt_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    sxtb w8, w0
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, sxtb
+; CHECK-NO-CMPBR-NEXT:    b.gt LBB0_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB0_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp sgt i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbge_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cbge_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbge w0, w1, LBB1_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB1_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbge_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    sxtb w8, w0
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, sxtb
+; CHECK-NO-CMPBR-NEXT:    b.ge LBB1_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB1_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp sge i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+
+define void @cbhi_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cbhi_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbhi w0, w1, LBB2_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB2_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbhi_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxtb
+; CHECK-NO-CMPBR-NEXT:    b.hi LBB2_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB2_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp ugt i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbhs_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cbhs_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbhs w0, w1, LBB3_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB3_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbhs_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxtb
+; CHECK-NO-CMPBR-NEXT:    b.hs LBB3_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB3_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp uge i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbeq_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cbeq_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbeq w0, w1, LBB4_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB4_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbeq_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxtb
+; CHECK-NO-CMPBR-NEXT:    b.eq LBB4_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB4_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp eq i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbne_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cbne_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbne w0, w1, LBB5_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB5_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbne_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxtb
+; CHECK-NO-CMPBR-NEXT:    b.ne LBB5_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB5_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp ne i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cble_ge_swap_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cble_ge_swap_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbge w1, w0, LBB6_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB6_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cble_ge_swap_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    sxtb w8, w0
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, sxtb
+; CHECK-NO-CMPBR-NEXT:    b.le LBB6_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB6_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp sle i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cblo_hi_swap_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cblo_hi_swap_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbhi w1, w0, LBB7_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB7_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cblo_hi_swap_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxtb
+; CHECK-NO-CMPBR-NEXT:    b.lo LBB7_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB7_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp ult i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbls_hs_swap_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cbls_hs_swap_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbhs w1, w0, LBB8_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB8_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbls_hs_swap_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxtb
+; CHECK-NO-CMPBR-NEXT:    b.ls LBB8_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB8_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp ule i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cblt_gt_swap_i8(i8 %a, i8 %b)  {
+; CHECK-CMPBR-LABEL: cblt_gt_swap_i8:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbbgt w1, w0, LBB9_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB9_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cblt_gt_swap_i8:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    sxtb w8, w0
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, sxtb
+; CHECK-NO-CMPBR-NEXT:    b.lt LBB9_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB9_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp slt i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbgt_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cbgt_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhgt w0, w1, LBB10_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB10_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbgt_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    sxth w8, w0
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, sxth
+; CHECK-NO-CMPBR-NEXT:    b.gt LBB10_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB10_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp sgt i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbge_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cbge_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhge w0, w1, LBB11_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB11_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbge_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    sxth w8, w0
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, sxth
+; CHECK-NO-CMPBR-NEXT:    b.ge LBB11_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB11_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp sge i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+
+define void @cbhi_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cbhi_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhhi w0, w1, LBB12_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB12_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbhi_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xffff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxth
+; CHECK-NO-CMPBR-NEXT:    b.hi LBB12_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB12_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp ugt i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbhs_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cbhs_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhhs w0, w1, LBB13_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB13_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbhs_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xffff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxth
+; CHECK-NO-CMPBR-NEXT:    b.hs LBB13_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB13_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp uge i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbeq_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cbeq_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbheq w0, w1, LBB14_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB14_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbeq_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xffff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxth
+; CHECK-NO-CMPBR-NEXT:    b.eq LBB14_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB14_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp eq i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbne_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cbne_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhne w0, w1, LBB15_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB15_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbne_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xffff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxth
+; CHECK-NO-CMPBR-NEXT:    b.ne LBB15_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB15_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp ne i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cble_ge_swap_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cble_ge_swap_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhge w1, w0, LBB16_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB16_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cble_ge_swap_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    sxth w8, w0
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, sxth
+; CHECK-NO-CMPBR-NEXT:    b.le LBB16_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB16_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp sle i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cblo_hi_swap_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cblo_hi_swap_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhhi w1, w0, LBB17_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB17_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cblo_hi_swap_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xffff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxth
+; CHECK-NO-CMPBR-NEXT:    b.lo LBB17_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB17_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp ult i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbls_hs_swap_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cbls_hs_swap_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhhs w1, w0, LBB18_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB18_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbls_hs_swap_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    and w8, w0, #0xffff
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, uxth
+; CHECK-NO-CMPBR-NEXT:    b.ls LBB18_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB18_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp ule i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cblt_gt_swap_i16(i16 %a, i16 %b)  {
+; CHECK-CMPBR-LABEL: cblt_gt_swap_i16:
+; CHECK-CMPBR:       ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT:    cbhgt w1, w0, LBB19_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB19_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cblt_gt_swap_i16:
+; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT:    sxth w8, w0
+; CHECK-NO-CMPBR-NEXT:    cmp w8, w1, sxth
+; CHECK-NO-CMPBR-NEXT:    b.lt LBB19_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB19_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+entry:
+  %cmp = icmp slt i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
 
 define void @cbgt_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cbgt_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbgt w0, w1, LBB0_2
+; CHECK-CMPBR-NEXT:    cbgt w0, w1, LBB20_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB0_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB20_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbgt_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.gt LBB0_2
+; CHECK-NO-CMPBR-NEXT:    b.gt LBB20_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB0_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB20_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp sgt i32 %a, %b
@@ -35,19 +636,19 @@ if.end:
 define void @cbge_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cbge_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbge w0, w1, LBB1_2
+; CHECK-CMPBR-NEXT:    cbge w0, w1, LBB21_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB1_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB21_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbge_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.ge LBB1_2
+; CHECK-NO-CMPBR-NEXT:    b.ge LBB21_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB1_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB21_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp sge i32 %a, %b
@@ -65,19 +666,19 @@ if.end:
 define void @cbhi_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cbhi_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbhi w0, w1, LBB2_2
+; CHECK-CMPBR-NEXT:    cbhi w0, w1, LBB22_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB2_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB22_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbhi_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.hi LBB2_2
+; CHECK-NO-CMPBR-NEXT:    b.hi LBB22_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB2_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB22_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp ugt i32 %a, %b
@@ -94,19 +695,19 @@ if.end:
 define void @cbhs_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cbhs_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbhs w0, w1, LBB3_2
+; CHECK-CMPBR-NEXT:    cbhs w0, w1, LBB23_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB3_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB23_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbhs_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.hs LBB3_2
+; CHECK-NO-CMPBR-NEXT:    b.hs LBB23_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB3_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB23_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp uge i32 %a, %b
@@ -123,19 +724,19 @@ if.end:
 define void @cbeq_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cbeq_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbeq w0, w1, LBB4_2
+; CHECK-CMPBR-NEXT:    cbeq w0, w1, LBB24_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB4_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB24_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbeq_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.eq LBB4_2
+; CHECK-NO-CMPBR-NEXT:    b.eq LBB24_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB4_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB24_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp eq i32 %a, %b
@@ -152,19 +753,19 @@ if.end:
 define void @cbne_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cbne_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbne w0, w1, LBB5_2
+; CHECK-CMPBR-NEXT:    cbne w0, w1, LBB25_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB5_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB25_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbne_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.ne LBB5_2
+; CHECK-NO-CMPBR-NEXT:    b.ne LBB25_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB5_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB25_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp ne i32 %a, %b
@@ -181,19 +782,19 @@ if.end:
 define void @cble_ge_swap_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cble_ge_swap_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbge w1, w0, LBB6_2
+; CHECK-CMPBR-NEXT:    cbge w1, w0, LBB26_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB6_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB26_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cble_ge_swap_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.le LBB6_2
+; CHECK-NO-CMPBR-NEXT:    b.le LBB26_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB6_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB26_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp sle i32 %a, %b
@@ -210,19 +811,19 @@ if.end:
 define void @cblo_hi_swap_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cblo_hi_swap_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbhi w1, w0, LBB7_2
+; CHECK-CMPBR-NEXT:    cbhi w1, w0, LBB27_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB7_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB27_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cblo_hi_swap_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.lo LBB7_2
+; CHECK-NO-CMPBR-NEXT:    b.lo LBB27_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB7_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB27_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp ult i32 %a, %b
@@ -239,19 +840,19 @@ if.end:
 define void @cbls_hs_swap_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cbls_hs_swap_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbhs w1, w0, LBB8_2
+; CHECK-CMPBR-NEXT:    cbhs w1, w0, LBB28_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB8_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB28_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbls_hs_swap_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.ls LBB8_2
+; CHECK-NO-CMPBR-NEXT:    b.ls LBB28_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB8_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB28_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp ule i32 %a, %b
@@ -268,19 +869,19 @@ if.end:
 define void @cblt_gt_swap_i32(i32 %a, i32 %b)  {
 ; CHECK-CMPBR-LABEL: cblt_gt_swap_i32:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbgt w1, w0, LBB9_2
+; CHECK-CMPBR-NEXT:    cbgt w1, w0, LBB29_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB9_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB29_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cblt_gt_swap_i32:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
-; CHECK-NO-CMPBR-NEXT:    b.lt LBB9_2
+; CHECK-NO-CMPBR-NEXT:    b.lt LBB29_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB9_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB29_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp slt i32 %a, %b
@@ -297,19 +898,19 @@ if.end:
 define void @cbgt_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cbgt_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbgt x0, x1, LBB10_2
+; CHECK-CMPBR-NEXT:    cbgt x0, x1, LBB30_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB10_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB30_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbgt_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.gt LBB10_2
+; CHECK-NO-CMPBR-NEXT:    b.gt LBB30_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB10_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB30_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp sgt i64 %a, %b
@@ -326,19 +927,19 @@ if.end:
 define void @cbge_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cbge_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbge x0, x1, LBB11_2
+; CHECK-CMPBR-NEXT:    cbge x0, x1, LBB31_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB11_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB31_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbge_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.ge LBB11_2
+; CHECK-NO-CMPBR-NEXT:    b.ge LBB31_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB11_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB31_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp sge i64 %a, %b
@@ -356,19 +957,19 @@ if.end:
 define void @cbhi_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cbhi_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbhi x0, x1, LBB12_2
+; CHECK-CMPBR-NEXT:    cbhi x0, x1, LBB32_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB12_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB32_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbhi_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.hi LBB12_2
+; CHECK-NO-CMPBR-NEXT:    b.hi LBB32_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB12_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB32_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp ugt i64 %a, %b
@@ -385,19 +986,19 @@ if.end:
 define void @cbhs_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cbhs_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbhs x0, x1, LBB13_2
+; CHECK-CMPBR-NEXT:    cbhs x0, x1, LBB33_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB13_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB33_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbhs_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.hs LBB13_2
+; CHECK-NO-CMPBR-NEXT:    b.hs LBB33_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB13_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB33_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp uge i64 %a, %b
@@ -414,19 +1015,19 @@ if.end:
 define void @cbeq_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cbeq_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbeq x0, x1, LBB14_2
+; CHECK-CMPBR-NEXT:    cbeq x0, x1, LBB34_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB14_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB34_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbeq_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.eq LBB14_2
+; CHECK-NO-CMPBR-NEXT:    b.eq LBB34_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB14_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB34_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp eq i64 %a, %b
@@ -443,19 +1044,19 @@ if.end:
 define void @cbne_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cbne_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbne x0, x1, LBB15_2
+; CHECK-CMPBR-NEXT:    cbne x0, x1, LBB35_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB15_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB35_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbne_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.ne LBB15_2
+; CHECK-NO-CMPBR-NEXT:    b.ne LBB35_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB15_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB35_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp ne i64 %a, %b
@@ -472,19 +1073,19 @@ if.end:
 define void @cble_ge_swap_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cble_ge_swap_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbge x1, x0, LBB16_2
+; CHECK-CMPBR-NEXT:    cbge x1, x0, LBB36_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB16_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB36_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cble_ge_swap_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.le LBB16_2
+; CHECK-NO-CMPBR-NEXT:    b.le LBB36_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB16_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB36_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp sle i64 %a, %b
@@ -501,19 +1102,19 @@ if.end:
 define void @cblo_hi_swap_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cblo_hi_swap_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbhi x1, x0, LBB17_2
+; CHECK-CMPBR-NEXT:    cbhi x1, x0, LBB37_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB17_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB37_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cblo_hi_swap_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.lo LBB17_2
+; CHECK-NO-CMPBR-NEXT:    b.lo LBB37_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB17_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB37_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp ult i64 %a, %b
@@ -530,19 +1131,19 @@ if.end:
 define void @cbls_hs_swap_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cbls_hs_swap_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbhs x1, x0, LBB18_2
+; CHECK-CMPBR-NEXT:    cbhs x1, x0, LBB38_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB18_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB38_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cbls_hs_swap_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.ls LBB18_2
+; CHECK-NO-CMPBR-NEXT:    b.ls LBB38_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB18_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB38_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp ule i64 %a, %b
@@ -559,19 +1160,19 @@ if.end:
 define void @cblt_gt_swap_i64(i64 %a, i64 %b)  {
 ; CHECK-CMPBR-LABEL: cblt_gt_swap_i64:
 ; CHECK-CMPBR:       ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT:    cbgt x1, x0, LBB19_2
+; CHECK-CMPBR-NEXT:    cbgt x1, x0, LBB39_2
 ; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-CMPBR-NEXT:    ret
-; CHECK-CMPBR-NEXT:  LBB19_2: ; %if.then
+; CHECK-CMPBR-NEXT:  LBB39_2: ; %if.then
 ; CHECK-CMPBR-NEXT:    brk #0x1
 ;
 ; CHECK-NO-CMPBR-LABEL: cblt_gt_swap_i64:
 ; CHECK-NO-CMPBR:       ; %bb.0: ; %entry
 ; CHECK-NO-CMPBR-NEXT:    cmp x0, x1
-; CHECK-NO-CMPBR-NEXT:    b.lt LBB19_2
+; CHECK-NO-CMPBR-NEXT:    b.lt LBB39_2
 ; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
 ; CHECK-NO-CMPBR-NEXT:    ret
-; CHECK-NO-CMPBR-NEXT:  LBB19_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:  LBB39_2: ; %if.then
 ; CHECK-NO-CMPBR-NEXT:    brk #0x1
 entry:
   %cmp = icmp slt i64 %a, %b
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-zext-sext.ll b/llvm/test/CodeGen/AArch64/cmpbr-zext-sext.ll
new file mode 100644
index 0000000000000..79589eac3f977
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cmpbr-zext-sext.ll
@@ -0,0 +1,230 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple arm64-apple-ios -mattr +cmpbr -verify-machineinstrs -o - < %s | FileCheck %s --check-prefix=CHECK-CMPBR
+; RUN: llc -mtriple arm64-apple-ios -mattr -cmpbr -verify-machineinstrs -o - < %s | FileCheck %s --check-prefix=CHECK-NO-CMPBR
+
+define void @cbb_assertsext_eq(i8 signext %a, i8 signext %b) {
+; CHECK-CMPBR-LABEL: cbb_assertsext_eq:
+; CHECK-CMPBR:       ; %bb.0:
+; CHECK-CMPBR-NEXT:    cbbeq w0, w1, LBB0_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB0_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbb_assertsext_eq:
+; CHECK-NO-CMPBR:       ; %bb.0:
+; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
+; CHECK-NO-CMPBR-NEXT:    b.eq LBB0_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB0_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+  %cmp = icmp eq i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbb_assertsext_sgt(i8 signext %a, i8 signext %b) {
+; CHECK-CMPBR-LABEL: cbb_assertsext_sgt:
+; CHECK-CMPBR:       ; %bb.0:
+; CHECK-CMPBR-NEXT:    cbbgt w0, w1, LBB1_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB1_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbb_assertsext_sgt:
+; CHECK-NO-CMPBR:       ; %bb.0:
+; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
+; CHECK-NO-CMPBR-NEXT:    b.gt LBB1_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB1_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+  %cmp = icmp sgt i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbh_assertsext_slt(i16 signext %a, i16 signext %b) {
+; CHECK-CMPBR-LABEL: cbh_assertsext_slt:
+; CHECK-CMPBR:       ; %bb.0:
+; CHECK-CMPBR-NEXT:    cbbgt w1, w0, LBB2_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB2_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbh_assertsext_slt:
+; CHECK-NO-CMPBR:       ; %bb.0:
+; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
+; CHECK-NO-CMPBR-NEXT:    b.lt LBB2_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB2_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+  %cmp = icmp slt i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbb_assertzext_eq(i8 zeroext %a, i8 zeroext %b) {
+; CHECK-CMPBR-LABEL: cbb_assertzext_eq:
+; CHECK-CMPBR:       ; %bb.0:
+; CHECK-CMPBR-NEXT:    cbbeq w0, w1, LBB3_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB3_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbb_assertzext_eq:
+; CHECK-NO-CMPBR:       ; %bb.0:
+; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
+; CHECK-NO-CMPBR-NEXT:    b.eq LBB3_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB3_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+  %cmp = icmp eq i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbb_assertzext_ugt(i8 zeroext %a, i8 zeroext %b) {
+; CHECK-CMPBR-LABEL: cbb_assertzext_ugt:
+; CHECK-CMPBR:       ; %bb.0:
+; CHECK-CMPBR-NEXT:    cbbhi w0, w1, LBB4_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB4_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbb_assertzext_ugt:
+; CHECK-NO-CMPBR:       ; %bb.0:
+; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
+; CHECK-NO-CMPBR-NEXT:    b.hi LBB4_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB4_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+  %cmp = icmp ugt i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbh_assertzext_ule(i16 zeroext %a, i16 zeroext %b) {
+; CHECK-CMPBR-LABEL: cbh_assertzext_ule:
+; CHECK-CMPBR:       ; %bb.0:
+; CHECK-CMPBR-NEXT:    cbbhs w1, w0, LBB5_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB5_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbh_assertzext_ule:
+; CHECK-NO-CMPBR:       ; %bb.0:
+; CHECK-NO-CMPBR-NEXT:    cmp w0, w1
+; CHECK-NO-CMPBR-NEXT:    b.ls LBB5_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB5_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+  %cmp = icmp ule i16 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbb_mixed_assertsext_only_first(i8 signext %a, i8 %b) {
+; CHECK-CMPBR-LABEL: cbb_mixed_assertsext_only_first:
+; CHECK-CMPBR:       ; %bb.0:
+; CHECK-CMPBR-NEXT:    cbbgt w0, w1, LBB6_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB6_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbb_mixed_assertsext_only_first:
+; CHECK-NO-CMPBR:       ; %bb.0:
+; CHECK-NO-CMPBR-NEXT:    cmp w0, w1, sxtb
+; CHECK-NO-CMPBR-NEXT:    b.gt LBB6_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB6_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+  %cmp = icmp sgt i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+define void @cbb_mixed_assertzext_only_second(i8 %a, i8 zeroext %b) {
+; CHECK-CMPBR-LABEL: cbb_mixed_assertzext_only_second:
+; CHECK-CMPBR:       ; %bb.0:
+; CHECK-CMPBR-NEXT:    cbbhi w0, w1, LBB7_2
+; CHECK-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT:    ret
+; CHECK-CMPBR-NEXT:  LBB7_2: ; %if.then
+; CHECK-CMPBR-NEXT:    brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbb_mixed_assertzext_only_second:
+; CHECK-NO-CMPBR:       ; %bb.0:
+; CHECK-NO-CMPBR-NEXT:    cmp w1, w0, uxtb
+; CHECK-NO-CMPBR-NEXT:    b.lo LBB7_2
+; CHECK-NO-CMPBR-NEXT:  ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT:    ret
+; CHECK-NO-CMPBR-NEXT:  LBB7_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT:    brk #0x1
+  %cmp = icmp ugt i8 %a, %b
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @llvm.trap()
+  unreachable
+
+if.end:
+  ret void
+}
+
+
+declare void @llvm.trap()
    
    
More information about the llvm-commits
mailing list