From 55a4f0f7eeb16726b6a1c390ee689bdd4bc1a8b1 Mon Sep 17 00:00:00 2001 From: David Tellenbach 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(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(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 { def : InstAlias(insn # "Xrr") GPR64:$Rm, GPR64:$Rt, am_brcmpcond:$target), 0>; } + +class CmpBranchRegisterPseudo + : Pseudo<(outs), (ins ccode:$Cond, regtype:$Rt, regtype:$Rm, am_brcmpcond:$Target), []>, + Sched<[WriteBr]> { + let isBranch = 1; + let isTerminator = 1; +} + +class CmpBranchImmediatePseudo + : 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 + CBDisplacementBits("aarch64-cb-offset-bits", cl::Hidden, cl::init(9), + cl::desc("Restrict range of CB instructions (DEBUG)")); + static cl::opt 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(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(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; defm : PromoteBinaryv8f16Tov4f32; defm : PromoteBinaryv8f16Tov4f32; +//===----------------------------------------------------------------------===// +// 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; + def CBXPrr : CmpBranchRegisterPseudo; + def CBWPri : CmpBranchImmediatePseudo; + def CBXPri : CmpBranchImmediatePseudo; + +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 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 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 + 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 +bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *P, SDValue N, + SDValue &Imm) { + ConstantSDNode *C = dyn_cast(P->getOperand(1)); + if (!C) + return false; + + AArch64CC::CondCode CC = static_cast(C->getZExtValue()); + if (auto *CN = dyn_cast(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(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, ImmLeaf= 0 && Imm < 64; }]> { let ParserMatchClass = UImm6Operand; } +def CmpBranchUImm6Operand_32b + : Operand, + ComplexPattern"> { + let ParserMatchClass = UImm6Operand; + let WantsParent = true; +} + +def CmpBranchUImm6Operand_64b + : Operand, + ComplexPattern"> { + 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; def CBXPri : CmpBranchImmediatePseudo; -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 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 bool SelectCmpBranchUImm6Operand(SDNode *P, SDValue N, SDValue &Imm); }; @@ -7493,14 +7492,10 @@ bool AArch64DAGToDAGISel::SelectSMETileSlice(SDValue N, unsigned MaxSize, return true; } -template bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *P, SDValue N, SDValue &Imm) { - ConstantSDNode *C = dyn_cast(P->getOperand(1)); - if (!C) - return false; - - AArch64CC::CondCode CC = static_cast(C->getZExtValue()); + AArch64CC::CondCode CC = + static_cast(P->getConstantOperandVal(1)); if (auto *CN = dyn_cast(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, ImmLeaf= 0 && Imm < 64; }]> { } def CmpBranchUImm6Operand_32b - : Operand, - ComplexPattern"> { - let ParserMatchClass = UImm6Operand; + : ComplexPattern { let WantsParent = true; } def CmpBranchUImm6Operand_64b - : Operand, - ComplexPattern"> { - let ParserMatchClass = UImm6Operand; + : ComplexPattern { 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 +}