-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[RISCV] Add ISel patterns for Qualcomm uC Xqcicli extension #148121
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
Change-Id: I50a62db40ada7bc7f5233992d0d44f2840b1dac4
Change-Id: I4f96ecfbe7164981e543d8964db524990de0feab
@llvm/pr-subscribers-backend-risc-v Author: quic_hchandel (hchandel) ChangesAdd CodeGen patterns for conditional load immediate instructions Patch is 25.40 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/148121.diff 3 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index bf58226e0bd39..134b6df68bcad 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1488,6 +1488,9 @@ def HasVendorXqcics
AssemblerPredicate<(all_of FeatureVendorXqcics),
"'Xqcics' (Qualcomm uC Conditional Select Extension)">;
+def HasVendorXqcicsOrXqcicm
+ : Predicate<"Subtarget->hasVendorXqcics() || Subtarget->hasVendorXqcicm()">;
+
def FeatureVendorXqcicsr
: RISCVExperimentalExtension<0, 4, "Qualcomm uC CSR Extension">;
def HasVendorXqcicsr
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 6a1b8965b4e13..21d1125ed472a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1336,6 +1336,22 @@ class QCISELECTIICCPat<CondCode Cond, QCISELECTIICC Inst>
: Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rd), (XLenVT GPRNoX0:$rs1), Cond)), simm5:$simm1, simm5:$simm2),
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, simm5:$simm1, simm5:$simm2)>;
+class QCILICCPat<CondCode Cond, QCILICC Inst>
+ : Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), (XLenVT GPRNoX0:$rs2), Cond)), simm5:$simm, (XLenVT GPRNoX0:$rd)),
+ (Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm)>;
+
+class QCILICCPatInv<CondCode Cond, QCILICC Inst>
+ : Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), (XLenVT GPRNoX0:$rs2), Cond)), (XLenVT GPRNoX0:$rd), simm5:$simm),
+ (Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm)>;
+
+class QCILICCIPat<CondCode Cond, QCILICC Inst, DAGOperand InTyImm>
+ : Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), InTyImm:$imm, Cond)), simm5:$simm, (XLenVT GPRNoX0:$rd)),
+ (Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, simm5:$simm)>;
+
+class QCILICCIPatInv<CondCode Cond, QCILICC Inst, DAGOperand InTyImm>
+ : Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), InTyImm:$imm, Cond)), (XLenVT GPRNoX0:$rd), simm5:$simm),
+ (Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, simm5:$simm)>;
+
// 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),
@@ -1485,6 +1501,36 @@ def : QCIMVCCIPat <SETLT, QC_MVLTI, simm5>;
def : QCIMVCCIPat <SETULT, QC_MVLTUI, uimm5>;
}
+let Predicates = [HasVendorXqcicli, HasVendorXqcicsOrXqcicm, IsRV32] in {
+def : QCILICCPat <SETEQ, QC_LIEQ>;
+def : QCILICCPat <SETNE, QC_LINE>;
+def : QCILICCPat <SETLT, QC_LILT>;
+def : QCILICCPat <SETGE, QC_LIGE>;
+def : QCILICCPat <SETULT, QC_LILTU>;
+def : QCILICCPat <SETUGE, QC_LIGEU>;
+
+def : QCILICCIPat <SETEQ, QC_LIEQI, simm5>;
+def : QCILICCIPat <SETNE, QC_LINEI, simm5>;
+def : QCILICCIPat <SETLT, QC_LILTI, simm5>;
+def : QCILICCIPat <SETGE, QC_LIGEI, simm5>;
+def : QCILICCIPat <SETULT, QC_LILTUI, uimm5>;
+def : QCILICCIPat <SETUGE, QC_LIGEUI, uimm5>;
+
+def : QCILICCPatInv <SETNE, QC_LIEQ>;
+def : QCILICCPatInv <SETEQ, QC_LINE>;
+def : QCILICCPatInv <SETGE, QC_LILT>;
+def : QCILICCPatInv <SETLT, QC_LIGE>;
+def : QCILICCPatInv <SETUGE, QC_LILTU>;
+def : QCILICCPatInv <SETULT, QC_LIGEU>;
+
+def : QCILICCIPatInv <SETNE, QC_LIEQI, simm5>;
+def : QCILICCIPatInv <SETEQ, QC_LINEI, simm5>;
+def : QCILICCIPatInv <SETGE, QC_LILTI, simm5>;
+def : QCILICCIPatInv <SETLT, QC_LIGEI, simm5>;
+def : QCILICCIPatInv <SETUGE, QC_LILTUI, uimm5>;
+def : QCILICCIPatInv <SETULT, QC_LIGEUI, uimm5>;
+}
+
let Predicates = [HasVendorXqcics, IsRV32] in {
def : Pat<(select (XLenVT GPRNoX0:$rd), (XLenVT GPRNoX0:$rs2),(XLenVT GPRNoX0:$rs3)),
(QC_SELECTNEI GPRNoX0:$rd, (XLenVT 0), GPRNoX0:$rs2, GPRNoX0:$rs3)>;
diff --git a/llvm/test/CodeGen/RISCV/xqcicli.ll b/llvm/test/CodeGen/RISCV/xqcicli.ll
new file mode 100644
index 0000000000000..b0d51429556ef
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/xqcicli.ll
@@ -0,0 +1,717 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test that we are able to generate the Xqcicli instructions
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=RV32I
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicli,+experimental-xqcics -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=RV32IXQCICLI
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicli,+experimental-xqcicm -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=RV32IXQCICLI
+
+define i32 @select_cc_example_eq(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_eq:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: bne a1, a2, .LBB0_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB0_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_eq:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lieq a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp eq i32 %b, %x
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ne(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ne:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: beq a1, a2, .LBB1_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB1_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_ne:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.line a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ne i32 %b, %x
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_slt(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_slt:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: bge a1, a2, .LBB2_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB2_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_slt:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lilt a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp slt i32 %b, %x
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_sge(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_sge:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: blt a1, a2, .LBB3_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB3_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_sge:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lige a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp sge i32 %b, %x
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_uge(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_uge:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: bltu a1, a2, .LBB4_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB4_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_uge:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.ligeu a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp uge i32 %b, %x
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ult(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ult:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: bgeu a1, a2, .LBB5_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB5_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_ult:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.liltu a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ult i32 %b, %x
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_eq_c(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_eq_c:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: beq a1, a2, .LBB6_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB6_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_eq_c:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.line a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp eq i32 %b, %x
+ %sel = select i1 %cmp, i32 %a, i32 11
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ne_c(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ne_c:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: bne a1, a2, .LBB7_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB7_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_ne_c:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lieq a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ne i32 %b, %x
+ %sel = select i1 %cmp, i32 %a, i32 11
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_slt_c(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_slt_c:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: blt a1, a2, .LBB8_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB8_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_slt_c:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lige a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp slt i32 %b, %x
+ %sel = select i1 %cmp, i32 %a, i32 11
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_sge_c(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_sge_c:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: bge a1, a2, .LBB9_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB9_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_sge_c:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lilt a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp sge i32 %b, %x
+ %sel = select i1 %cmp, i32 %a, i32 11
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_uge_c(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_uge_c:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: bgeu a1, a2, .LBB10_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB10_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_uge_c:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.liltu a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp uge i32 %b, %x
+ %sel = select i1 %cmp, i32 %a, i32 11
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ult_c(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ult_c:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: bltu a1, a2, .LBB11_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB11_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_ult_c:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.ligeu a0, a1, a2, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ult i32 %b, %x
+ %sel = select i1 %cmp, i32 %a, i32 11
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_eqi(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_eqi:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: bne a1, a2, .LBB12_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB12_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_eqi:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lieqi a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp eq i32 %b, 12
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_nei(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_nei:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: beq a1, a2, .LBB13_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB13_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_nei:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.linei a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ne i32 %b, 12
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_slti(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_slti:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: bge a1, a2, .LBB14_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB14_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_slti:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lilti a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp slt i32 %b, 12
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_sgei(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_sgei:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 11
+; RV32I-NEXT: bge a2, a1, .LBB15_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB15_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_sgei:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.ligei a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp sge i32 %b, 12
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ulti(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ulti:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: bgeu a1, a2, .LBB16_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB16_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_ulti:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.liltui a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ult i32 %b, 12
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ugei(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ugei:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 11
+; RV32I-NEXT: bgeu a2, a1, .LBB17_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB17_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_ugei:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.ligeui a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp uge i32 %b, 12
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_eqi_c1(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_eqi_c1:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: bne a1, a2, .LBB18_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB18_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_eqi_c1:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lieqi a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp eq i32 12, %b
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_nei_c1(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_nei_c1:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: beq a1, a2, .LBB19_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB19_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_nei_c1:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.linei a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ne i32 12, %b
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_slti_c1(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_slti_c1:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: bge a2, a1, .LBB20_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB20_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_slti_c1:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.ligei a0, a1, 13, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp slt i32 12, %b
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_sgei_c1(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_sgei_c1:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 13
+; RV32I-NEXT: bge a1, a2, .LBB21_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB21_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_sgei_c1:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lilti a0, a1, 13, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp sge i32 12, %b
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ulti_c1(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ulti_c1:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: bgeu a2, a1, .LBB22_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB22_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_ulti_c1:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.ligeui a0, a1, 13, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ult i32 12, %b
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_ugei_c1(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_ugei_c1:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 13
+; RV32I-NEXT: bgeu a1, a2, .LBB23_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB23_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_ugei_c1:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.liltui a0, a1, 13, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp uge i32 12, %b
+ %sel = select i1 %cmp, i32 11, i32 %a
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_eqi_c2(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_eqi_c2:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: beq a1, a2, .LBB24_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB24_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_eqi_c2:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.linei a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp eq i32 12, %b
+ %sel = select i1 %cmp, i32 %a, i32 11
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_nei_c2(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_nei_c2:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: bne a1, a2, .LBB25_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB25_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_nei_c2:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lieqi a0, a1, 12, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp ne i32 12, %b
+ %sel = select i1 %cmp, i32 %a, i32 11
+ ret i32 %sel
+}
+
+define i32 @select_cc_example_slti_c2(i32 %a, i32 %b, i32 %x, i32 %y) {
+; RV32I-LABEL: select_cc_example_slti_c2:
+; RV32I: # %bb.0: # %entry
+; RV32I-NEXT: li a2, 12
+; RV32I-NEXT: blt a2, a1, .LBB26_2
+; RV32I-NEXT: # %bb.1: # %entry
+; RV32I-NEXT: li a0, 11
+; RV32I-NEXT: .LBB26_2: # %entry
+; RV32I-NEXT: ret
+;
+; RV32IXQCICLI-LABEL: select_cc_example_slti_c2:
+; RV32IXQCICLI: # %bb.0: # %entry
+; RV32IXQCICLI-NEXT: qc.lilti a0, a1, 13, 11
+; RV32IXQCICLI-NEXT: ret
+entry:
+ %cmp = icmp slt i32 12, %b
+ %se...
[truncated]
|
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.
@@ -1485,6 +1501,36 @@ def : QCIMVCCIPat <SETLT, QC_MVLTI, simm5>; | |||
def : QCIMVCCIPat <SETULT, QC_MVLTUI, uimm5>; | |||
} | |||
|
|||
let Predicates = [HasVendorXqcicli, HasVendorXqcicsOrXqcicm, IsRV32] in { |
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.
Why do we need this?
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.
It's complex and a comment would be helpful, so maybe I'll sketch one out.
These patterns are written using select
, which is normally not legal on RISC-V. We cannot mark select
as legal when we only have xqcicli
, because we cannot isel a select of a condition and two arbitrary xlen values (in registers) when we only have xqcicli
(there is no instruction in the extension that can do so).
But we only care about codegen for configs where we have both xqcics/xqcicm and xqcicli - we can sort-of see xqcicli as an optimisation of the other two. If we have either of the other two, then we have marked select
as legal and we can lower a select
with a condition and two xlen values (in registers).
These patterns would only be used if we have one of the other two extensions, so make that clear with their predicates.
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.
I'm curious why you want select to be legal for any of the Xqc instructions. It looks like select_cc (either the RISCVISD version or the ISD version) is a better match for the ISA.
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.
I advised towards this way because I felt our best aim was to try to keep to standard nodes (which is why i avoided riscvisd::select_cc
), and to try to keep to what was mostly already happening in RISC-V (which is why i avoided isd::select_cc
), but evidently that instinct isn't quite right.
I would like to proceed with this approach for this patch, and later we can refactor to riscvisd::select_cc
, I think.
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.
I would like to proceed with this approach for this patch, and later we can refactor to riscvisd::select_cc, I think.
I'm fine with that.
; Test that we are able to generate the Xqcicli instructions | ||
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ | ||
; RUN: | FileCheck %s --check-prefixes=RV32I | ||
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicli,+experimental-xqcics -verify-machineinstrs < %s \ |
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.
What about a RUN line with only xqcicli enable?
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.
See the other comment above, but the thing here is we need at least one of xqcics or xqcicm, for select to be marked legal and the patterns to be able to apply.
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
Change-Id: Iecd0bdb4fc58e98154824a726cf51ae5f0606502
Add CodeGen patterns for conditional load immediate instructions