-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Add isel patterns for generating Xqcibi branch instructions #139872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-risc-v Author: Sudharsan Veeravalli (svs-quic) ChangesAdd ISEL patterns for generating the Xqcibi branch immediate instructions. Similar to #135771 adds new CondCodes for the various branch instructions and uses them to return the appropriate instruction. Patch is 22.94 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/139872.diff 5 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c01496c9a7f3a..282b848c9a330 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2389,6 +2389,8 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
if (auto *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
int64_t C = RHSC->getSExtValue();
+ const RISCVSubtarget &Subtarget =
+ DAG.getMachineFunction().getSubtarget<RISCVSubtarget>();
switch (CC) {
default: break;
case ISD::SETGT:
@@ -2398,6 +2400,13 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
CC = ISD::SETGE;
return;
}
+ if (Subtarget.hasVendorXqcibi() && 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.
@@ -2408,6 +2417,15 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
return;
}
break;
+ case ISD::SETUGT:
+ if (Subtarget.hasVendorXqcibi() && 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;
}
}
@@ -21203,6 +21221,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 f181c1e137545..a4f33546b01ac 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -993,6 +993,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;
}
}
@@ -1050,6 +1074,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;
}
}
@@ -1077,6 +1125,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;
}
}
@@ -1452,6 +1524,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:
@@ -2633,6 +2717,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;
@@ -2660,6 +2747,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;
@@ -2679,6 +2769,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;
@@ -2691,6 +2784,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..5e8f8f2956dc0 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<riscv_selectcc, [{
+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+ int64_t Imm = dyn_cast<ConstantSDNode>(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<PatFrag StoreOp, RVInst Inst>
: 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<CondCode Cond, QCIBranchInst_rii Inst, DAGOperand InTyImm>
+ : Pat<(riscv_brcc (XLenVT GPRNoX0:$rs1), InTyImm:$rs2, Cond, bb:$imm12),
+ (Inst GPRNoX0:$rs1, InTyImm:$rs2, bare_simm13_lsb0:$imm12)>;
+
+class Bcci48Pat<CondCode Cond, QCIBranchInst48_rii Inst, DAGOperand InTyImm>
+ : 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<CondCode Cond, DAGOperand InTyImm, Pseudo OpNode >
+ : 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<ushlsat, QC_SHLUSAT>;
def : PatGprNoX0GprNoX0<sshlsat, QC_SHLSAT>;
} // Predicates = [HasVendorXqcia, IsRV32]
+/// Branches
+
+let Predicates = [HasVendorXqcibi, IsRV32], AddedComplexity = 2 in {
+def : BcciPat<SETEQ, QC_BEQI, simm5nonzero>;
+def : BcciPat<SETNE, QC_BNEI, simm5nonzero>;
+def : BcciPat<SETLT, QC_BLTI, simm5nonzero>;
+def : BcciPat<SETGE, QC_BGEI, simm5nonzero>;
+def : BcciPat<SETULT, QC_BLTUI, uimm5nonzero>;
+def : BcciPat<SETUGE, QC_BGEUI, uimm5nonzero>;
+
+def : Bcci48Pat<SETEQ, QC_E_BEQI, simm16nonzero>;
+def : Bcci48Pat<SETNE, QC_E_BNEI, simm16nonzero>;
+def : Bcci48Pat<SETLT, QC_E_BLTI, simm16nonzero>;
+def : Bcci48Pat<SETGE, QC_E_BGEI, simm16nonzero>;
+def : Bcci48Pat<SETULT, QC_E_BLTUI, uimm16nonzero>;
+def : Bcci48Pat<SETUGE, QC_E_BGEUI, uimm16nonzero>;
+
+def : SelectQCbi<SETEQ, simm5nonzero, Select_GPR_Using_CC_Simm5NonZero>;
+def : SelectQCbi<SETNE, simm5nonzero, Select_GPR_Using_CC_Simm5NonZero>;
+def : SelectQCbi<SETLT, simm5nonzero, Select_GPR_Using_CC_Simm5NonZero>;
+def : SelectQCbi<SETGE, simm5nonzero, Select_GPR_Using_CC_Simm5NonZero>;
+def : SelectQCbi<SETULT, uimm5nonzero, Select_GPR_Using_CC_Uimm5NonZero>;
+def : SelectQCbi<SETUGE, uimm5nonzero, Select_GPR_Using_CC_Uimm5NonZero>;
+
+def : SelectQCbi<SETEQ, simm16nonzero, Select_GPR_Using_CC_Simm16NonZero>;
+def : SelectQCbi<SETNE, simm16nonzero, Select_GPR_Using_CC_Simm16NonZero>;
+def : SelectQCbi<SETLT, simm16nonzero, Select_GPR_Using_CC_Simm16NonZero>;
+def : SelectQCbi<SETGE, simm16nonzero, Select_GPR_Using_CC_Simm16NonZero>;
+def : SelectQCbi<SETULT, uimm16nonzero, Select_GPR_Using_CC_Uimm16NonZero>;
+def : SelectQCbi<SETUGE, uimm16nonzero, Select_GPR_Using_CC_Uimm16NonZero>;
+} // 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...
[truncated]
|
@topperc do the changes look good to you? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…instructions Similar to llvm#139872. This patch adds isel patterns to match `riscv_brcc` and `riscv_selectcc_frag` to XAndesPerf branch instructions.
Add ISEL patterns for generating the Xqcibi branch immediate instructions. Similar to #135771 adds new CondCodes for the various branch instructions and uses them to return the appropriate instruction.