[llvm] [AArch64][FEAT_CMPBR] Codegen for Armv9.6-a compare-and-branch (PR #116465)
David Tellenbach via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 19 12:01:17 PST 2025
https://github.com/dtellenbach updated https://github.com/llvm/llvm-project/pull/116465
>From 55a4f0f7eeb16726b6a1c390ee689bdd4bc1a8b1 Mon Sep 17 00:00:00 2001
From: David Tellenbach <dtellenbach at apple.com>
Date: Thu, 14 Nov 2024 23:36:34 -0800
Subject: [PATCH 1/4] [AArch64][FEAT_CMPBR] Codegen for Armv9.6-a
compare-and-branch
This patch adds codegen for all Arm9.6-a compare-and-branch
instructions, that operate on full w or x registers. The instruction
variants operating on half-words (cbh) and bytes (cbb) are added in a
subsequent patch.
Since CB doesn't use standard 4-bit Arm condition codes but a reduced
set of conditions, encoded in 3 bits, some conditions are expressed
by modifying operands, namely incrementing or decrementing immediate
operands and swapping register operands. To invert a CB instruction
it's therefore not enough to just modify the condition code which
doesn't play particularly well with how the backend is currently
organized. We therefore introduce a number of pseudos which operate on
the standard 4-bit condition codes and lower them late during codegen.
---
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 166 ++-
.../Target/AArch64/AArch64ISelLowering.cpp | 52 +
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 4 +
.../lib/Target/AArch64/AArch64InstrFormats.td | 15 +
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 94 +-
llvm/lib/Target/AArch64/AArch64InstrInfo.h | 4 +
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 25 +
.../Target/AArch64/Utils/AArch64BaseInfo.h | 20 +
.../AArch64/cmpbr-branch-relaxation.mir | 156 +++
.../CodeGen/AArch64/cmpbr-early-ifcvt.mir | 116 ++
.../AArch64/cmpbr-reg-imm-at-bounds.ll | 1060 +++++++++++++++++
.../CodeGen/AArch64/cmpbr-reg-imm-bounds.ll | 94 ++
llvm/test/CodeGen/AArch64/cmpbr-reg-imm.ll | 583 +++++++++
llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll | 586 +++++++++
14 files changed, 2973 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/cmpbr-branch-relaxation.mir
create mode 100644 llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
create mode 100644 llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
create mode 100644 llvm/test/CodeGen/AArch64/cmpbr-reg-imm-bounds.ll
create mode 100644 llvm/test/CodeGen/AArch64/cmpbr-reg-imm.ll
create mode 100644 llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index f1f25b65fc53f..418544cbcfe08 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -208,6 +208,9 @@ class AArch64AsmPrinter : public AsmPrinter {
void emitAttributes(unsigned Flags, uint64_t PAuthABIPlatform,
uint64_t PAuthABIVersion, AArch64TargetStreamer *TS);
+ // Emit expansion of Compare-and-branch pseudo instructions
+ void emitCBPseudoExpansion(const MachineInstr *MI);
+
void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
void EmitToStreamer(const MCInst &Inst) {
EmitToStreamer(*OutStreamer, Inst);
@@ -2589,6 +2592,160 @@ AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
return BAE;
}
+void AArch64AsmPrinter::emitCBPseudoExpansion(const MachineInstr *MI) {
+ bool IsImm = false;
+ bool Is32Bit = false;
+
+ switch (MI->getOpcode()) {
+ default:
+ llvm_unreachable("This is not a CB pseudo instruction");
+ case AArch64::CBWPrr:
+ IsImm = false;
+ Is32Bit = true;
+ break;
+ case AArch64::CBXPrr:
+ IsImm = false;
+ Is32Bit = false;
+ break;
+ case AArch64::CBWPri:
+ IsImm = true;
+ Is32Bit = true;
+ break;
+ case AArch64::CBXPri:
+ IsImm = true;
+ Is32Bit = false;
+ break;
+ }
+
+ AArch64CC::CondCode CC =
+ static_cast<AArch64CC::CondCode>(MI->getOperand(0).getImm());
+ bool NeedsRegSwap = false;
+ bool NeedsImmDec = false;
+ bool NeedsImmInc = false;
+
+ // 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);
+ NeedsRegSwap = false;
+ NeedsImmDec = false;
+ NeedsImmInc = false;
+ break;
+ case AArch64CC::NE:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBNEWri : AArch64::CBNEXri)
+ : (Is32Bit ? AArch64::CBNEWrr : AArch64::CBNEXrr);
+ NeedsRegSwap = false;
+ NeedsImmDec = false;
+ NeedsImmInc = false;
+ break;
+ case AArch64CC::HS:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
+ : (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
+ NeedsRegSwap = false;
+ NeedsImmDec = IsImm;
+ NeedsImmInc = false;
+ break;
+ case AArch64CC::LO:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
+ : (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
+ NeedsRegSwap = !IsImm;
+ NeedsImmDec = false;
+ NeedsImmInc = false;
+ break;
+ case AArch64CC::HI:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
+ : (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
+ NeedsRegSwap = false;
+ NeedsImmDec = false;
+ NeedsImmInc = false;
+ break;
+ case AArch64CC::LS:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
+ : (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
+ NeedsRegSwap = !IsImm;
+ NeedsImmDec = false;
+ NeedsImmInc = IsImm;
+ break;
+ case AArch64CC::GE:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
+ : (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
+ NeedsRegSwap = false;
+ NeedsImmDec = IsImm;
+ NeedsImmInc = false;
+ break;
+ case AArch64CC::LT:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
+ : (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
+ NeedsRegSwap = !IsImm;
+ NeedsImmDec = false;
+ NeedsImmInc = false;
+ break;
+ case AArch64CC::GT:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
+ : (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
+ NeedsRegSwap = false;
+ NeedsImmDec = false;
+ NeedsImmInc = false;
+ break;
+ case AArch64CC::LE:
+ MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
+ : (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
+ NeedsRegSwap = !IsImm;
+ NeedsImmDec = false;
+ NeedsImmInc = IsImm;
+ break;
+ }
+
+ assert(!(NeedsImmDec && NeedsImmInc) &&
+ "Cannot require increment and decrement of CB immediate operand at "
+ "the same time");
+
+ MCInst Inst;
+ Inst.setOpcode(MCOpC);
+
+ MCOperand Lhs, Rhs, Trgt;
+ lowerOperand(MI->getOperand(1), Lhs);
+ lowerOperand(MI->getOperand(2), Rhs);
+ lowerOperand(MI->getOperand(3), Trgt);
+
+ // Now swap, increment or decrement
+ if (NeedsRegSwap) {
+ assert(
+ !IsImm &&
+ "Unexpected register swap for CB instruction with immediate operand");
+ assert(Lhs.isReg() && "Expected register operand for CB");
+ assert(Rhs.isReg() && "Expected register operand for CB");
+ Inst.addOperand(Rhs);
+ Inst.addOperand(Lhs);
+ } else if (NeedsImmDec) {
+ assert(IsImm && "Unexpected immediate decrement for CB instruction with "
+ "reg-reg operands");
+ Rhs.setImm(Rhs.getImm() - 1);
+ Inst.addOperand(Lhs);
+ Inst.addOperand(Rhs);
+ } else if (NeedsImmInc) {
+ assert(IsImm && "Unexpected immediate increment for CB instruction with "
+ "reg-reg operands");
+ Rhs.setImm(Rhs.getImm() + 1);
+ Inst.addOperand(Lhs);
+ Inst.addOperand(Rhs);
+ } else {
+ Inst.addOperand(Lhs);
+ Inst.addOperand(Rhs);
+ }
+
+ assert((!IsImm || (Rhs.getImm() >= 0 && Rhs.getImm() < 64)) &&
+ "CB immediate operand out-of-bounds");
+
+ Inst.addOperand(Trgt);
+ EmitToStreamer(*OutStreamer, Inst);
+}
+
// Simple pseudo-instructions have their lowering (with expansion to real
// instructions) auto-generated.
#include "AArch64GenMCPseudoLowering.inc"
@@ -3155,13 +3312,20 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
return;
case AArch64::BLR:
- case AArch64::BR:
+ case AArch64::BR: {
recordIfImportCall(MI);
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
EmitToStreamer(*OutStreamer, TmpInst);
return;
}
+ case AArch64::CBWPri:
+ case AArch64::CBXPri:
+ case AArch64::CBWPrr:
+ case AArch64::CBXPrr:
+ emitCBPseudoExpansion(MI);
+ return;
+ }
// Finally, do the automated lowerings for everything else.
MCInst TmpInst;
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 34464d317beaf..d51382b5e34e0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2983,6 +2983,8 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
MAKE_CASE(AArch64ISD::CTTZ_ELTS)
MAKE_CASE(AArch64ISD::CALL_ARM64EC_TO_X64)
MAKE_CASE(AArch64ISD::URSHR_I_PRED)
+ MAKE_CASE(AArch64ISD::CBRR)
+ MAKE_CASE(AArch64ISD::CBRI)
}
#undef MAKE_CASE
return nullptr;
@@ -10593,6 +10595,56 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
DAG.getConstant(SignBitPos, dl, MVT::i64), Dest);
}
+ // Try to emit Armv9.6 CB instructions. We prefer tb{n}z/cb{n}z due to their
+ // larger branch displacement but do prefer CB over cmp + br.
+ if (Subtarget->hasCMPBR() &&
+ AArch64CC::isValidCBCond(changeIntCCToAArch64CC(CC)) &&
+ ProduceNonFlagSettingCondBr) {
+ AArch64CC::CondCode ACC = changeIntCCToAArch64CC(CC);
+ unsigned Opc = AArch64ISD::CBRR;
+ if (auto *Imm = dyn_cast<ConstantSDNode>(RHS)) {
+ // Check conservatively if the immediate fits the valid range [0, 64).
+ // Immediate variants for GE and HS definitely need to be decremented
+ // when lowering the pseudos later, so an immediate of 1 would become 0.
+ // For the inverse conditions LT and LO we don't know for sure if they
+ // will need a decrement but should the decision be made to reverse the
+ // branch condition, we again end up with the need to decrement.
+ // The same argument holds for LE, LS, GT and HI and possibly
+ // incremented immediates. This can lead to slightly less optimal
+ // codegen, e.g. we never codegen the legal case
+ // cblt w0, #63, A
+ // because we could end up with the illegal case
+ // cbge w0, #64, B
+ // should the decision to reverse the branch direction be made. For the
+ // lower bound cases this is no problem since we can express comparisons
+ // against 0 with either tbz/tnbz or using wzr/xzr.
+ uint64_t LowerBound = 0, UpperBound = 64;
+ switch (ACC) {
+ case AArch64CC::GE:
+ case AArch64CC::HS:
+ case AArch64CC::LT:
+ case AArch64CC::LO:
+ LowerBound = 1;
+ break;
+ case AArch64CC::LE:
+ case AArch64CC::LS:
+ case AArch64CC::GT:
+ case AArch64CC::HI:
+ UpperBound = 63;
+ break;
+ default:
+ break;
+ }
+
+ if (Imm->getAPIntValue().uge(LowerBound) &&
+ Imm->getAPIntValue().ult(UpperBound))
+ Opc = AArch64ISD::CBRI;
+ }
+
+ SDValue Cond = DAG.getTargetConstant(ACC, dl, MVT::i32);
+ return DAG.getNode(Opc, dl, MVT::Other, Chain, Cond, LHS, RHS, Dest);
+ }
+
SDValue CCVal;
SDValue Cmp = getAArch64Cmp(LHS, RHS, CC, CCVal, DAG, dl);
return DAG.getNode(AArch64ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal,
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index b26f28dc79f88..c840ce0adbcec 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -529,6 +529,10 @@ enum NodeType : unsigned {
// SME ZA loads and stores
SME_ZA_LDR,
SME_ZA_STR,
+
+ // Compare-and-branch
+ CBRR,
+ CBRI,
};
} // end namespace AArch64ISD
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index d13bb908df78e..7d29a05c5fb81 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -13232,6 +13232,21 @@ multiclass CmpBranchRegisterAlias<string mnemonic, string insn> {
def : InstAlias<mnemonic # "\t$Rt, $Rm, $target",
(!cast<Instruction>(insn # "Xrr") GPR64:$Rm, GPR64:$Rt, am_brcmpcond:$target), 0>;
}
+
+class CmpBranchRegisterPseudo<RegisterClass regtype>
+ : Pseudo<(outs), (ins ccode:$Cond, regtype:$Rt, regtype:$Rm, am_brcmpcond:$Target), []>,
+ Sched<[WriteBr]> {
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
+class CmpBranchImmediatePseudo<RegisterClass regtype, ImmLeaf imtype>
+ : Pseudo<(outs), (ins ccode:$Cond, regtype:$Rt, imtype:$Imm, am_brcmpcond:$Target), []>,
+ Sched<[WriteBr]> {
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
//----------------------------------------------------------------------------
// 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.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 0f2b969fba35c..efa03d4a1035b 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -62,6 +62,10 @@ using namespace llvm;
#define GET_INSTRINFO_CTOR_DTOR
#include "AArch64GenInstrInfo.inc"
+static cl::opt<unsigned>
+ CBDisplacementBits("aarch64-cb-offset-bits", cl::Hidden, cl::init(9),
+ cl::desc("Restrict range of CB instructions (DEBUG)"));
+
static cl::opt<unsigned> TBZDisplacementBits(
"aarch64-tbz-offset-bits", cl::Hidden, cl::init(14),
cl::desc("Restrict range of TB[N]Z instructions (DEBUG)"));
@@ -216,6 +220,18 @@ static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
Cond.push_back(LastInst->getOperand(0));
Cond.push_back(LastInst->getOperand(1));
+ break;
+ case AArch64::CBWPri:
+ case AArch64::CBXPri:
+ case AArch64::CBWPrr:
+ case AArch64::CBXPrr:
+ Target = LastInst->getOperand(3).getMBB();
+ Cond.push_back(MachineOperand::CreateImm(-1));
+ Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
+ Cond.push_back(LastInst->getOperand(0));
+ Cond.push_back(LastInst->getOperand(1));
+ Cond.push_back(LastInst->getOperand(2));
+ break;
}
}
@@ -237,6 +253,11 @@ static unsigned getBranchDisplacementBits(unsigned Opc) {
return CBZDisplacementBits;
case AArch64::Bcc:
return BCCDisplacementBits;
+ case AArch64::CBWPri:
+ case AArch64::CBXPri:
+ case AArch64::CBWPrr:
+ case AArch64::CBXPrr:
+ return CBDisplacementBits;
}
}
@@ -266,6 +287,11 @@ AArch64InstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
case AArch64::CBNZX:
case AArch64::Bcc:
return MI.getOperand(1).getMBB();
+ case AArch64::CBWPri:
+ case AArch64::CBXPri:
+ case AArch64::CBWPrr:
+ case AArch64::CBXPrr:
+ return MI.getOperand(3).getMBB();
}
}
@@ -543,6 +569,17 @@ bool AArch64InstrInfo::reverseBranchCondition(
case AArch64::TBNZX:
Cond[1].setImm(AArch64::TBZX);
break;
+
+ // Cond is { -1, Opcode, CC, Op0, Op1 }
+ case AArch64::CBWPri:
+ case AArch64::CBXPri:
+ case AArch64::CBWPrr:
+ case AArch64::CBXPrr: {
+ // Pseudos using standard 4bit Arm condition codes
+ AArch64CC::CondCode CC =
+ static_cast<AArch64CC::CondCode>(Cond[2].getImm());
+ Cond[2].setImm(AArch64CC::getInvertedCondCode(CC));
+ }
}
}
@@ -593,10 +630,19 @@ void AArch64InstrInfo::instantiateCondBranch(
} else {
// Folded compare-and-branch
// Note that we use addOperand instead of addReg to keep the flags.
+
+ // cbz, cbnz
const MachineInstrBuilder MIB =
BuildMI(&MBB, DL, get(Cond[1].getImm())).add(Cond[2]);
+
+ // tbz/tbnz
if (Cond.size() > 3)
- MIB.addImm(Cond[3].getImm());
+ MIB.add(Cond[3]);
+
+ // cb
+ if (Cond.size() > 4)
+ MIB.add(Cond[4]);
+
MIB.addMBB(TBB);
}
}
@@ -842,6 +888,48 @@ void AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB,
AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 64));
break;
}
+ case 5: { // cb
+ // We must insert a cmp, that is a subs
+ // 0 1 2 3 4
+ // Cond is { -1, Opcode, CC, Op0, Op1 }
+ 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;
+ IsImm = true;
+ break;
+ case AArch64::CBXPri:
+ SUBSOpC = AArch64::SUBSXri;
+ SUBSDestReg = AArch64::XZR;
+ IsImm = true;
+ break;
+ case AArch64::CBWPrr:
+ SUBSOpC = AArch64::SUBSWrr;
+ SUBSDestReg = AArch64::WZR;
+ IsImm = false;
+ break;
+ case AArch64::CBXPrr:
+ SUBSOpC = AArch64::SUBSXrr;
+ SUBSDestReg = AArch64::XZR;
+ IsImm = false;
+ break;
+ }
+
+ if (IsImm)
+ 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)
+ .addReg(Cond[3].getReg())
+ .addReg(Cond[4].getReg());
+ }
}
unsigned Opc = 0;
@@ -8426,6 +8514,10 @@ bool AArch64InstrInfo::optimizeCondBranch(MachineInstr &MI) const {
default:
llvm_unreachable("Unknown branch instruction?");
case AArch64::Bcc:
+ case AArch64::CBWPri:
+ case AArch64::CBXPri:
+ case AArch64::CBWPrr:
+ case AArch64::CBXPrr:
return false;
case AArch64::CBZW:
case AArch64::CBZX:
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 9a0034223ab9b..f7a1485cdd26a 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -692,6 +692,10 @@ static inline bool isCondBranchOpcode(int Opc) {
case AArch64::TBZX:
case AArch64::TBNZW:
case AArch64::TBNZX:
+ case AArch64::CBWPri:
+ case AArch64::CBXPri:
+ case AArch64::CBWPrr:
+ case AArch64::CBXPrr:
return true;
default:
return false;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index ce0c260b78410..9b2b21c846ce9 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -518,6 +518,9 @@ def SDT_AArch64TBL : SDTypeProfile<1, 2, [
SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>
]>;
+def SDT_AArch64cbrr : SDTypeProfile<0, 4, [SDTCisVT<0, i32>, SDTCisInt<1>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>]>;
+def SDT_AArch64cbri : SDTypeProfile<0, 4, [SDTCisVT<0, i32>, SDTCisInt<1>, SDTCisInt<2>, SDTCisVT<3, OtherVT>]>;
+
// non-extending masked load fragment.
def nonext_masked_load :
PatFrag<(ops node:$ptr, node:$pred, node:$def),
@@ -694,6 +697,8 @@ def topbitsallzero64: PatLeaf<(i64 GPR64:$src), [{
}]>;
// Node definitions.
+def AArch64CBrr : SDNode<"AArch64ISD::CBRR", SDT_AArch64cbrr, [SDNPHasChain]>;
+def AArch64CBri : SDNode<"AArch64ISD::CBRI", SDT_AArch64cbri, [SDNPHasChain]>;
def AArch64adrp : SDNode<"AArch64ISD::ADRP", SDTIntUnaryOp, []>;
def AArch64adr : SDNode<"AArch64ISD::ADR", SDTIntUnaryOp, []>;
def AArch64addlow : SDNode<"AArch64ISD::ADDlow", SDTIntBinOp, []>;
@@ -10488,6 +10493,10 @@ defm : PromoteBinaryv8f16Tov4f32<any_fdiv, FDIVv4f32>;
defm : PromoteBinaryv8f16Tov4f32<any_fmul, FMULv4f32>;
defm : PromoteBinaryv8f16Tov4f32<any_fsub, FSUBv4f32>;
+//===----------------------------------------------------------------------===//
+// Compare and Branch (FEAT_CMPBR)
+//===----------------------------------------------------------------------===//
+
let Predicates = [HasCMPBR] in {
defm CBGT : CmpBranchRegister<0b000, "cbgt">;
defm CBGE : CmpBranchRegister<0b001, "cbge">;
@@ -10536,6 +10545,22 @@ let Predicates = [HasCMPBR] in {
defm : CmpBranchWRegisterAlias<"cbhlo", "CBHHI">;
defm : CmpBranchWRegisterAlias<"cbhls", "CBHHS">;
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<(AArch64CBrr i32:$Cond, GPR32:$Rn, GPR32:$Rt, bb:$Target),
+ (CBWPrr ccode:$Cond, GPR32:$Rn, GPR32:$Rt, am_brcmpcond:$Target)>;
+def : Pat<(AArch64CBrr i32:$Cond, GPR64:$Rn, GPR64:$Rt, bb:$Target),
+ (CBXPrr ccode:$Cond, GPR64:$Rn, GPR64:$Rt, am_brcmpcond:$Target)>;
+def : Pat<(AArch64CBri i32:$Cond, GPR32:$Rn, i32:$Imm, bb:$Target),
+ (CBWPri ccode:$Cond, GPR32:$Rn, uimm6_32b:$Imm, am_brcmpcond:$Target)>;
+def : Pat<(AArch64CBri i32:$Cond, GPR64:$Rn, i64:$Imm, bb:$Target),
+ (CBXPri ccode:$Cond, GPR64:$Rn, uimm6_64b:$Imm, am_brcmpcond:$Target)>;
+
} // HasCMPBR
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 9671fa3b3d92f..a4ee963e2cce0 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -362,6 +362,26 @@ inline static unsigned getNZCVToSatisfyCondCode(CondCode Code) {
}
}
+/// True, if a given condition code can be used in a fused compare-and-branch
+/// instructions, false otherwise.
+inline static bool isValidCBCond(AArch64CC::CondCode Code) {
+ switch (Code) {
+ default:
+ return false;
+ case AArch64CC::EQ:
+ case AArch64CC::NE:
+ case AArch64CC::HS:
+ case AArch64CC::LO:
+ case AArch64CC::HI:
+ case AArch64CC::LS:
+ case AArch64CC::GE:
+ case AArch64CC::LT:
+ case AArch64CC::GT:
+ case AArch64CC::LE:
+ return true;
+ }
+}
+
} // end namespace AArch64CC
struct SysAlias {
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-branch-relaxation.mir b/llvm/test/CodeGen/AArch64/cmpbr-branch-relaxation.mir
new file mode 100644
index 0000000000000..5fccb452e9642
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cmpbr-branch-relaxation.mir
@@ -0,0 +1,156 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple arm64-apple-ios -mattr +cmpbr -o - -aarch64-cb-offset-bits=3 \
+# RUN: -run-pass=branch-relaxation -verify-machineinstrs -simplify-mir %s | \
+# RUN: FileCheck -check-prefix=RELAX %s
+# RUN: llc -mtriple arm64-apple-ios -mattr +cmpbr -o - -aarch64-cb-offset-bits=9 \
+# RUN: -run-pass=branch-relaxation -verify-machineinstrs -simplify-mir %s | \
+# RUN: FileCheck -check-prefix=NO-RELAX %s
+---
+name: relax_cb
+registers:
+ - { id: 0, class: gpr32 }
+ - { id: 1, class: gpr32 }
+liveins:
+ - { reg: '$w0', virtual-reg: '%0' }
+ - { reg: '$w1', virtual-reg: '%1' }
+body: |
+ ; RELAX-LABEL: name: relax_cb
+ ; RELAX: bb.0:
+ ; RELAX-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
+ ; RELAX-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+ ; RELAX-NEXT: CBWPrr 1, [[COPY]], [[COPY1]], %bb.1
+ ; RELAX-NEXT: B %bb.2
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: bb.1:
+ ; RELAX-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+ ; RELAX-NEXT: [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr]], [[COPY1]]
+ ; RELAX-NEXT: [[ADDWrr2:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr1]], [[ADDWrr]]
+ ; RELAX-NEXT: [[ADDWrr3:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr2]], [[ADDWrr1]]
+ ; RELAX-NEXT: [[ADDWrr4:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr3]], [[ADDWrr2]]
+ ; RELAX-NEXT: $w0 = ADDWrr [[ADDWrr4]], [[ADDWrr3]]
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: bb.2:
+ ; RELAX-NEXT: RET_ReallyLR implicit $w0
+ ;
+ ; NO-RELAX-LABEL: name: relax_cb
+ ; NO-RELAX: bb.0:
+ ; NO-RELAX-NEXT: successors: %bb.1, %bb.2
+ ; NO-RELAX-NEXT: {{ $}}
+ ; NO-RELAX-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
+ ; NO-RELAX-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+ ; NO-RELAX-NEXT: CBWPrr 0, [[COPY]], [[COPY1]], %bb.2
+ ; NO-RELAX-NEXT: {{ $}}
+ ; NO-RELAX-NEXT: bb.1:
+ ; NO-RELAX-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+ ; NO-RELAX-NEXT: [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr]], [[COPY1]]
+ ; NO-RELAX-NEXT: [[ADDWrr2:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr1]], [[ADDWrr]]
+ ; NO-RELAX-NEXT: [[ADDWrr3:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr2]], [[ADDWrr1]]
+ ; NO-RELAX-NEXT: [[ADDWrr4:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr3]], [[ADDWrr2]]
+ ; NO-RELAX-NEXT: $w0 = ADDWrr [[ADDWrr4]], [[ADDWrr3]]
+ ; NO-RELAX-NEXT: {{ $}}
+ ; NO-RELAX-NEXT: bb.2:
+ ; NO-RELAX-NEXT: RET_ReallyLR implicit $w0
+ bb.0:
+ successors: %bb.1, %bb.2
+ %0:gpr32 = COPY $w0
+ %1:gpr32 = COPY $w1
+ CBWPrr 0, %0, %1, %bb.2
+
+ bb.1:
+ successors: %bb.2
+ %2:gpr32 = ADDWrr %0, %1
+ %3:gpr32 = ADDWrr %2, %1
+ %4:gpr32 = ADDWrr %3, %2
+ %5:gpr32 = ADDWrr %4, %3
+ %6:gpr32 = ADDWrr %5, %4
+ $w0 = ADDWrr %6, %5
+
+ bb.2:
+ RET_ReallyLR implicit $w0
+...
+---
+name: relax_and_split_block
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gpr32 }
+ - { id: 1, class: gpr32 }
+liveins:
+ - { reg: '$w0', virtual-reg: '%0' }
+ - { reg: '$w1', virtual-reg: '%1' }
+body: |
+ ; RELAX-LABEL: name: relax_and_split_block
+ ; RELAX: bb.0:
+ ; RELAX-NEXT: liveins: $w0, $w1
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
+ ; RELAX-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+ ; RELAX-NEXT: CBWPrr 1, [[COPY]], [[COPY1]], %bb.3
+ ; RELAX-NEXT: B %bb.2
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: bb.3:
+ ; RELAX-NEXT: liveins: $w0, $w1
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: CBWPrr 0, [[COPY]], [[COPY1]], %bb.1
+ ; RELAX-NEXT: B %bb.2
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: bb.1:
+ ; RELAX-NEXT: liveins: $w0, $w1
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+ ; RELAX-NEXT: [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr]], [[COPY1]]
+ ; RELAX-NEXT: [[ADDWrr2:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr1]], [[ADDWrr]]
+ ; RELAX-NEXT: [[ADDWrr3:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr2]], [[ADDWrr1]]
+ ; RELAX-NEXT: [[ADDWrr4:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr3]], [[ADDWrr2]]
+ ; RELAX-NEXT: $w0 = ADDWrr [[ADDWrr4]], [[ADDWrr3]]
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: bb.2:
+ ; RELAX-NEXT: liveins: $w0, $w1
+ ; RELAX-NEXT: {{ $}}
+ ; RELAX-NEXT: RET_ReallyLR implicit $w0
+ ;
+ ; NO-RELAX-LABEL: name: relax_and_split_block
+ ; NO-RELAX: bb.0:
+ ; NO-RELAX-NEXT: successors: %bb.1, %bb.2
+ ; NO-RELAX-NEXT: liveins: $w0, $w1
+ ; NO-RELAX-NEXT: {{ $}}
+ ; NO-RELAX-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
+ ; NO-RELAX-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
+ ; NO-RELAX-NEXT: CBWPrr 0, [[COPY]], [[COPY1]], %bb.2
+ ; NO-RELAX-NEXT: CBWPrr 1, [[COPY]], [[COPY1]], %bb.2
+ ; NO-RELAX-NEXT: {{ $}}
+ ; NO-RELAX-NEXT: bb.1:
+ ; NO-RELAX-NEXT: liveins: $w0, $w1
+ ; NO-RELAX-NEXT: {{ $}}
+ ; NO-RELAX-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+ ; NO-RELAX-NEXT: [[ADDWrr1:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr]], [[COPY1]]
+ ; NO-RELAX-NEXT: [[ADDWrr2:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr1]], [[ADDWrr]]
+ ; NO-RELAX-NEXT: [[ADDWrr3:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr2]], [[ADDWrr1]]
+ ; NO-RELAX-NEXT: [[ADDWrr4:%[0-9]+]]:gpr32 = ADDWrr [[ADDWrr3]], [[ADDWrr2]]
+ ; NO-RELAX-NEXT: $w0 = ADDWrr [[ADDWrr4]], [[ADDWrr3]]
+ ; NO-RELAX-NEXT: {{ $}}
+ ; NO-RELAX-NEXT: bb.2:
+ ; NO-RELAX-NEXT: liveins: $w0, $w1
+ ; NO-RELAX-NEXT: {{ $}}
+ ; NO-RELAX-NEXT: RET_ReallyLR implicit $w0
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: $w0, $w1
+ %0:gpr32 = COPY $w0
+ %1:gpr32 = COPY $w1
+ CBWPrr 0, %0, %1, %bb.2
+ CBWPrr 1, %0, %1, %bb.2
+
+ bb.1:
+ successors: %bb.2
+ liveins: $w0, $w1
+ %2:gpr32 = ADDWrr %0, %1
+ %3:gpr32 = ADDWrr %2, %1
+ %4:gpr32 = ADDWrr %3, %2
+ %5:gpr32 = ADDWrr %4, %3
+ %6:gpr32 = ADDWrr %5, %4
+ $w0 = ADDWrr %6, %5
+
+ bb.2:
+ liveins: $w0, $w1
+ RET_ReallyLR implicit $w0
+...
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir b/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
new file mode 100644
index 0000000000000..c3377164f357e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cmpbr-early-ifcvt.mir
@@ -0,0 +1,116 @@
+# 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
+---
+name: cb_diamond
+alignment: 4
+tracksRegLiveness: true
+noPhis: false
+isSSA: true
+noVRegs: false
+hasFakeUses: false
+registers:
+ - { id: 0, class: gpr64 }
+ - { id: 1, class: gpr64 }
+ - { id: 2, class: gpr64 }
+ - { id: 3, class: gpr64 }
+ - { id: 4, class: gpr64 }
+ - { id: 5, class: gpr64 }
+liveins:
+ - { reg: '$x0', virtual-reg: '%0' }
+ - { reg: '$x1', virtual-reg: '%1' }
+frameInfo:
+ maxAlignment: 1
+ maxCallFrameSize: 0
+machineFunctionInfo: {}
+body: |
+ ; CHECK-LABEL: name: cb_diamond
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
+ ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY1]], $xzr
+ ; CHECK-NEXT: $xzr = SUBSXrr [[COPY]], [[COPY1]], implicit-def $nzcv
+ ; CHECK-NEXT: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[ADDXrr]], [[MADDXrrr]], 11, implicit $nzcv
+ ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr killed [[CSELXr]], [[COPY]]
+ ; CHECK-NEXT: $x0 = COPY [[ADDXrr1]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: $x0, $x1
+
+ %0:gpr64 = COPY $x0
+ %1:gpr64 = COPY $x1
+ CBXPrr 11, %0, %1, %bb.1
+ B %bb.2
+
+ bb.1:
+ successors: %bb.3
+ %2:gpr64 = ADDXrr %0, %1
+ B %bb.3
+
+ bb.2:
+ successors: %bb.3
+ %3:gpr64 = MADDXrrr %0, %1, $xzr
+ B %bb.3
+
+ bb.3:
+ %4:gpr64 = PHI %2, %bb.1, %3, %bb.2
+ %5:gpr64 = ADDXrr killed %4, %0
+ $x0 = COPY %5
+ RET_ReallyLR implicit $x0
+...
+---
+name: cb_triangle
+alignment: 4
+tracksRegLiveness: true
+noPhis: false
+isSSA: true
+noVRegs: false
+hasFakeUses: false
+registers:
+ - { id: 0, class: gpr64 }
+ - { id: 1, class: gpr64 }
+ - { id: 2, class: gpr64 }
+ - { id: 3, class: gpr64 }
+ - { id: 4, class: gpr64 }
+liveins:
+ - { reg: '$x0', virtual-reg: '%0' }
+ - { reg: '$x1', virtual-reg: '%1' }
+frameInfo:
+ maxAlignment: 1
+ maxCallFrameSize: 0
+machineFunctionInfo: {}
+body: |
+ ; CHECK-LABEL: name: cb_triangle
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1
+ ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: $xzr = SUBSXrr [[COPY]], [[COPY1]], implicit-def $nzcv
+ ; CHECK-NEXT: [[CSELXr:%[0-9]+]]:gpr64 = CSELXr [[COPY1]], [[ADDXrr]], 10, implicit $nzcv
+ ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr killed [[CSELXr]], [[COPY]]
+ ; CHECK-NEXT: $x0 = COPY [[ADDXrr1]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: $x0, $x1
+
+ %0:gpr64 = COPY $x0
+ %1:gpr64 = COPY $x1
+ CBXPrr 10, %0, %1, %bb.2
+
+ bb.1:
+ successors: %bb.2
+ %2:gpr64 = ADDXrr %0, %1
+
+ bb.2:
+ %3:gpr64 = PHI %1, %bb.0, %2, %bb.1
+ %4:gpr64 = ADDXrr killed %3, %0
+ $x0 = COPY %4
+ RET_ReallyLR implicit $x0
+...
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
new file mode 100644
index 0000000000000..6b929cac7e54f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
@@ -0,0 +1,1060 @@
+; 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
+
+; slt, sle, sgt, sge, ult, ule, ugt, uge, eq, ne
+
+define void @slt_0(i32 %a) {
+; CHECK-CMPBR-LABEL: slt_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: tbnz w0, #31, 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: slt_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: tbnz w0, #31, 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 slt i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @slt_m1(i32 %a) {
+; CHECK-CMPBR-LABEL: slt_m1:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #-2 ; =0xfffffffe
+; CHECK-CMPBR-NEXT: cbge w8, w0, 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: slt_m1:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn w0, #2
+; CHECK-NO-CMPBR-NEXT: b.le 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 slt i32 %a, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @slt_63(i32 %a) {
+; CHECK-CMPBR-LABEL: slt_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblt w0, #63, 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: slt_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #62
+; CHECK-NO-CMPBR-NEXT: b.le 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 slt i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @slt_64(i32 %a) {
+; CHECK-CMPBR-LABEL: slt_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #63 ; =0x3f
+; CHECK-CMPBR-NEXT: cbge w8, w0, 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: slt_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #63
+; CHECK-NO-CMPBR-NEXT: b.le 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 slt i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sle_0(i32 %a) {
+; CHECK-CMPBR-LABEL: sle_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblt w0, #1, 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: sle_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #0
+; CHECK-NO-CMPBR-NEXT: b.le 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 sle i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sle_m1(i32 %a) {
+; CHECK-CMPBR-LABEL: sle_m1:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: tbnz w0, #31, 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: sle_m1:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: tbnz w0, #31, 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 sle i32 %a, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sle_63(i32 %a) {
+; CHECK-CMPBR-LABEL: sle_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #63 ; =0x3f
+; CHECK-CMPBR-NEXT: cbge w8, 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: sle_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #63
+; 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 i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sle_64(i32 %a) {
+; CHECK-CMPBR-LABEL: sle_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbge w8, 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: sle_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; CHECK-NO-CMPBR-NEXT: b.le 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 sle i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sgt_0(i32 %a) {
+; CHECK-CMPBR-LABEL: sgt_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbgt w0, #0, 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: sgt_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #1
+; CHECK-NO-CMPBR-NEXT: b.ge 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 sgt i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sgt_m1(i32 %a) {
+; CHECK-CMPBR-LABEL: sgt_m1:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: tbz w0, #31, 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: sgt_m1:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: tbz w0, #31, 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 sgt i32 %a, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sgt_63(i32 %a) {
+; CHECK-CMPBR-LABEL: sgt_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbge w0, w8, 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: sgt_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; CHECK-NO-CMPBR-NEXT: b.ge 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 i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sgt_64(i32 %a) {
+; CHECK-CMPBR-LABEL: sgt_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #65 ; =0x41
+; CHECK-CMPBR-NEXT: cbge w0, w8, 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: sgt_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #65
+; 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 sgt i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sge_0(i32 %a) {
+; CHECK-CMPBR-LABEL: sge_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: tbz w0, #31, 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: sge_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: tbz w0, #31, 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 sge i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sge_m1(i32 %a) {
+; CHECK-CMPBR-LABEL: sge_m1:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #-1 ; =0xffffffff
+; CHECK-CMPBR-NEXT: cbge w0, w8, 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: sge_m1:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn w0, #1
+; CHECK-NO-CMPBR-NEXT: b.ge 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 sge i32 %a, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sge_63(i32 %a) {
+; CHECK-CMPBR-LABEL: sge_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbge w0, w8, 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: sge_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; CHECK-NO-CMPBR-NEXT: b.ge 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 sgt i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sge_64(i32 %a) {
+; CHECK-CMPBR-LABEL: sge_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #65 ; =0x41
+; CHECK-CMPBR-NEXT: cbge w0, w8, 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: sge_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #65
+; CHECK-NO-CMPBR-NEXT: b.ge 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 sgt i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ult_0(i32 %a) {
+; CHECK-CMPBR-LABEL: ult_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbhi wzr, 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: ult_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #0
+; CHECK-NO-CMPBR-NEXT: b.lo 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 ult i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ult_63(i32 %a) {
+; CHECK-CMPBR-LABEL: ult_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblo w0, #63, 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: ult_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #62
+; CHECK-NO-CMPBR-NEXT: b.ls 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 i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ult_64(i32 %a) {
+; CHECK-CMPBR-LABEL: ult_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #63 ; =0x3f
+; CHECK-CMPBR-NEXT: cbhs w8, 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: ult_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #63
+; 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 ult i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ule_0(i32 %a) {
+; CHECK-CMPBR-LABEL: ule_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbz 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: ule_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cbz w0, 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 ule i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ule_63(i32 %a) {
+; CHECK-CMPBR-LABEL: ule_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #63 ; =0x3f
+; CHECK-CMPBR-NEXT: cbhs w8, w0, LBB20_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB20_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ule_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #63
+; CHECK-NO-CMPBR-NEXT: b.ls LBB20_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB20_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ule i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ule_64(i32 %a) {
+; CHECK-CMPBR-LABEL: ule_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbhs w8, w0, LBB21_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB21_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ule_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; CHECK-NO-CMPBR-NEXT: b.ls LBB21_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB21_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ule i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ugt_0(i32 %a) {
+; CHECK-CMPBR-LABEL: ugt_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbnz w0, LBB22_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB22_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ugt_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cbnz w0, LBB22_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB22_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ugt i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ugt_63(i32 %a) {
+; CHECK-CMPBR-LABEL: ugt_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbhs w0, w8, LBB23_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB23_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ugt_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; 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: LBB23_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ugt i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ugt_64(i32 %a) {
+; CHECK-CMPBR-LABEL: ugt_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #65 ; =0x41
+; CHECK-CMPBR-NEXT: cbhs w0, w8, LBB24_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB24_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ugt_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #65
+; CHECK-NO-CMPBR-NEXT: b.hs LBB24_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB24_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ugt i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @uge_0(i32 %a) {
+; CHECK-CMPBR-LABEL: uge_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbhs w0, wzr, LBB25_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB25_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: uge_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #0
+; CHECK-NO-CMPBR-NEXT: b.hs LBB25_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB25_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp uge i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @uge_63(i32 %a) {
+; CHECK-CMPBR-LABEL: uge_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbhi w0, #62, LBB26_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB26_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: uge_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #63
+; CHECK-NO-CMPBR-NEXT: b.hs LBB26_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB26_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp uge i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @uge_64(i32 %a) {
+; CHECK-CMPBR-LABEL: uge_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbhs w0, w8, LBB27_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB27_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: uge_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; CHECK-NO-CMPBR-NEXT: b.hs LBB27_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB27_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp uge i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @eq_0(i32 %a) {
+; CHECK-CMPBR-LABEL: eq_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbz w0, LBB28_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB28_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: eq_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cbz w0, LBB28_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB28_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp eq i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @eq_m1(i32 %a) {
+; CHECK-CMPBR-LABEL: eq_m1:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #-1 ; =0xffffffff
+; CHECK-CMPBR-NEXT: cbeq w0, w8, LBB29_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB29_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: eq_m1:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn w0, #1
+; CHECK-NO-CMPBR-NEXT: b.eq LBB29_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB29_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp eq i32 %a, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @eq_63(i32 %a) {
+; CHECK-CMPBR-LABEL: eq_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbeq w0, #63, LBB30_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB30_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: eq_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #63
+; CHECK-NO-CMPBR-NEXT: b.eq LBB30_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB30_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp eq i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @eq_64(i32 %a) {
+; CHECK-CMPBR-LABEL: eq_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbeq w0, w8, LBB31_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB31_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: eq_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; CHECK-NO-CMPBR-NEXT: b.eq LBB31_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB31_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp eq i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ne_0(i32 %a) {
+; CHECK-CMPBR-LABEL: ne_0:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbnz w0, LBB32_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB32_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ne_0:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cbnz w0, LBB32_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB32_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ne i32 %a, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ne_m1(i32 %a) {
+; CHECK-CMPBR-LABEL: ne_m1:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #-1 ; =0xffffffff
+; CHECK-CMPBR-NEXT: cbne w0, w8, LBB33_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB33_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ne_m1:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn w0, #1
+; CHECK-NO-CMPBR-NEXT: b.ne LBB33_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB33_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ne i32 %a, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ne_63(i32 %a) {
+; CHECK-CMPBR-LABEL: ne_63:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbne w0, #63, LBB34_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB34_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ne_63:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #63
+; CHECK-NO-CMPBR-NEXT: b.ne LBB34_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB34_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ne i32 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ne_64(i32 %a) {
+; CHECK-CMPBR-LABEL: ne_64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbne w0, w8, LBB35_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB35_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ne_64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; 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: LBB35_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ne i32 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-bounds.ll b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-bounds.ll
new file mode 100644
index 0000000000000..45134866cf156
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-bounds.ll
@@ -0,0 +1,94 @@
+; 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 @cbge_out_of_upper_bound(i32 %a) {
+; CHECK-CMPBR-LABEL: cbge_out_of_upper_bound:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #71 ; =0x47
+; CHECK-CMPBR-NEXT: cbge w0, w8, 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: cbge_out_of_upper_bound:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #71
+; CHECK-NO-CMPBR-NEXT: b.ge 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 i32 %a, 70
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbge_out_of_lower_bound(i32 %a) {
+; CHECK-CMPBR-LABEL: cbge_out_of_lower_bound:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #-10 ; =0xfffffff6
+; CHECK-CMPBR-NEXT: cbge w0, w8, 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_out_of_lower_bound:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn w0, #10
+; 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 i32 %a, -10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+; This should trigger a register swap.
+define void @cble_out_of_lower_bound(i32 %a) {
+; CHECK-CMPBR-LABEL: cble_out_of_lower_bound:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #-10 ; =0xfffffff6
+; CHECK-CMPBR-NEXT: cbhs w8, 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: cble_out_of_lower_bound:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn w0, #10
+; CHECK-NO-CMPBR-NEXT: b.ls 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 ule i32 %a, -10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm.ll b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm.ll
new file mode 100644
index 0000000000000..ad778181bcf9b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm.ll
@@ -0,0 +1,583 @@
+; 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 @cbgt_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbgt_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbgt w0, #10, 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_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #11
+; CHECK-NO-CMPBR-NEXT: b.ge 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 i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cblt_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cblt_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblt w0, #10, 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: cblt_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #9
+; CHECK-NO-CMPBR-NEXT: b.le 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 slt i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbhi_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbhi_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbhi w0, #10, 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_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #11
+; CHECK-NO-CMPBR-NEXT: b.hs 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 i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cblo_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cblo_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblo w0, #10, 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: cblo_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #9
+; CHECK-NO-CMPBR-NEXT: b.ls 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 ult i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbeq_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbeq_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbeq w0, #10, 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_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #10
+; 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 i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbne_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbne_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbne w0, #10, 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_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #10
+; 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 i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbge_gt_dec_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbge_gt_dec_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbgt w0, #9, 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: cbge_gt_dec_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #10
+; CHECK-NO-CMPBR-NEXT: b.ge 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 sge i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbhs_hi_dec_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbhs_hi_dec_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbhi w0, #9, 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: cbhs_hi_dec_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #10
+; CHECK-NO-CMPBR-NEXT: b.hs 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 uge i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cble_lt_inc_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cble_lt_inc_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblt w0, #11, 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: cble_lt_inc_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #10
+; CHECK-NO-CMPBR-NEXT: b.le 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 sle i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbls_lo_inc_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbls_lo_inc_i32:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblo w0, #11, 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: cbls_lo_inc_i32:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #10
+; CHECK-NO-CMPBR-NEXT: b.ls 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 ule i32 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbgt_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cbgt_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbgt x0, #10, 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_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #11
+; CHECK-NO-CMPBR-NEXT: b.ge 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 i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cblt_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cblt_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblt x0, #10, 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: cblt_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #9
+; CHECK-NO-CMPBR-NEXT: b.le 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 slt i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbhi_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cbhi_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbhi x0, #10, 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_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #11
+; CHECK-NO-CMPBR-NEXT: b.hs 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 i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cblo_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cblo_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblo x0, #10, 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: cblo_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #9
+; CHECK-NO-CMPBR-NEXT: b.ls 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 ult i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbeq_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cbeq_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbeq x0, #10, 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_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #10
+; 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 i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbne_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cbne_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbne x0, #10, 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_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #10
+; 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 i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbge_gt_dec_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cbge_gt_dec_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbgt x0, #9, 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: cbge_gt_dec_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #10
+; CHECK-NO-CMPBR-NEXT: b.ge 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 sge i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbhs_hi_dec_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cbhs_hi_dec_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbhi x0, #9, 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: cbhs_hi_dec_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #10
+; CHECK-NO-CMPBR-NEXT: b.hs 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 uge i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cble_lt_inc_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cble_lt_inc_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblt x0, #11, 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: cble_lt_inc_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #10
+; CHECK-NO-CMPBR-NEXT: b.le 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 sle i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbls_lo_inc_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: cbls_lo_inc_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblo x0, #11, 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: cbls_lo_inc_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #10
+; CHECK-NO-CMPBR-NEXT: b.ls 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 ule i64 %a, 10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll b/llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll
new file mode 100644
index 0000000000000..9e95434564f02
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cmpbr-reg-reg.ll
@@ -0,0 +1,586 @@
+; 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 @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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i32 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %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_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: ; %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_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: ; %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 i64 %a, %b
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
>From 563ae0f107f9216ce6934cba37f2f3070fc91af6 Mon Sep 17 00:00:00 2001
From: David Tellenbach <dtellenbach at apple.com>
Date: Tue, 11 Feb 2025 09:59:42 -0800
Subject: [PATCH 2/4] Address review comments
---
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 36 ------
.../AArch64/cmpbr-reg-imm-at-bounds.ll | 104 ++++++++++++++++--
.../CodeGen/AArch64/cmpbr-reg-imm-bounds.ll | 94 ----------------
3 files changed, 97 insertions(+), 137 deletions(-)
delete mode 100644 llvm/test/CodeGen/AArch64/cmpbr-reg-imm-bounds.ll
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 418544cbcfe08..eaca75b80dd12 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -2600,11 +2600,9 @@ void AArch64AsmPrinter::emitCBPseudoExpansion(const MachineInstr *MI) {
default:
llvm_unreachable("This is not a CB pseudo instruction");
case AArch64::CBWPrr:
- IsImm = false;
Is32Bit = true;
break;
case AArch64::CBXPrr:
- IsImm = false;
Is32Bit = false;
break;
case AArch64::CBWPri:
@@ -2613,7 +2611,6 @@ void AArch64AsmPrinter::emitCBPseudoExpansion(const MachineInstr *MI) {
break;
case AArch64::CBXPri:
IsImm = true;
- Is32Bit = false;
break;
}
@@ -2632,79 +2629,53 @@ void AArch64AsmPrinter::emitCBPseudoExpansion(const MachineInstr *MI) {
case AArch64CC::EQ:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBEQWri : AArch64::CBEQXri)
: (Is32Bit ? AArch64::CBEQWrr : AArch64::CBEQXrr);
- NeedsRegSwap = false;
- NeedsImmDec = false;
- NeedsImmInc = false;
break;
case AArch64CC::NE:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBNEWri : AArch64::CBNEXri)
: (Is32Bit ? AArch64::CBNEWrr : AArch64::CBNEXrr);
- NeedsRegSwap = false;
- NeedsImmDec = false;
- NeedsImmInc = false;
break;
case AArch64CC::HS:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
: (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
- NeedsRegSwap = false;
NeedsImmDec = IsImm;
- NeedsImmInc = false;
break;
case AArch64CC::LO:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
: (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
NeedsRegSwap = !IsImm;
- NeedsImmDec = false;
- NeedsImmInc = false;
break;
case AArch64CC::HI:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
: (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
- NeedsRegSwap = false;
- NeedsImmDec = false;
- NeedsImmInc = false;
break;
case AArch64CC::LS:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
: (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
NeedsRegSwap = !IsImm;
- NeedsImmDec = false;
NeedsImmInc = IsImm;
break;
case AArch64CC::GE:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
: (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
- NeedsRegSwap = false;
NeedsImmDec = IsImm;
- NeedsImmInc = false;
break;
case AArch64CC::LT:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
: (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
NeedsRegSwap = !IsImm;
- NeedsImmDec = false;
- NeedsImmInc = false;
break;
case AArch64CC::GT:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
: (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
- NeedsRegSwap = false;
- NeedsImmDec = false;
- NeedsImmInc = false;
break;
case AArch64CC::LE:
MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
: (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
NeedsRegSwap = !IsImm;
- NeedsImmDec = false;
NeedsImmInc = IsImm;
break;
}
- assert(!(NeedsImmDec && NeedsImmInc) &&
- "Cannot require increment and decrement of CB immediate operand at "
- "the same time");
-
MCInst Inst;
Inst.setOpcode(MCOpC);
@@ -2715,22 +2686,15 @@ void AArch64AsmPrinter::emitCBPseudoExpansion(const MachineInstr *MI) {
// Now swap, increment or decrement
if (NeedsRegSwap) {
- assert(
- !IsImm &&
- "Unexpected register swap for CB instruction with immediate operand");
assert(Lhs.isReg() && "Expected register operand for CB");
assert(Rhs.isReg() && "Expected register operand for CB");
Inst.addOperand(Rhs);
Inst.addOperand(Lhs);
} else if (NeedsImmDec) {
- assert(IsImm && "Unexpected immediate decrement for CB instruction with "
- "reg-reg operands");
Rhs.setImm(Rhs.getImm() - 1);
Inst.addOperand(Lhs);
Inst.addOperand(Rhs);
} else if (NeedsImmInc) {
- assert(IsImm && "Unexpected immediate increment for CB instruction with "
- "reg-reg operands");
Rhs.setImm(Rhs.getImm() + 1);
Inst.addOperand(Lhs);
Inst.addOperand(Rhs);
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
index 6b929cac7e54f..1b02b35e4f30e 100644
--- a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
+++ b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
@@ -416,8 +416,7 @@ if.end:
define void @sge_63(i32 %a) {
; CHECK-CMPBR-LABEL: sge_63:
; CHECK-CMPBR: ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
-; CHECK-CMPBR-NEXT: cbge w0, w8, LBB14_2
+; CHECK-CMPBR-NEXT: cbgt w0, #62, LBB14_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
; CHECK-CMPBR-NEXT: ret
; CHECK-CMPBR-NEXT: LBB14_2: ; %if.then
@@ -425,14 +424,14 @@ define void @sge_63(i32 %a) {
;
; CHECK-NO-CMPBR-LABEL: sge_63:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
-; CHECK-NO-CMPBR-NEXT: cmp w0, #64
+; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.ge 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 sgt i32 %a, 63
+ %cmp = icmp sge i32 %a, 63
br i1 %cmp, label %if.then, label %if.end
if.then:
@@ -446,7 +445,7 @@ if.end:
define void @sge_64(i32 %a) {
; CHECK-CMPBR-LABEL: sge_64:
; CHECK-CMPBR: ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT: mov w8, #65 ; =0x41
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbge w0, w8, LBB15_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
; CHECK-CMPBR-NEXT: ret
@@ -455,14 +454,14 @@ define void @sge_64(i32 %a) {
;
; CHECK-NO-CMPBR-LABEL: sge_64:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
-; CHECK-NO-CMPBR-NEXT: cmp w0, #65
+; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.ge 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 sgt i32 %a, 64
+ %cmp = icmp sge i32 %a, 64
br i1 %cmp, label %if.then, label %if.end
if.then:
@@ -1058,3 +1057,94 @@ if.then:
if.end:
ret void
}
+
+define void @cbge_out_of_upper_bound(i32 %a) {
+; CHECK-CMPBR-LABEL: cbge_out_of_upper_bound:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #71 ; =0x47
+; CHECK-CMPBR-NEXT: cbge w0, w8, LBB36_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB36_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbge_out_of_upper_bound:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp w0, #71
+; CHECK-NO-CMPBR-NEXT: b.ge LBB36_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB36_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp sgt i32 %a, 70
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @cbge_out_of_lower_bound(i32 %a) {
+; CHECK-CMPBR-LABEL: cbge_out_of_lower_bound:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #-10 ; =0xfffffff6
+; CHECK-CMPBR-NEXT: cbge w0, w8, LBB37_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB37_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cbge_out_of_lower_bound:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn w0, #10
+; CHECK-NO-CMPBR-NEXT: b.ge LBB37_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB37_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp sge i32 %a, -10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+; This should trigger a register swap.
+define void @cble_out_of_lower_bound(i32 %a) {
+; CHECK-CMPBR-LABEL: cble_out_of_lower_bound:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #-10 ; =0xfffffff6
+; CHECK-CMPBR-NEXT: cbhs w8, w0, LBB38_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB38_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: cble_out_of_lower_bound:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn w0, #10
+; 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: LBB38_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ule i32 %a, -10
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-bounds.ll b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-bounds.ll
deleted file mode 100644
index 45134866cf156..0000000000000
--- a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-bounds.ll
+++ /dev/null
@@ -1,94 +0,0 @@
-; 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 @cbge_out_of_upper_bound(i32 %a) {
-; CHECK-CMPBR-LABEL: cbge_out_of_upper_bound:
-; CHECK-CMPBR: ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT: mov w8, #71 ; =0x47
-; CHECK-CMPBR-NEXT: cbge w0, w8, 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: cbge_out_of_upper_bound:
-; CHECK-NO-CMPBR: ; %bb.0: ; %entry
-; CHECK-NO-CMPBR-NEXT: cmp w0, #71
-; CHECK-NO-CMPBR-NEXT: b.ge 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 i32 %a, 70
- br i1 %cmp, label %if.then, label %if.end
-
-if.then:
- tail call void @llvm.trap()
- unreachable
-
-if.end:
- ret void
-}
-
-define void @cbge_out_of_lower_bound(i32 %a) {
-; CHECK-CMPBR-LABEL: cbge_out_of_lower_bound:
-; CHECK-CMPBR: ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT: mov w8, #-10 ; =0xfffffff6
-; CHECK-CMPBR-NEXT: cbge w0, w8, 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_out_of_lower_bound:
-; CHECK-NO-CMPBR: ; %bb.0: ; %entry
-; CHECK-NO-CMPBR-NEXT: cmn w0, #10
-; 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 i32 %a, -10
- br i1 %cmp, label %if.then, label %if.end
-
-if.then:
- tail call void @llvm.trap()
- unreachable
-
-if.end:
- ret void
-}
-
-; This should trigger a register swap.
-define void @cble_out_of_lower_bound(i32 %a) {
-; CHECK-CMPBR-LABEL: cble_out_of_lower_bound:
-; CHECK-CMPBR: ; %bb.0: ; %entry
-; CHECK-CMPBR-NEXT: mov w8, #-10 ; =0xfffffff6
-; CHECK-CMPBR-NEXT: cbhs w8, 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: cble_out_of_lower_bound:
-; CHECK-NO-CMPBR: ; %bb.0: ; %entry
-; CHECK-NO-CMPBR-NEXT: cmn w0, #10
-; CHECK-NO-CMPBR-NEXT: b.ls 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 ule i32 %a, -10
- br i1 %cmp, label %if.then, label %if.end
-
-if.then:
- tail call void @llvm.trap()
- unreachable
-
-if.end:
- ret void
-}
>From df6e8314e22c7cd56018ae485e195693bf47fc2e Mon Sep 17 00:00:00 2001
From: David Tellenbach <dtellenbach at apple.com>
Date: Tue, 18 Feb 2025 20:50:06 -0800
Subject: [PATCH 3/4] Use single ISel opcode for register-register and
register-immediate CB
---
.../Target/AArch64/AArch64ISelDAGToDAG.cpp | 57 +++++++++++++++++++
.../Target/AArch64/AArch64ISelLowering.cpp | 50 ++--------------
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 3 +-
.../lib/Target/AArch64/AArch64InstrFormats.td | 14 +++++
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 29 +++++-----
5 files changed, 93 insertions(+), 60 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 1387a224fa660..9df50ef576faa 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -507,6 +507,9 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
bool SelectAllActivePredicate(SDValue N);
bool SelectAnyPredicate(SDValue N);
+
+ template <int Bits>
+ bool SelectCmpBranchUImm6Operand(SDNode *P, SDValue N, SDValue &Imm);
};
class AArch64DAGToDAGISelLegacy : public SelectionDAGISelLegacy {
@@ -7489,3 +7492,57 @@ bool AArch64DAGToDAGISel::SelectSMETileSlice(SDValue N, unsigned MaxSize,
Offset = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i64);
return true;
}
+
+template <int Bits>
+bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *P, SDValue N,
+ SDValue &Imm) {
+ ConstantSDNode *C = dyn_cast<ConstantSDNode>(P->getOperand(1));
+ if (!C)
+ return false;
+
+ AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(C->getZExtValue());
+ if (auto *CN = dyn_cast<ConstantSDNode>(N)) {
+ // Check conservatively if the immediate fits the valid range [0, 64).
+ // Immediate variants for GE and HS definitely need to be decremented
+ // when lowering the pseudos later, so an immediate of 1 would become 0.
+ // For the inverse conditions LT and LO we don't know for sure if they
+ // will need a decrement but should the decision be made to reverse the
+ // branch condition, we again end up with the need to decrement.
+ // The same argument holds for LE, LS, GT and HI and possibly
+ // incremented immediates. This can lead to slightly less optimal
+ // codegen, e.g. we never codegen the legal case
+ // cblt w0, #63, A
+ // because we could end up with the illegal case
+ // cbge w0, #64, B
+ // should the decision to reverse the branch direction be made. For the
+ // lower bound cases this is no problem since we can express comparisons
+ // against 0 with either tbz/tnbz or using wzr/xzr.
+ uint64_t LowerBound = 0, UpperBound = 64;
+ switch (CC) {
+ case AArch64CC::GE:
+ case AArch64CC::HS:
+ case AArch64CC::LT:
+ case AArch64CC::LO:
+ LowerBound = 1;
+ break;
+ case AArch64CC::LE:
+ case AArch64CC::LS:
+ case AArch64CC::GT:
+ case AArch64CC::HI:
+ UpperBound = 63;
+ break;
+ default:
+ break;
+ }
+
+ if (CN->getAPIntValue().uge(LowerBound) &&
+ CN->getAPIntValue().ult(UpperBound)) {
+ SDLoc DL(N);
+ Imm = CurDAG->getTargetConstant(CN->getZExtValue(), DL,
+ Bits == 32 ? MVT::i32 : MVT::i64);
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d51382b5e34e0..5b6166dc8fb96 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2983,8 +2983,7 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
MAKE_CASE(AArch64ISD::CTTZ_ELTS)
MAKE_CASE(AArch64ISD::CALL_ARM64EC_TO_X64)
MAKE_CASE(AArch64ISD::URSHR_I_PRED)
- MAKE_CASE(AArch64ISD::CBRR)
- MAKE_CASE(AArch64ISD::CBRI)
+ MAKE_CASE(AArch64ISD::CB)
}
#undef MAKE_CASE
return nullptr;
@@ -10600,49 +10599,10 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
if (Subtarget->hasCMPBR() &&
AArch64CC::isValidCBCond(changeIntCCToAArch64CC(CC)) &&
ProduceNonFlagSettingCondBr) {
- AArch64CC::CondCode ACC = changeIntCCToAArch64CC(CC);
- unsigned Opc = AArch64ISD::CBRR;
- if (auto *Imm = dyn_cast<ConstantSDNode>(RHS)) {
- // Check conservatively if the immediate fits the valid range [0, 64).
- // Immediate variants for GE and HS definitely need to be decremented
- // when lowering the pseudos later, so an immediate of 1 would become 0.
- // For the inverse conditions LT and LO we don't know for sure if they
- // will need a decrement but should the decision be made to reverse the
- // branch condition, we again end up with the need to decrement.
- // The same argument holds for LE, LS, GT and HI and possibly
- // incremented immediates. This can lead to slightly less optimal
- // codegen, e.g. we never codegen the legal case
- // cblt w0, #63, A
- // because we could end up with the illegal case
- // cbge w0, #64, B
- // should the decision to reverse the branch direction be made. For the
- // lower bound cases this is no problem since we can express comparisons
- // against 0 with either tbz/tnbz or using wzr/xzr.
- uint64_t LowerBound = 0, UpperBound = 64;
- switch (ACC) {
- case AArch64CC::GE:
- case AArch64CC::HS:
- case AArch64CC::LT:
- case AArch64CC::LO:
- LowerBound = 1;
- break;
- case AArch64CC::LE:
- case AArch64CC::LS:
- case AArch64CC::GT:
- case AArch64CC::HI:
- UpperBound = 63;
- break;
- default:
- break;
- }
-
- if (Imm->getAPIntValue().uge(LowerBound) &&
- Imm->getAPIntValue().ult(UpperBound))
- Opc = AArch64ISD::CBRI;
- }
-
- SDValue Cond = DAG.getTargetConstant(ACC, dl, MVT::i32);
- return DAG.getNode(Opc, dl, MVT::Other, Chain, Cond, LHS, RHS, Dest);
+ SDValue Cond =
+ DAG.getTargetConstant(changeIntCCToAArch64CC(CC), dl, MVT::i32);
+ return DAG.getNode(AArch64ISD::CB, dl, MVT::Other, Chain, Cond, LHS, RHS,
+ Dest);
}
SDValue CCVal;
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index c840ce0adbcec..1987c892ac080 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -531,8 +531,7 @@ enum NodeType : unsigned {
SME_ZA_STR,
// Compare-and-branch
- CBRR,
- CBRI,
+ CB,
};
} // end namespace AArch64ISD
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 7d29a05c5fb81..1469e00686bcc 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -400,6 +400,20 @@ def uimm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 64; }]> {
let ParserMatchClass = UImm6Operand;
}
+def CmpBranchUImm6Operand_32b
+ : Operand<i32>,
+ ComplexPattern<i32, 1, "SelectCmpBranchUImm6Operand<32>"> {
+ let ParserMatchClass = UImm6Operand;
+ let WantsParent = true;
+}
+
+def CmpBranchUImm6Operand_64b
+ : Operand<i64>,
+ ComplexPattern<i64, 1, "SelectCmpBranchUImm6Operand<64>"> {
+ let ParserMatchClass = UImm6Operand;
+ let WantsParent = true;
+}
+
def UImm6Plus1Operand : AsmOperandClass {
let Name = "UImm6P1";
let DiagnosticType = "InvalidImm1_64";
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 9b2b21c846ce9..b6171a8df4d6e 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -518,8 +518,9 @@ def SDT_AArch64TBL : SDTypeProfile<1, 2, [
SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>
]>;
-def SDT_AArch64cbrr : SDTypeProfile<0, 4, [SDTCisVT<0, i32>, SDTCisInt<1>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>]>;
-def SDT_AArch64cbri : SDTypeProfile<0, 4, [SDTCisVT<0, i32>, SDTCisInt<1>, SDTCisInt<2>, SDTCisVT<3, OtherVT>]>;
+def SDT_AArch64cb : SDTypeProfile<0, 4,
+ [SDTCisVT<0, i32>, SDTCisInt<1>, SDTCisInt<2>,
+ SDTCisVT<3, OtherVT>]>;
// non-extending masked load fragment.
def nonext_masked_load :
@@ -697,8 +698,7 @@ def topbitsallzero64: PatLeaf<(i64 GPR64:$src), [{
}]>;
// Node definitions.
-def AArch64CBrr : SDNode<"AArch64ISD::CBRR", SDT_AArch64cbrr, [SDNPHasChain]>;
-def AArch64CBri : SDNode<"AArch64ISD::CBRI", SDT_AArch64cbri, [SDNPHasChain]>;
+def AArch64CB : SDNode<"AArch64ISD::CB", SDT_AArch64cb, [SDNPHasChain]>;
def AArch64adrp : SDNode<"AArch64ISD::ADRP", SDTIntUnaryOp, []>;
def AArch64adr : SDNode<"AArch64ISD::ADR", SDTIntUnaryOp, []>;
def AArch64addlow : SDNode<"AArch64ISD::ADDlow", SDTIntBinOp, []>;
@@ -10552,15 +10552,18 @@ let Predicates = [HasCMPBR] in {
def CBWPri : CmpBranchImmediatePseudo<GPR32, uimm6_32b>;
def CBXPri : CmpBranchImmediatePseudo<GPR64, uimm6_64b>;
-def : Pat<(AArch64CBrr i32:$Cond, GPR32:$Rn, GPR32:$Rt, bb:$Target),
- (CBWPrr ccode:$Cond, GPR32:$Rn, GPR32:$Rt, am_brcmpcond:$Target)>;
-def : Pat<(AArch64CBrr i32:$Cond, GPR64:$Rn, GPR64:$Rt, bb:$Target),
- (CBXPrr ccode:$Cond, GPR64:$Rn, GPR64:$Rt, am_brcmpcond:$Target)>;
-def : Pat<(AArch64CBri i32:$Cond, GPR32:$Rn, i32:$Imm, bb:$Target),
- (CBWPri ccode:$Cond, GPR32:$Rn, uimm6_32b:$Imm, am_brcmpcond:$Target)>;
-def : Pat<(AArch64CBri i32:$Cond, GPR64:$Rn, i64:$Imm, bb:$Target),
- (CBXPri ccode:$Cond, GPR64:$Rn, uimm6_64b:$Imm, am_brcmpcond:$Target)>;
-
+ 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)>;
} // HasCMPBR
>From 0139ebe1044f616fc60ab736bd77561f5bed6338 Mon Sep 17 00:00:00 2001
From: David Tellenbach <dtellenbach at apple.com>
Date: Wed, 19 Feb 2025 11:16:17 -0800
Subject: [PATCH 4/4] Address review comments and add i64 bounds tests
---
.../Target/AArch64/AArch64ISelDAGToDAG.cpp | 12 +-
.../lib/Target/AArch64/AArch64InstrFormats.td | 8 +-
.../AArch64/cmpbr-reg-imm-at-bounds.ll | 412 +++++++++++++-----
3 files changed, 300 insertions(+), 132 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 9df50ef576faa..3ca9107cb2ce5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -508,7 +508,6 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
bool SelectAllActivePredicate(SDValue N);
bool SelectAnyPredicate(SDValue N);
- template <int Bits>
bool SelectCmpBranchUImm6Operand(SDNode *P, SDValue N, SDValue &Imm);
};
@@ -7493,14 +7492,10 @@ bool AArch64DAGToDAGISel::SelectSMETileSlice(SDValue N, unsigned MaxSize,
return true;
}
-template <int Bits>
bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *P, SDValue N,
SDValue &Imm) {
- ConstantSDNode *C = dyn_cast<ConstantSDNode>(P->getOperand(1));
- if (!C)
- return false;
-
- AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(C->getZExtValue());
+ AArch64CC::CondCode CC =
+ static_cast<AArch64CC::CondCode>(P->getConstantOperandVal(1));
if (auto *CN = dyn_cast<ConstantSDNode>(N)) {
// Check conservatively if the immediate fits the valid range [0, 64).
// Immediate variants for GE and HS definitely need to be decremented
@@ -7538,8 +7533,7 @@ bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *P, SDValue N,
if (CN->getAPIntValue().uge(LowerBound) &&
CN->getAPIntValue().ult(UpperBound)) {
SDLoc DL(N);
- Imm = CurDAG->getTargetConstant(CN->getZExtValue(), DL,
- Bits == 32 ? MVT::i32 : MVT::i64);
+ Imm = CurDAG->getTargetConstant(CN->getZExtValue(), DL, N.getValueType());
return true;
}
}
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 1469e00686bcc..feb77a5c2a12d 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -401,16 +401,12 @@ def uimm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 64; }]> {
}
def CmpBranchUImm6Operand_32b
- : Operand<i32>,
- ComplexPattern<i32, 1, "SelectCmpBranchUImm6Operand<32>"> {
- let ParserMatchClass = UImm6Operand;
+ : ComplexPattern<i32, 1, "SelectCmpBranchUImm6Operand", [imm]> {
let WantsParent = true;
}
def CmpBranchUImm6Operand_64b
- : Operand<i64>,
- ComplexPattern<i64, 1, "SelectCmpBranchUImm6Operand<64>"> {
- let ParserMatchClass = UImm6Operand;
+ : ComplexPattern<i64, 1, "SelectCmpBranchUImm6Operand", [imm]> {
let WantsParent = true;
}
diff --git a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
index 1b02b35e4f30e..d264cf2126099 100644
--- a/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
+++ b/llvm/test/CodeGen/AArch64/cmpbr-reg-imm-at-bounds.ll
@@ -4,8 +4,8 @@
; slt, sle, sgt, sge, ult, ule, ugt, uge, eq, ne
-define void @slt_0(i32 %a) {
-; CHECK-CMPBR-LABEL: slt_0:
+define void @slt_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: slt_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: tbnz w0, #31, LBB0_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -13,7 +13,7 @@ define void @slt_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB0_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: slt_0:
+; CHECK-NO-CMPBR-LABEL: slt_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: tbnz w0, #31, LBB0_2
; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -32,8 +32,8 @@ if.end:
ret void
}
-define void @slt_m1(i32 %a) {
-; CHECK-CMPBR-LABEL: slt_m1:
+define void @slt_m1_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: slt_m1_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #-2 ; =0xfffffffe
; CHECK-CMPBR-NEXT: cbge w8, w0, LBB1_2
@@ -42,7 +42,7 @@ define void @slt_m1(i32 %a) {
; CHECK-CMPBR-NEXT: LBB1_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: slt_m1:
+; CHECK-NO-CMPBR-LABEL: slt_m1_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmn w0, #2
; CHECK-NO-CMPBR-NEXT: b.le LBB1_2
@@ -62,8 +62,8 @@ if.end:
ret void
}
-define void @slt_63(i32 %a) {
-; CHECK-CMPBR-LABEL: slt_63:
+define void @slt_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: slt_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cblt w0, #63, LBB2_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -71,7 +71,7 @@ define void @slt_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB2_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: slt_63:
+; CHECK-NO-CMPBR-LABEL: slt_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #62
; CHECK-NO-CMPBR-NEXT: b.le LBB2_2
@@ -91,8 +91,8 @@ if.end:
ret void
}
-define void @slt_64(i32 %a) {
-; CHECK-CMPBR-LABEL: slt_64:
+define void @slt_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: slt_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #63 ; =0x3f
; CHECK-CMPBR-NEXT: cbge w8, w0, LBB3_2
@@ -101,7 +101,7 @@ define void @slt_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB3_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: slt_64:
+; CHECK-NO-CMPBR-LABEL: slt_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.le LBB3_2
@@ -121,8 +121,8 @@ if.end:
ret void
}
-define void @sle_0(i32 %a) {
-; CHECK-CMPBR-LABEL: sle_0:
+define void @sle_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sle_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cblt w0, #1, LBB4_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -130,7 +130,7 @@ define void @sle_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB4_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sle_0:
+; CHECK-NO-CMPBR-LABEL: sle_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #0
; CHECK-NO-CMPBR-NEXT: b.le LBB4_2
@@ -150,8 +150,8 @@ if.end:
ret void
}
-define void @sle_m1(i32 %a) {
-; CHECK-CMPBR-LABEL: sle_m1:
+define void @sle_m1_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sle_m1_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: tbnz w0, #31, LBB5_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -159,7 +159,7 @@ define void @sle_m1(i32 %a) {
; CHECK-CMPBR-NEXT: LBB5_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sle_m1:
+; CHECK-NO-CMPBR-LABEL: sle_m1_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: tbnz w0, #31, LBB5_2
; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -178,8 +178,8 @@ if.end:
ret void
}
-define void @sle_63(i32 %a) {
-; CHECK-CMPBR-LABEL: sle_63:
+define void @sle_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sle_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #63 ; =0x3f
; CHECK-CMPBR-NEXT: cbge w8, w0, LBB6_2
@@ -188,7 +188,7 @@ define void @sle_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB6_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sle_63:
+; CHECK-NO-CMPBR-LABEL: sle_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.le LBB6_2
@@ -208,8 +208,8 @@ if.end:
ret void
}
-define void @sle_64(i32 %a) {
-; CHECK-CMPBR-LABEL: sle_64:
+define void @sle_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sle_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbge w8, w0, LBB7_2
@@ -218,7 +218,7 @@ define void @sle_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB7_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sle_64:
+; CHECK-NO-CMPBR-LABEL: sle_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.le LBB7_2
@@ -238,8 +238,8 @@ if.end:
ret void
}
-define void @sgt_0(i32 %a) {
-; CHECK-CMPBR-LABEL: sgt_0:
+define void @sgt_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sgt_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbgt w0, #0, LBB8_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -247,7 +247,7 @@ define void @sgt_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB8_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sgt_0:
+; CHECK-NO-CMPBR-LABEL: sgt_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #1
; CHECK-NO-CMPBR-NEXT: b.ge LBB8_2
@@ -267,8 +267,8 @@ if.end:
ret void
}
-define void @sgt_m1(i32 %a) {
-; CHECK-CMPBR-LABEL: sgt_m1:
+define void @sgt_m1_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sgt_m1_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: tbz w0, #31, LBB9_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -276,7 +276,7 @@ define void @sgt_m1(i32 %a) {
; CHECK-CMPBR-NEXT: LBB9_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sgt_m1:
+; CHECK-NO-CMPBR-LABEL: sgt_m1_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: tbz w0, #31, LBB9_2
; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -295,8 +295,8 @@ if.end:
ret void
}
-define void @sgt_63(i32 %a) {
-; CHECK-CMPBR-LABEL: sgt_63:
+define void @sgt_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sgt_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbge w0, w8, LBB10_2
@@ -305,7 +305,7 @@ define void @sgt_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB10_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sgt_63:
+; CHECK-NO-CMPBR-LABEL: sgt_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.ge LBB10_2
@@ -325,8 +325,8 @@ if.end:
ret void
}
-define void @sgt_64(i32 %a) {
-; CHECK-CMPBR-LABEL: sgt_64:
+define void @sgt_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sgt_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #65 ; =0x41
; CHECK-CMPBR-NEXT: cbge w0, w8, LBB11_2
@@ -335,7 +335,7 @@ define void @sgt_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB11_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sgt_64:
+; CHECK-NO-CMPBR-LABEL: sgt_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #65
; CHECK-NO-CMPBR-NEXT: b.ge LBB11_2
@@ -355,8 +355,8 @@ if.end:
ret void
}
-define void @sge_0(i32 %a) {
-; CHECK-CMPBR-LABEL: sge_0:
+define void @sge_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sge_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: tbz w0, #31, LBB12_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -364,7 +364,7 @@ define void @sge_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB12_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sge_0:
+; CHECK-NO-CMPBR-LABEL: sge_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: tbz w0, #31, LBB12_2
; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -383,8 +383,8 @@ if.end:
ret void
}
-define void @sge_m1(i32 %a) {
-; CHECK-CMPBR-LABEL: sge_m1:
+define void @sge_m1_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sge_m1_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #-1 ; =0xffffffff
; CHECK-CMPBR-NEXT: cbge w0, w8, LBB13_2
@@ -393,7 +393,7 @@ define void @sge_m1(i32 %a) {
; CHECK-CMPBR-NEXT: LBB13_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sge_m1:
+; CHECK-NO-CMPBR-LABEL: sge_m1_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmn w0, #1
; CHECK-NO-CMPBR-NEXT: b.ge LBB13_2
@@ -413,8 +413,8 @@ if.end:
ret void
}
-define void @sge_63(i32 %a) {
-; CHECK-CMPBR-LABEL: sge_63:
+define void @sge_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sge_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbgt w0, #62, LBB14_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -422,7 +422,7 @@ define void @sge_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB14_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sge_63:
+; CHECK-NO-CMPBR-LABEL: sge_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.ge LBB14_2
@@ -442,8 +442,8 @@ if.end:
ret void
}
-define void @sge_64(i32 %a) {
-; CHECK-CMPBR-LABEL: sge_64:
+define void @sge_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: sge_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbge w0, w8, LBB15_2
@@ -452,7 +452,7 @@ define void @sge_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB15_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: sge_64:
+; CHECK-NO-CMPBR-LABEL: sge_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.ge LBB15_2
@@ -472,8 +472,8 @@ if.end:
ret void
}
-define void @ult_0(i32 %a) {
-; CHECK-CMPBR-LABEL: ult_0:
+define void @ult_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ult_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbhi wzr, w0, LBB16_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -481,7 +481,7 @@ define void @ult_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB16_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ult_0:
+; CHECK-NO-CMPBR-LABEL: ult_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #0
; CHECK-NO-CMPBR-NEXT: b.lo LBB16_2
@@ -501,8 +501,8 @@ if.end:
ret void
}
-define void @ult_63(i32 %a) {
-; CHECK-CMPBR-LABEL: ult_63:
+define void @ult_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ult_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cblo w0, #63, LBB17_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -510,7 +510,7 @@ define void @ult_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB17_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ult_63:
+; CHECK-NO-CMPBR-LABEL: ult_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #62
; CHECK-NO-CMPBR-NEXT: b.ls LBB17_2
@@ -530,8 +530,8 @@ if.end:
ret void
}
-define void @ult_64(i32 %a) {
-; CHECK-CMPBR-LABEL: ult_64:
+define void @ult_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ult_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #63 ; =0x3f
; CHECK-CMPBR-NEXT: cbhs w8, w0, LBB18_2
@@ -540,7 +540,7 @@ define void @ult_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB18_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ult_64:
+; CHECK-NO-CMPBR-LABEL: ult_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.ls LBB18_2
@@ -560,8 +560,8 @@ if.end:
ret void
}
-define void @ule_0(i32 %a) {
-; CHECK-CMPBR-LABEL: ule_0:
+define void @ule_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ule_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbz w0, LBB19_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -569,7 +569,7 @@ define void @ule_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB19_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ule_0:
+; CHECK-NO-CMPBR-LABEL: ule_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cbz w0, LBB19_2
; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -588,8 +588,8 @@ if.end:
ret void
}
-define void @ule_63(i32 %a) {
-; CHECK-CMPBR-LABEL: ule_63:
+define void @ule_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ule_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #63 ; =0x3f
; CHECK-CMPBR-NEXT: cbhs w8, w0, LBB20_2
@@ -598,7 +598,7 @@ define void @ule_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB20_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ule_63:
+; CHECK-NO-CMPBR-LABEL: ule_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.ls LBB20_2
@@ -618,8 +618,8 @@ if.end:
ret void
}
-define void @ule_64(i32 %a) {
-; CHECK-CMPBR-LABEL: ule_64:
+define void @ule_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ule_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbhs w8, w0, LBB21_2
@@ -628,7 +628,7 @@ define void @ule_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB21_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ule_64:
+; CHECK-NO-CMPBR-LABEL: ule_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.ls LBB21_2
@@ -648,8 +648,8 @@ if.end:
ret void
}
-define void @ugt_0(i32 %a) {
-; CHECK-CMPBR-LABEL: ugt_0:
+define void @ugt_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ugt_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbnz w0, LBB22_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -657,7 +657,7 @@ define void @ugt_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB22_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ugt_0:
+; CHECK-NO-CMPBR-LABEL: ugt_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cbnz w0, LBB22_2
; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -676,8 +676,8 @@ if.end:
ret void
}
-define void @ugt_63(i32 %a) {
-; CHECK-CMPBR-LABEL: ugt_63:
+define void @ugt_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ugt_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbhs w0, w8, LBB23_2
@@ -686,7 +686,7 @@ define void @ugt_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB23_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ugt_63:
+; CHECK-NO-CMPBR-LABEL: ugt_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.hs LBB23_2
@@ -706,8 +706,8 @@ if.end:
ret void
}
-define void @ugt_64(i32 %a) {
-; CHECK-CMPBR-LABEL: ugt_64:
+define void @ugt_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ugt_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #65 ; =0x41
; CHECK-CMPBR-NEXT: cbhs w0, w8, LBB24_2
@@ -716,7 +716,7 @@ define void @ugt_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB24_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ugt_64:
+; CHECK-NO-CMPBR-LABEL: ugt_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #65
; CHECK-NO-CMPBR-NEXT: b.hs LBB24_2
@@ -736,8 +736,8 @@ if.end:
ret void
}
-define void @uge_0(i32 %a) {
-; CHECK-CMPBR-LABEL: uge_0:
+define void @uge_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: uge_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbhs w0, wzr, LBB25_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -745,7 +745,7 @@ define void @uge_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB25_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: uge_0:
+; CHECK-NO-CMPBR-LABEL: uge_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #0
; CHECK-NO-CMPBR-NEXT: b.hs LBB25_2
@@ -765,8 +765,8 @@ if.end:
ret void
}
-define void @uge_63(i32 %a) {
-; CHECK-CMPBR-LABEL: uge_63:
+define void @uge_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: uge_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbhi w0, #62, LBB26_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -774,7 +774,7 @@ define void @uge_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB26_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: uge_63:
+; CHECK-NO-CMPBR-LABEL: uge_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.hs LBB26_2
@@ -794,8 +794,8 @@ if.end:
ret void
}
-define void @uge_64(i32 %a) {
-; CHECK-CMPBR-LABEL: uge_64:
+define void @uge_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: uge_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbhs w0, w8, LBB27_2
@@ -804,7 +804,7 @@ define void @uge_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB27_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: uge_64:
+; CHECK-NO-CMPBR-LABEL: uge_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.hs LBB27_2
@@ -824,8 +824,8 @@ if.end:
ret void
}
-define void @eq_0(i32 %a) {
-; CHECK-CMPBR-LABEL: eq_0:
+define void @eq_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: eq_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbz w0, LBB28_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -833,7 +833,7 @@ define void @eq_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB28_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: eq_0:
+; CHECK-NO-CMPBR-LABEL: eq_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cbz w0, LBB28_2
; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -852,8 +852,8 @@ if.end:
ret void
}
-define void @eq_m1(i32 %a) {
-; CHECK-CMPBR-LABEL: eq_m1:
+define void @eq_m1_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: eq_m1_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #-1 ; =0xffffffff
; CHECK-CMPBR-NEXT: cbeq w0, w8, LBB29_2
@@ -862,7 +862,7 @@ define void @eq_m1(i32 %a) {
; CHECK-CMPBR-NEXT: LBB29_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: eq_m1:
+; CHECK-NO-CMPBR-LABEL: eq_m1_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmn w0, #1
; CHECK-NO-CMPBR-NEXT: b.eq LBB29_2
@@ -882,8 +882,8 @@ if.end:
ret void
}
-define void @eq_63(i32 %a) {
-; CHECK-CMPBR-LABEL: eq_63:
+define void @eq_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: eq_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbeq w0, #63, LBB30_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -891,7 +891,7 @@ define void @eq_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB30_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: eq_63:
+; CHECK-NO-CMPBR-LABEL: eq_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.eq LBB30_2
@@ -911,8 +911,8 @@ if.end:
ret void
}
-define void @eq_64(i32 %a) {
-; CHECK-CMPBR-LABEL: eq_64:
+define void @eq_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: eq_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbeq w0, w8, LBB31_2
@@ -921,7 +921,7 @@ define void @eq_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB31_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: eq_64:
+; CHECK-NO-CMPBR-LABEL: eq_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.eq LBB31_2
@@ -941,8 +941,8 @@ if.end:
ret void
}
-define void @ne_0(i32 %a) {
-; CHECK-CMPBR-LABEL: ne_0:
+define void @ne_0_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ne_0_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbnz w0, LBB32_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -950,7 +950,7 @@ define void @ne_0(i32 %a) {
; CHECK-CMPBR-NEXT: LBB32_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ne_0:
+; CHECK-NO-CMPBR-LABEL: ne_0_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cbnz w0, LBB32_2
; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -969,8 +969,8 @@ if.end:
ret void
}
-define void @ne_m1(i32 %a) {
-; CHECK-CMPBR-LABEL: ne_m1:
+define void @ne_m1_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ne_m1_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #-1 ; =0xffffffff
; CHECK-CMPBR-NEXT: cbne w0, w8, LBB33_2
@@ -979,7 +979,7 @@ define void @ne_m1(i32 %a) {
; CHECK-CMPBR-NEXT: LBB33_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ne_m1:
+; CHECK-NO-CMPBR-LABEL: ne_m1_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmn w0, #1
; CHECK-NO-CMPBR-NEXT: b.ne LBB33_2
@@ -999,8 +999,8 @@ if.end:
ret void
}
-define void @ne_63(i32 %a) {
-; CHECK-CMPBR-LABEL: ne_63:
+define void @ne_63_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ne_63_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cbne w0, #63, LBB34_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
@@ -1008,7 +1008,7 @@ define void @ne_63(i32 %a) {
; CHECK-CMPBR-NEXT: LBB34_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ne_63:
+; CHECK-NO-CMPBR-LABEL: ne_63_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #63
; CHECK-NO-CMPBR-NEXT: b.ne LBB34_2
@@ -1028,8 +1028,8 @@ if.end:
ret void
}
-define void @ne_64(i32 %a) {
-; CHECK-CMPBR-LABEL: ne_64:
+define void @ne_64_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: ne_64_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
; CHECK-CMPBR-NEXT: cbne w0, w8, LBB35_2
@@ -1038,7 +1038,7 @@ define void @ne_64(i32 %a) {
; CHECK-CMPBR-NEXT: LBB35_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: ne_64:
+; CHECK-NO-CMPBR-LABEL: ne_64_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #64
; CHECK-NO-CMPBR-NEXT: b.ne LBB35_2
@@ -1058,8 +1058,8 @@ if.end:
ret void
}
-define void @cbge_out_of_upper_bound(i32 %a) {
-; CHECK-CMPBR-LABEL: cbge_out_of_upper_bound:
+define void @cbge_out_of_upper_bound_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbge_out_of_upper_bound_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #71 ; =0x47
; CHECK-CMPBR-NEXT: cbge w0, w8, LBB36_2
@@ -1068,7 +1068,7 @@ define void @cbge_out_of_upper_bound(i32 %a) {
; CHECK-CMPBR-NEXT: LBB36_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: cbge_out_of_upper_bound:
+; CHECK-NO-CMPBR-LABEL: cbge_out_of_upper_bound_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmp w0, #71
; CHECK-NO-CMPBR-NEXT: b.ge LBB36_2
@@ -1088,8 +1088,8 @@ if.end:
ret void
}
-define void @cbge_out_of_lower_bound(i32 %a) {
-; CHECK-CMPBR-LABEL: cbge_out_of_lower_bound:
+define void @cbge_out_of_lower_bound_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cbge_out_of_lower_bound_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #-10 ; =0xfffffff6
; CHECK-CMPBR-NEXT: cbge w0, w8, LBB37_2
@@ -1098,7 +1098,7 @@ define void @cbge_out_of_lower_bound(i32 %a) {
; CHECK-CMPBR-NEXT: LBB37_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: cbge_out_of_lower_bound:
+; CHECK-NO-CMPBR-LABEL: cbge_out_of_lower_bound_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmn w0, #10
; CHECK-NO-CMPBR-NEXT: b.ge LBB37_2
@@ -1119,8 +1119,8 @@ if.end:
}
; This should trigger a register swap.
-define void @cble_out_of_lower_bound(i32 %a) {
-; CHECK-CMPBR-LABEL: cble_out_of_lower_bound:
+define void @cble_out_of_lower_bound_i32(i32 %a) {
+; CHECK-CMPBR-LABEL: cble_out_of_lower_bound_i32:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: mov w8, #-10 ; =0xfffffff6
; CHECK-CMPBR-NEXT: cbhs w8, w0, LBB38_2
@@ -1129,7 +1129,7 @@ define void @cble_out_of_lower_bound(i32 %a) {
; CHECK-CMPBR-NEXT: LBB38_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
;
-; CHECK-NO-CMPBR-LABEL: cble_out_of_lower_bound:
+; CHECK-NO-CMPBR-LABEL: cble_out_of_lower_bound_i32:
; CHECK-NO-CMPBR: ; %bb.0: ; %entry
; CHECK-NO-CMPBR-NEXT: cmn w0, #10
; CHECK-NO-CMPBR-NEXT: b.ls LBB38_2
@@ -1148,3 +1148,181 @@ if.then:
if.end:
ret void
}
+
+define void @slt_m1_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: slt_m1_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov x8, #-2 ; =0xfffffffffffffffe
+; CHECK-CMPBR-NEXT: cbge x8, x0, LBB39_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB39_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: slt_m1_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn x0, #2
+; CHECK-NO-CMPBR-NEXT: b.le LBB39_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB39_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp slt i64 %a, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @sle_64_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: sle_64_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbge x8, x0, LBB40_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB40_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: sle_64_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #64
+; CHECK-NO-CMPBR-NEXT: b.le LBB40_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB40_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp sle i64 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ult_63_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: ult_63_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cblo x0, #63, LBB41_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB41_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ult_63_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #62
+; CHECK-NO-CMPBR-NEXT: b.ls LBB41_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB41_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ult i64 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @uge_64_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: uge_64_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov w8, #64 ; =0x40
+; CHECK-CMPBR-NEXT: cbhs x0, x8, LBB42_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB42_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: uge_64_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #64
+; CHECK-NO-CMPBR-NEXT: b.hs LBB42_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB42_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp uge i64 %a, 64
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @eq_m1_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: eq_m1_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: mov x8, #-1 ; =0xffffffffffffffff
+; CHECK-CMPBR-NEXT: cbeq x0, x8, LBB43_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB43_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: eq_m1_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmn x0, #1
+; CHECK-NO-CMPBR-NEXT: b.eq LBB43_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB43_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp eq i64 %a, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
+
+define void @ne_63_i64(i64 %a) {
+; CHECK-CMPBR-LABEL: ne_63_i64:
+; CHECK-CMPBR: ; %bb.0: ; %entry
+; CHECK-CMPBR-NEXT: cbne x0, #63, LBB44_2
+; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-CMPBR-NEXT: ret
+; CHECK-CMPBR-NEXT: LBB44_2: ; %if.then
+; CHECK-CMPBR-NEXT: brk #0x1
+;
+; CHECK-NO-CMPBR-LABEL: ne_63_i64:
+; CHECK-NO-CMPBR: ; %bb.0: ; %entry
+; CHECK-NO-CMPBR-NEXT: cmp x0, #63
+; CHECK-NO-CMPBR-NEXT: b.ne LBB44_2
+; CHECK-NO-CMPBR-NEXT: ; %bb.1: ; %if.end
+; CHECK-NO-CMPBR-NEXT: ret
+; CHECK-NO-CMPBR-NEXT: LBB44_2: ; %if.then
+; CHECK-NO-CMPBR-NEXT: brk #0x1
+entry:
+ %cmp = icmp ne i64 %a, 63
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @llvm.trap()
+ unreachable
+
+if.end:
+ ret void
+}
More information about the llvm-commits
mailing list