diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index c56877b9fcfe4..bc4cce4e27b21 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -2400,6 +2400,8 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS, if (auto *RHSC = dyn_cast(RHS)) { int64_t C = RHSC->getSExtValue(); + const RISCVSubtarget &Subtarget = + DAG.getMachineFunction().getSubtarget(); switch (CC) { default: break; case ISD::SETGT: @@ -2409,6 +2411,13 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS, CC = ISD::SETGE; return; } + if (Subtarget.hasVendorXqcibi() && C != INT64_MAX && isInt<16>(C + 1)) { + // We have a branch immediate instruction for SETGE but not SETGT. + // Convert X > C to X >= C + 1, if (C + 1) is a 16-bit signed immediate. + RHS = DAG.getSignedConstant(C + 1, DL, RHS.getValueType()); + CC = ISD::SETGE; + return; + } break; case ISD::SETLT: // Convert X < 1 to 0 >= X. @@ -2419,6 +2428,16 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS, return; } break; + case ISD::SETUGT: + if (Subtarget.hasVendorXqcibi() && C != INT64_MAX && isInt<16>(C + 1) && + C != -1) { + // We have a branch immediate instruction for SETUGE but not SETUGT. + // Convert X > C to X >= C + 1, if (C + 1) is a 16-bit signed immediate. + RHS = DAG.getSignedConstant(C + 1, DL, RHS.getValueType()); + CC = ISD::SETUGE; + return; + } + break; } } @@ -21298,6 +21317,10 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, return emitReadCounterWidePseudo(MI, BB); case RISCV::Select_GPR_Using_CC_GPR: case RISCV::Select_GPR_Using_CC_Imm: + case RISCV::Select_GPR_Using_CC_Simm5NonZero: + case RISCV::Select_GPR_Using_CC_Uimm5NonZero: + case RISCV::Select_GPR_Using_CC_Simm16NonZero: + case RISCV::Select_GPR_Using_CC_Uimm16NonZero: case RISCV::Select_FPR16_Using_CC_GPR: case RISCV::Select_FPR16INX_Using_CC_GPR: case RISCV::Select_FPR32_Using_CC_GPR: diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 87e6248a38693..317c7d8d74801 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -977,6 +977,30 @@ static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc) { return RISCVCC::COND_CV_BEQIMM; case RISCV::CV_BNEIMM: return RISCVCC::COND_CV_BNEIMM; + case RISCV::QC_BEQI: + return RISCVCC::COND_QC_BEQI; + case RISCV::QC_E_BEQI: + return RISCVCC::COND_QC_E_BEQI; + case RISCV::QC_BNEI: + return RISCVCC::COND_QC_BNEI; + case RISCV::QC_E_BNEI: + return RISCVCC::COND_QC_E_BNEI; + case RISCV::QC_BLTI: + return RISCVCC::COND_QC_BLTI; + case RISCV::QC_E_BLTI: + return RISCVCC::COND_QC_E_BLTI; + case RISCV::QC_BGEI: + return RISCVCC::COND_QC_BGEI; + case RISCV::QC_E_BGEI: + return RISCVCC::COND_QC_E_BGEI; + case RISCV::QC_BLTUI: + return RISCVCC::COND_QC_BLTUI; + case RISCV::QC_E_BLTUI: + return RISCVCC::COND_QC_E_BLTUI; + case RISCV::QC_BGEUI: + return RISCVCC::COND_QC_BGEUI; + case RISCV::QC_E_BGEUI: + return RISCVCC::COND_QC_E_BGEUI; } } @@ -1034,6 +1058,30 @@ unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC) { return RISCV::CV_BEQIMM; case RISCVCC::COND_CV_BNEIMM: return RISCV::CV_BNEIMM; + case RISCVCC::COND_QC_BEQI: + return RISCV::QC_BEQI; + case RISCVCC::COND_QC_E_BEQI: + return RISCV::QC_E_BEQI; + case RISCVCC::COND_QC_BNEI: + return RISCV::QC_BNEI; + case RISCVCC::COND_QC_E_BNEI: + return RISCV::QC_E_BNEI; + case RISCVCC::COND_QC_BLTI: + return RISCV::QC_BLTI; + case RISCVCC::COND_QC_E_BLTI: + return RISCV::QC_E_BLTI; + case RISCVCC::COND_QC_BGEI: + return RISCV::QC_BGEI; + case RISCVCC::COND_QC_E_BGEI: + return RISCV::QC_E_BGEI; + case RISCVCC::COND_QC_BLTUI: + return RISCV::QC_BLTUI; + case RISCVCC::COND_QC_E_BLTUI: + return RISCV::QC_E_BLTUI; + case RISCVCC::COND_QC_BGEUI: + return RISCV::QC_BGEUI; + case RISCVCC::COND_QC_E_BGEUI: + return RISCV::QC_E_BGEUI; } } @@ -1061,6 +1109,30 @@ RISCVCC::CondCode RISCVCC::getOppositeBranchCondition(RISCVCC::CondCode CC) { return RISCVCC::COND_CV_BNEIMM; case RISCVCC::COND_CV_BNEIMM: return RISCVCC::COND_CV_BEQIMM; + case RISCVCC::COND_QC_BEQI: + return RISCVCC::COND_QC_BNEI; + case RISCVCC::COND_QC_E_BEQI: + return RISCVCC::COND_QC_E_BNEI; + case RISCVCC::COND_QC_BNEI: + return RISCVCC::COND_QC_BEQI; + case RISCVCC::COND_QC_E_BNEI: + return RISCVCC::COND_QC_E_BEQI; + case RISCVCC::COND_QC_BLTI: + return RISCVCC::COND_QC_BGEI; + case RISCVCC::COND_QC_E_BLTI: + return RISCVCC::COND_QC_E_BGEI; + case RISCVCC::COND_QC_BGEI: + return RISCVCC::COND_QC_BLTI; + case RISCVCC::COND_QC_E_BGEI: + return RISCVCC::COND_QC_E_BLTI; + case RISCVCC::COND_QC_BLTUI: + return RISCVCC::COND_QC_BGEUI; + case RISCVCC::COND_QC_E_BLTUI: + return RISCVCC::COND_QC_E_BGEUI; + case RISCVCC::COND_QC_BGEUI: + return RISCVCC::COND_QC_BLTUI; + case RISCVCC::COND_QC_E_BGEUI: + return RISCVCC::COND_QC_E_BLTUI; } } @@ -1436,6 +1508,18 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp, case RISCV::BGEU: case RISCV::CV_BEQIMM: case RISCV::CV_BNEIMM: + case RISCV::QC_BEQI: + case RISCV::QC_BNEI: + case RISCV::QC_BGEI: + case RISCV::QC_BLTI: + case RISCV::QC_BLTUI: + case RISCV::QC_BGEUI: + case RISCV::QC_E_BEQI: + case RISCV::QC_E_BNEI: + case RISCV::QC_E_BGEI: + case RISCV::QC_E_BLTI: + case RISCV::QC_E_BLTUI: + case RISCV::QC_E_BGEUI: return isIntN(13, BrOffset); case RISCV::JAL: case RISCV::PseudoBR: @@ -2617,6 +2701,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_UIMM5_LSB0: Ok = isShiftedUInt<4, 1>(Imm); break; + case RISCVOp::OPERAND_UIMM5_NONZERO: + Ok = isUInt<5>(Imm) && (Imm != 0); + break; case RISCVOp::OPERAND_UIMM6_LSB0: Ok = isShiftedUInt<5, 1>(Imm); break; @@ -2644,6 +2731,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_UIMM10_LSB00_NONZERO: Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0); break; + case RISCVOp::OPERAND_UIMM16_NONZERO: + Ok = isUInt<16>(Imm) && (Imm != 0); + break; case RISCVOp::OPERAND_ZERO: Ok = Imm == 0; break; @@ -2663,6 +2753,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_SIMM5_PLUS1: Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16; break; + case RISCVOp::OPERAND_SIMM5_NONZERO: + Ok = isInt<5>(Imm) && (Imm != 0); + break; case RISCVOp::OPERAND_SIMM6_NONZERO: Ok = Imm != 0 && isInt<6>(Imm); break; @@ -2675,6 +2768,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_SIMM12_LSB00000: Ok = isShiftedInt<7, 5>(Imm); break; + case RISCVOp::OPERAND_SIMM16_NONZERO: + Ok = isInt<16>(Imm) && (Imm != 0); + break; case RISCVOp::OPERAND_SIMM20_LI: Ok = isInt<20>(Imm); break; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h index 1ec6eed82469e..b099acd81e995 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h @@ -43,6 +43,18 @@ enum CondCode { COND_GEU, COND_CV_BEQIMM, COND_CV_BNEIMM, + COND_QC_BEQI, + COND_QC_BNEI, + COND_QC_BLTI, + COND_QC_BGEI, + COND_QC_BLTUI, + COND_QC_BGEUI, + COND_QC_E_BEQI, + COND_QC_E_BNEI, + COND_QC_E_BLTI, + COND_QC_E_BGEI, + COND_QC_E_BLTUI, + COND_QC_E_BGEUI, COND_INVALID }; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 57c1e999ac366..5c109d03d78d5 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -188,6 +188,36 @@ def AddLike: PatFrags<(ops node:$A, node:$B), def AddShl : PatFrag<(ops node:$Ra, node:$Rb, node:$SH3), (add node:$Ra, (shl node:$Rb, node:$SH3))>; +def IntCCtoQCRISCVCC : SDNodeXForm(N->getOperand(2))->get(); + int64_t Imm = cast(N->getOperand(1))->getSExtValue(); + RISCVCC::CondCode BrCC; + switch (CC) { + default: + report_fatal_error("Unexpected CondCode for Xqcibi branch instructions"); + case ISD::SETEQ: + BrCC = isInt<5>(Imm) ? RISCVCC::COND_QC_BEQI : RISCVCC::COND_QC_E_BEQI; + break; + case ISD::SETNE: + BrCC = isInt<5>(Imm) ? RISCVCC::COND_QC_BNEI : RISCVCC::COND_QC_E_BNEI; + break; + case ISD::SETLT: + BrCC = isInt<5>(Imm) ? RISCVCC::COND_QC_BLTI : RISCVCC::COND_QC_E_BLTI; + break; + case ISD::SETGE: + BrCC = isInt<5>(Imm) ? RISCVCC::COND_QC_BGEI : RISCVCC::COND_QC_E_BGEI; + break; + case ISD::SETULT: + BrCC = isUInt<5>(Imm) ? RISCVCC::COND_QC_BLTUI : RISCVCC::COND_QC_E_BLTUI; + break; + case ISD::SETUGE: + BrCC = isUInt<5>(Imm) ? RISCVCC::COND_QC_BGEUI : RISCVCC::COND_QC_E_BGEUI; + break; + } + return CurDAG->getTargetConstant(BrCC, SDLoc(N), Subtarget->getXLenVT()); +}]>; + + //===----------------------------------------------------------------------===// // Instruction Formats //===----------------------------------------------------------------------===// @@ -1288,6 +1318,36 @@ class QCScaledStPat : Pat<(StoreOp (i32 GPR:$rd), (AddShl (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt)), (Inst GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt)>; +// Match `riscv_brcc` and lower to the appropriate XQCIBI branch instruction. +class BcciPat + : Pat<(riscv_brcc (XLenVT GPRNoX0:$rs1), InTyImm:$rs2, Cond, bb:$imm12), + (Inst GPRNoX0:$rs1, InTyImm:$rs2, bare_simm13_lsb0:$imm12)>; + +class Bcci48Pat + : Pat<(riscv_brcc (XLenVT GPRNoX0:$rs1), InTyImm:$rs2, Cond, bb:$imm12), + (Inst GPRNoX0:$rs1, InTyImm:$rs2, bare_simm13_lsb0:$imm12)>; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, usesCustomInserter = 1 in { + def Select_GPR_Using_CC_Simm5NonZero : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, simm5nonzero:$imm5, + cond_code:$cc, GPR:$truev, GPR:$falsev), []>; + def Select_GPR_Using_CC_Uimm5NonZero : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, uimm5nonzero:$imm5, + cond_code:$cc, GPR:$truev, GPR:$falsev), []>; + def Select_GPR_Using_CC_Simm16NonZero : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, simm16nonzero:$imm16, + cond_code:$cc, GPR:$truev, GPR:$falsev), []>; + def Select_GPR_Using_CC_Uimm16NonZero : Pseudo<(outs GPR:$dst), + (ins GPR:$lhs, uimm16nonzero:$imm16, + cond_code:$cc, GPR:$truev, GPR:$falsev), []>; +} + +class SelectQCbi + : Pat<(riscv_selectcc_frag:$cc (i32 GPR:$lhs), InTyImm:$Constant, Cond, + (i32 GPR:$truev), GPR:$falsev), + (OpNode GPR:$lhs, InTyImm:$Constant, + (IntCCtoQCRISCVCC $cc), GPR:$truev, GPR:$falsev)>; + /// Simple arithmetic operations let Predicates = [HasVendorXqcilia, IsRV32] in { @@ -1342,6 +1402,38 @@ def : PatGprNoX0GprNoX0; def : PatGprNoX0GprNoX0; } // Predicates = [HasVendorXqcia, IsRV32] +/// Branches + +let Predicates = [HasVendorXqcibi, IsRV32], AddedComplexity = 2 in { +def : BcciPat; +def : BcciPat; +def : BcciPat; +def : BcciPat; +def : BcciPat; +def : BcciPat; + +def : Bcci48Pat; +def : Bcci48Pat; +def : Bcci48Pat; +def : Bcci48Pat; +def : Bcci48Pat; +def : Bcci48Pat; + +def : SelectQCbi; +def : SelectQCbi; +def : SelectQCbi; +def : SelectQCbi; +def : SelectQCbi; +def : SelectQCbi; + +def : SelectQCbi; +def : SelectQCbi; +def : SelectQCbi; +def : SelectQCbi; +def : SelectQCbi; +def : SelectQCbi; +} // let Predicates = [HasVendorXqcibi, IsRV32], AddedComplexity = 2 + let Predicates = [HasVendorXqciint, IsRV32] in def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>; diff --git a/llvm/test/CodeGen/RISCV/xqcibi.ll b/llvm/test/CodeGen/RISCV/xqcibi.ll new file mode 100644 index 0000000000000..242012b5ad462 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/xqcibi.ll @@ -0,0 +1,359 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; Test that we are able to generate the Xqcibi instructions +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck %s --check-prefixes=RV32I +; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcibi -verify-machineinstrs < %s \ +; RUN: | FileCheck %s --check-prefixes=RV32IXQCIBI + +define i32 @beqimm(i32 %a) { +; RV32I-LABEL: beqimm: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, -16 +; RV32I-NEXT: beq a0, a1, .LBB0_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB0_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: beqimm: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.beqi a0, -16, .LBB0_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB0_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp eq i32 %a, -16 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bneimm(i32 %a) { +; RV32I-LABEL: bneimm: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, 15 +; RV32I-NEXT: bne a0, a1, .LBB1_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB1_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bneimm: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.bnei a0, 15, .LBB1_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB1_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp ne i32 %a, 15 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bltimm(i32 %a) { +; RV32I-LABEL: bltimm: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, 5 +; RV32I-NEXT: blt a0, a1, .LBB2_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB2_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bltimm: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.blti a0, 5, .LBB2_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB2_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp slt i32 %a, 5 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bgeimm(i32 %a) { +; RV32I-LABEL: bgeimm: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, -6 +; RV32I-NEXT: blt a1, a0, .LBB3_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB3_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bgeimm: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.bgei a0, -5, .LBB3_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB3_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp sge i32 %a, -5 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bltuimm(i32 %a) { +; RV32I-LABEL: bltuimm: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, 31 +; RV32I-NEXT: bltu a0, a1, .LBB4_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB4_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bltuimm: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.bltui a0, 31, .LBB4_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB4_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp ult i32 %a, 31 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bgeuimm(i32 %a) { +; RV32I-LABEL: bgeuimm: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, 9 +; RV32I-NEXT: bltu a1, a0, .LBB5_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB5_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bgeuimm: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.bgeui a0, 10, .LBB5_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB5_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp uge i32 %a, 10 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @beqimm16(i32 %a) { +; RV32I-LABEL: beqimm16: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 1048568 +; RV32I-NEXT: beq a0, a1, .LBB6_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB6_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: beqimm16: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.e.beqi a0, -32768, .LBB6_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB6_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp eq i32 %a, -32768 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bneimm16(i32 %a) { +; RV32I-LABEL: bneimm16: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 8 +; RV32I-NEXT: addi a1, a1, -1 +; RV32I-NEXT: bne a0, a1, .LBB7_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB7_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bneimm16: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.e.bnei a0, 32767, .LBB7_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB7_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp ne i32 %a, 32767 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bltimm16(i32 %a) { +; RV32I-LABEL: bltimm16: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, -35 +; RV32I-NEXT: blt a0, a1, .LBB8_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB8_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bltimm16: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.e.blti a0, -35, .LBB8_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB8_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp slt i32 %a, -35 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bgeimm16(i32 %a) { +; RV32I-LABEL: bgeimm16: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, 254 +; RV32I-NEXT: blt a1, a0, .LBB9_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB9_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bgeimm16: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.e.bgei a0, 255, .LBB9_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB9_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp sge i32 %a, 255 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bltuimm16(i32 %a) { +; RV32I-LABEL: bltuimm16: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 16 +; RV32I-NEXT: addi a1, a1, -1 +; RV32I-NEXT: bltu a0, a1, .LBB10_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB10_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bltuimm16: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.e.bltui a0, 65535, .LBB10_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB10_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp ult i32 %a, 65535 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + +define i32 @bgeuimm16(i32 %a) { +; RV32I-LABEL: bgeuimm16: +; RV32I: # %bb.0: +; RV32I-NEXT: li a1, 99 +; RV32I-NEXT: bltu a1, a0, .LBB11_2 +; RV32I-NEXT: # %bb.1: # %f +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB11_2: # %t +; RV32I-NEXT: li a0, 1 +; RV32I-NEXT: ret +; +; RV32IXQCIBI-LABEL: bgeuimm16: +; RV32IXQCIBI: # %bb.0: +; RV32IXQCIBI-NEXT: qc.e.bgeui a0, 100, .LBB11_2 +; RV32IXQCIBI-NEXT: # %bb.1: # %f +; RV32IXQCIBI-NEXT: li a0, 0 +; RV32IXQCIBI-NEXT: ret +; RV32IXQCIBI-NEXT: .LBB11_2: # %t +; RV32IXQCIBI-NEXT: li a0, 1 +; RV32IXQCIBI-NEXT: ret + %1 = icmp uge i32 %a, 100 + br i1 %1, label %t, label %f, !prof !0 +f: + ret i32 0 +t: + ret i32 1 +} + + +!0 = !{!"branch_weights", i32 1, i32 99}