Skip to content

Commit dda7ce6

Browse files
authored
[RISCV] Move Xqci Select-likes to use riscv_selectcc (#153147)
The original patterns for the Xqci select-like instructions used `select`, and marked that ISD node as legal. This is not the usual way that `select` is dealt with in the RISC-V backend. Usually on RISC-V, we expand `select` to `riscv_select_cc` which holds references to the operands of the comparison and the possible values depending on the comparison. In retrospect, this is a much better fit for our instructions, as most of them correspond to specific condition codes, rather than more generic `select` with a truthy/falsey value. This PR moves the Xqci select-like patterns to use `riscv_select_cc` nodes. This applies to the Xqcicm, Xqcics and Xqcicli instruction patterns. In order to match the existing codegen, minor additions had to be made to `translateSetCCForBranch` to ensure that comparisons against specific immediate values are left in a form that can be matched more closely by the instructions. This prevents having to insert additional `li` instructions and use the register forms. There are a few slight regressions: - There are sometimes more `mv` instructions than entirely necessary. I believe these would not be seen with larger examples where the register allocator has more leeway. - In some tests where just one of the three extensions is enabled, codegen falls back to using a branch over a move. With all three extensions enabled (the configuration we most care about), these are not seen. - The generated patterns are very similar to each other - they have similar complexity (7 or 8) and there are still overlaps. Sometimes the choice between two instructions can be affected by the order of the patterns in the tablegen file. One other change is that Xqcicm instructions are prioritised over Xqcics instructions where they have identical patterns. This is done because one of the the Xqcicm instructions is compressible (`qc.mveqi`), while none of the Xqcics instructions are.
1 parent 339450f commit dda7ce6

File tree

11 files changed

+1959
-221
lines changed

11 files changed

+1959
-221
lines changed

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,18 +1498,15 @@ def HasVendorXqcicm
14981498
: Predicate<"Subtarget->hasVendorXqcicm()">,
14991499
AssemblerPredicate<(all_of FeatureVendorXqcicm),
15001500
"'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
1501+
def NoVendorXqcicm
1502+
: Predicate<"!Subtarget->hasVendorXqcicm()">;
15011503

15021504
def FeatureVendorXqcics
15031505
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Conditional Select Extension">;
15041506
def HasVendorXqcics
15051507
: Predicate<"Subtarget->hasVendorXqcics()">,
15061508
AssemblerPredicate<(all_of FeatureVendorXqcics),
15071509
"'Xqcics' (Qualcomm uC Conditional Select Extension)">;
1508-
def NoVendorXqcics
1509-
: Predicate<"!Subtarget->hasVendorXqcics()">;
1510-
1511-
def HasVendorXqcicsOrXqcicm
1512-
: Predicate<"Subtarget->hasVendorXqcics() || Subtarget->hasVendorXqcicm()">;
15131510

15141511
def FeatureVendorXqcicsr
15151512
: RISCVExperimentalExtension<0, 4, "Qualcomm uC CSR Extension">;

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
434434
setOperationAction(ISD::ABS, MVT::i32, Custom);
435435
}
436436

437-
if (!Subtarget.useCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov() &&
438-
!Subtarget.hasVendorXqcicm() && !Subtarget.hasVendorXqcics())
437+
if (!Subtarget.useCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov())
439438
setOperationAction(ISD::SELECT, XLenVT, Custom);
440439

441440
if (Subtarget.hasVendorXqcia() && !Subtarget.is64Bit()) {
@@ -2506,6 +2505,14 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
25062505
CC = ISD::SETGE;
25072506
return;
25082507
}
2508+
if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
2509+
C != INT64_MAX && isInt<5>(C + 1)) {
2510+
// We have a conditional move instruction for SETGE but not SETGT.
2511+
// Convert X > C to X >= C + 1, if (C + 1) is a 5-bit signed immediate.
2512+
RHS = DAG.getSignedConstant(C + 1, DL, RHS.getValueType());
2513+
CC = ISD::SETGE;
2514+
return;
2515+
}
25092516
if (Subtarget.hasVendorXqcibi() && C != INT64_MAX && isInt<16>(C + 1)) {
25102517
// We have a branch immediate instruction for SETGE but not SETGT.
25112518
// Convert X > C to X >= C + 1, if (C + 1) is a 16-bit signed immediate.
@@ -2524,6 +2531,14 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
25242531
}
25252532
break;
25262533
case ISD::SETUGT:
2534+
if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
2535+
C != INT64_MAX && isUInt<5>(C + 1)) {
2536+
// We have a conditional move instruction for SETUGE but not SETUGT.
2537+
// Convert X > C to X >= C + 1, if (C + 1) is a 5-bit signed immediate.
2538+
RHS = DAG.getConstant(C + 1, DL, RHS.getValueType());
2539+
CC = ISD::SETUGE;
2540+
return;
2541+
}
25272542
if (Subtarget.hasVendorXqcibi() && C != INT64_MAX && isUInt<16>(C + 1)) {
25282543
// We have a branch immediate instruction for SETUGE but not SETUGT.
25292544
// Convert X > C to X >= C + 1, if (C + 1) is a 16-bit unsigned

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 86 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,51 +1343,51 @@ class QCScaledStPat<PatFrag StoreOp, RVInst Inst>
13431343
(Inst GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt)>;
13441344

13451345
class QCIMVCCPat<CondCode Cond, QCIMVCC Inst>
1346-
: Pat<(select (i32 (setcc (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2), Cond)), (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd)),
1346+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2), Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
13471347
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs3)>;
13481348

13491349
class QCIMVCCIPat<CondCode Cond, QCIMVCCI Inst, DAGOperand InTyImm>
1350-
: Pat<(select (i32 (setcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond)), (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd)),
1350+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
13511351
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, GPRNoX0:$rs3)>;
13521352

13531353
class QCISELECTCCIPat<CondCode Cond, QCISELECTCCI Inst>
1354-
: Pat<(select (i32 (setcc (i32 GPRNoX0:$rd), simm5:$imm, Cond)), (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3)),
1354+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), simm5:$imm, Cond, (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3))),
13551355
(Inst GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, GPRNoX0:$rs3)>;
13561356

13571357
class QCISELECTICCIPat<CondCode Cond, QCISELECTICCI Inst>
1358-
: Pat<(select (i32 (setcc (i32 GPRNoX0:$rd), simm5:$imm, Cond)), (i32 GPRNoX0:$rs2), simm5:$simm2),
1358+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), simm5:$imm, Cond, (i32 GPRNoX0:$rs2), simm5:$simm2)),
13591359
(Inst GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, simm5:$simm2)>;
13601360

13611361
class QCISELECTICCIPatInv<CondCode Cond, QCISELECTICCI Inst>
1362-
: Pat<(select (i32 (setcc (i32 GPRNoX0:$rd), simm5:$imm, Cond)), simm5:$simm2, (i32 GPRNoX0:$rs2)),
1362+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), simm5:$imm, Cond, simm5:$simm2, (i32 GPRNoX0:$rs2))),
13631363
(Inst GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, simm5:$simm2)>;
13641364

13651365
class QCISELECTICCPat<CondCode Cond, QCISELECTICC Inst>
1366-
: Pat<(select (i32 (setcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond)), (i32 GPRNoX0:$rs2), simm5:$simm2),
1366+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond, (i32 GPRNoX0:$rs2), simm5:$simm2)),
13671367
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm2)>;
13681368

13691369
class QCISELECTICCPatInv<CondCode Cond, QCISELECTICC Inst>
1370-
: Pat<(select (i32 (setcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond)), simm5:$simm2, (i32 GPRNoX0:$rs2)),
1370+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond, simm5:$simm2, (i32 GPRNoX0:$rs2))),
13711371
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm2)>;
13721372

13731373
class QCISELECTIICCPat<CondCode Cond, QCISELECTIICC Inst>
1374-
: Pat<(select (i32 (setcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond)), simm5:$simm1, simm5:$simm2),
1374+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs1), Cond, simm5:$simm1, simm5:$simm2)),
13751375
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, simm5:$simm1, simm5:$simm2)>;
13761376

13771377
class QCILICCPat<CondCode Cond, QCILICC Inst>
1378-
: Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), (XLenVT GPRNoX0:$rs2), Cond)), simm5:$simm, (XLenVT GPRNoX0:$rd)),
1378+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2), Cond, simm5:$simm, (i32 GPRNoX0:$rd))),
13791379
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm)>;
13801380

13811381
class QCILICCPatInv<CondCode Cond, QCILICC Inst>
1382-
: Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), (XLenVT GPRNoX0:$rs2), Cond)), (XLenVT GPRNoX0:$rd), simm5:$simm),
1382+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2), Cond, (i32 GPRNoX0:$rd), simm5:$simm)),
13831383
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, GPRNoX0:$rs2, simm5:$simm)>;
13841384

13851385
class QCILICCIPat<CondCode Cond, QCILICC Inst, DAGOperand InTyImm>
1386-
: Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), InTyImm:$imm, Cond)), simm5:$simm, (XLenVT GPRNoX0:$rd)),
1386+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond, simm5:$simm, (i32 GPRNoX0:$rd))),
13871387
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, simm5:$simm)>;
13881388

13891389
class QCILICCIPatInv<CondCode Cond, QCILICC Inst, DAGOperand InTyImm>
1390-
: Pat<(select (XLenVT (setcc (XLenVT GPRNoX0:$rs1), InTyImm:$imm, Cond)), (XLenVT GPRNoX0:$rd), simm5:$simm),
1390+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond, (i32 GPRNoX0:$rd), simm5:$simm)),
13911391
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, simm5:$simm)>;
13921392

13931393
// Match `riscv_brcc` and lower to the appropriate XQCIBI branch instruction.
@@ -1539,81 +1539,93 @@ let Predicates = [HasVendorXqciint, IsRV32] in
15391539
def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>;
15401540

15411541
let Predicates = [HasVendorXqcicm, IsRV32] in {
1542-
def : Pat<(select (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rd),(i32 GPRNoX0:$rs3)),
1543-
(QC_MVEQI GPRNoX0:$rd, GPRNoX0:$rs1, (i32 0), GPRNoX0:$rs3)>;
1544-
1545-
def : QCIMVCCPat <SETEQ, QC_MVEQ>;
1546-
def : QCIMVCCPat <SETNE, QC_MVNE>;
1547-
def : QCIMVCCPat <SETLT, QC_MVLT>;
1548-
def : QCIMVCCPat <SETULT, QC_MVLTU>;
1549-
1550-
def : QCIMVCCIPat <SETLT, QC_MVLTI, simm5>;
1551-
def : QCIMVCCIPat <SETULT, QC_MVLTUI, uimm5>;
1552-
}
1553-
1554-
// Prioritize Xqcics over these patterns.
1555-
let Predicates = [HasVendorXqcicm, NoVendorXqcics, IsRV32] in {
1556-
def : QCIMVCCIPat <SETEQ, QC_MVEQI, simm5>;
1557-
def : QCIMVCCIPat <SETNE, QC_MVNEI, simm5>;
1542+
// (SELECT X, Y, Z) is canonicalised to `(riscv_selectcc x, 0, NE, y, z)`.
1543+
// This exists to prioritise over the `Select_GPR_Using_CC_GPR` pattern.
1544+
def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), SETNE, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
1545+
(QC_MVNEI GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;
1546+
def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), SETEQ, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
1547+
(QC_MVEQI GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;
1548+
1549+
def : QCIMVCCPat<SETEQ, QC_MVEQ>;
1550+
def : QCIMVCCPat<SETNE, QC_MVNE>;
1551+
def : QCIMVCCPat<SETLT, QC_MVLT>;
1552+
def : QCIMVCCPat<SETULT, QC_MVLTU>;
1553+
def : QCIMVCCPat<SETGE, QC_MVGE>;
1554+
def : QCIMVCCPat<SETUGE, QC_MVGEU>;
1555+
1556+
def : QCIMVCCIPat<SETEQ, QC_MVEQI, simm5>;
1557+
def : QCIMVCCIPat<SETNE, QC_MVNEI, simm5>;
1558+
def : QCIMVCCIPat<SETLT, QC_MVLTI, simm5>;
1559+
def : QCIMVCCIPat<SETULT, QC_MVLTUI, uimm5>;
1560+
def : QCIMVCCIPat<SETGE, QC_MVGEI, simm5>;
1561+
def : QCIMVCCIPat<SETUGE, QC_MVGEUI, uimm5>;
15581562
}
15591563

1560-
let Predicates = [HasVendorXqcicli, HasVendorXqcicsOrXqcicm, IsRV32] in {
1561-
def : QCILICCPat <SETEQ, QC_LIEQ>;
1562-
def : QCILICCPat <SETNE, QC_LINE>;
1563-
def : QCILICCPat <SETLT, QC_LILT>;
1564-
def : QCILICCPat <SETGE, QC_LIGE>;
1565-
def : QCILICCPat <SETULT, QC_LILTU>;
1566-
def : QCILICCPat <SETUGE, QC_LIGEU>;
1567-
1568-
def : QCILICCIPat <SETEQ, QC_LIEQI, simm5>;
1569-
def : QCILICCIPat <SETNE, QC_LINEI, simm5>;
1570-
def : QCILICCIPat <SETLT, QC_LILTI, simm5>;
1571-
def : QCILICCIPat <SETGE, QC_LIGEI, simm5>;
1572-
def : QCILICCIPat <SETULT, QC_LILTUI, uimm5>;
1573-
def : QCILICCIPat <SETUGE, QC_LIGEUI, uimm5>;
1574-
1575-
def : QCILICCPatInv <SETNE, QC_LIEQ>;
1576-
def : QCILICCPatInv <SETEQ, QC_LINE>;
1577-
def : QCILICCPatInv <SETGE, QC_LILT>;
1578-
def : QCILICCPatInv <SETLT, QC_LIGE>;
1579-
def : QCILICCPatInv <SETUGE, QC_LILTU>;
1580-
def : QCILICCPatInv <SETULT, QC_LIGEU>;
1581-
1582-
def : QCILICCIPatInv <SETNE, QC_LIEQI, simm5>;
1583-
def : QCILICCIPatInv <SETEQ, QC_LINEI, simm5>;
1584-
def : QCILICCIPatInv <SETGE, QC_LILTI, simm5>;
1585-
def : QCILICCIPatInv <SETLT, QC_LIGEI, simm5>;
1586-
def : QCILICCIPatInv <SETUGE, QC_LILTUI, uimm5>;
1587-
def : QCILICCIPatInv <SETULT, QC_LIGEUI, uimm5>;
1588-
}
1564+
let Predicates = [HasVendorXqcicli, IsRV32] in {
1565+
def : QCILICCPat<SETEQ, QC_LIEQ>;
1566+
def : QCILICCPat<SETNE, QC_LINE>;
1567+
def : QCILICCPat<SETLT, QC_LILT>;
1568+
def : QCILICCPat<SETGE, QC_LIGE>;
1569+
def : QCILICCPat<SETULT, QC_LILTU>;
1570+
def : QCILICCPat<SETUGE, QC_LIGEU>;
1571+
1572+
def : QCILICCIPat<SETEQ, QC_LIEQI, simm5>;
1573+
def : QCILICCIPat<SETNE, QC_LINEI, simm5>;
1574+
def : QCILICCIPat<SETLT, QC_LILTI, simm5>;
1575+
def : QCILICCIPat<SETGE, QC_LIGEI, simm5>;
1576+
def : QCILICCIPat<SETULT, QC_LILTUI, uimm5>;
1577+
def : QCILICCIPat<SETUGE, QC_LIGEUI, uimm5>;
1578+
1579+
def : QCILICCPatInv<SETNE, QC_LIEQ>;
1580+
def : QCILICCPatInv<SETEQ, QC_LINE>;
1581+
def : QCILICCPatInv<SETGE, QC_LILT>;
1582+
def : QCILICCPatInv<SETLT, QC_LIGE>;
1583+
def : QCILICCPatInv<SETUGE, QC_LILTU>;
1584+
def : QCILICCPatInv<SETULT, QC_LIGEU>;
1585+
1586+
def : QCILICCIPatInv<SETNE, QC_LIEQI, simm5>;
1587+
def : QCILICCIPatInv<SETEQ, QC_LINEI, simm5>;
1588+
def : QCILICCIPatInv<SETGE, QC_LILTI, simm5>;
1589+
def : QCILICCIPatInv<SETLT, QC_LIGEI, simm5>;
1590+
def : QCILICCIPatInv<SETUGE, QC_LILTUI, uimm5>;
1591+
def : QCILICCIPatInv<SETULT, QC_LIGEUI, uimm5>;
1592+
} // Predicates = [HasVendorXqcicli, IsRV32]
15891593

15901594
let Predicates = [HasVendorXqcics, IsRV32] in {
1591-
def : Pat<(select (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs2),(i32 GPRNoX0:$rs3)),
1592-
(QC_SELECTNEI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, GPRNoX0:$rs3)>;
1593-
def : Pat<(select (i32 GPRNoX0:$rd), (i32 GPRNoX0:$rs2), simm5:$simm2),
1595+
// (SELECT X, Y, Z) is canonicalised to `(riscv_selectcc x, 0, NE, y, z)`.
1596+
// These exist to prioritise over the `Select_GPR_Using_CC_GPR` pattern.
1597+
def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 0), SETNE, (i32 GPRNoX0:$rs2), simm5:$simm2)),
15941598
(QC_SELECTINEI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, simm5:$simm2)>;
1595-
def : Pat<(select (i32 GPRNoX0:$rd), simm5:$simm2,(i32 GPRNoX0:$rs2)),
1599+
def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 0), SETNE, simm5:$simm2, (i32 GPRNoX0:$rs2))),
15961600
(QC_SELECTIEQI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, simm5:$simm2)>;
15971601

1598-
def : QCISELECTCCIPat <SETEQ, QC_SELECTEQI>;
1599-
def : QCISELECTCCIPat <SETNE, QC_SELECTNEI>;
1600-
1601-
def : QCISELECTICCIPat <SETEQ, QC_SELECTIEQI>;
1602-
def : QCISELECTICCIPat <SETNE, QC_SELECTINEI>;
1602+
def : QCISELECTICCIPat<SETEQ, QC_SELECTIEQI>;
1603+
def : QCISELECTICCIPat<SETNE, QC_SELECTINEI>;
16031604

1604-
def : QCISELECTICCIPatInv <SETEQ, QC_SELECTINEI>;
1605-
def : QCISELECTICCIPatInv <SETNE, QC_SELECTIEQI>;
1605+
def : QCISELECTICCIPatInv<SETEQ, QC_SELECTINEI>;
1606+
def : QCISELECTICCIPatInv<SETNE, QC_SELECTIEQI>;
16061607

1607-
def : QCISELECTICCPat <SETEQ, QC_SELECTIEQ>;
1608-
def : QCISELECTICCPat <SETNE, QC_SELECTINE>;
1608+
def : QCISELECTICCPat<SETEQ, QC_SELECTIEQ>;
1609+
def : QCISELECTICCPat<SETNE, QC_SELECTINE>;
16091610

1610-
def : QCISELECTICCPatInv <SETEQ, QC_SELECTINE>;
1611-
def : QCISELECTICCPatInv <SETNE, QC_SELECTIEQ>;
1611+
def : QCISELECTICCPatInv<SETEQ, QC_SELECTINE>;
1612+
def : QCISELECTICCPatInv<SETNE, QC_SELECTIEQ>;
16121613

1613-
def : QCISELECTIICCPat <SETEQ, QC_SELECTIIEQ>;
1614-
def : QCISELECTIICCPat <SETNE, QC_SELECTIINE>;
1614+
def : QCISELECTIICCPat<SETEQ, QC_SELECTIIEQ>;
1615+
def : QCISELECTIICCPat<SETNE, QC_SELECTIINE>;
16151616
} // Predicates = [HasVendorXqcics, IsRV32]
16161617

1618+
// Prioritize Xqcicm over these patterns, because Xqcicm is compressible.
1619+
let Predicates = [HasVendorXqcics, NoVendorXqcicm, IsRV32] in {
1620+
def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 0), SETNE, (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3))),
1621+
(QC_SELECTNEI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, GPRNoX0:$rs3)>;
1622+
def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), (i32 0), SETEQ, (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3))),
1623+
(QC_SELECTEQI GPRNoX0:$rd, (i32 0), GPRNoX0:$rs2, GPRNoX0:$rs3)>;
1624+
1625+
def : QCISELECTCCIPat<SETEQ, QC_SELECTEQI>;
1626+
def : QCISELECTCCIPat<SETNE, QC_SELECTNEI>;
1627+
}
1628+
16171629
let Predicates = [HasVendorXqcilsm, IsRV32] in {
16181630
def : Pat<(qc_setwmi GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7),
16191631
(QC_SETWMI GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7)>;

llvm/test/CodeGen/RISCV/select-bare.ll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
; RUN: | FileCheck %s -check-prefix=RV32I
44
; RUN: llc -mtriple=riscv64 -mattr=+xmipscmov -verify-machineinstrs < %s \
55
; RUN: | FileCheck -check-prefix=RV64I-CCMOV %s
6+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
7+
; RUN: | FileCheck %s --check-prefixes=RV32IXQCI
68

79
define i32 @bare_select(i1 %a, i32 %b, i32 %c) nounwind {
810
; RV32I-LABEL: bare_select:
@@ -20,6 +22,13 @@ define i32 @bare_select(i1 %a, i32 %b, i32 %c) nounwind {
2022
; RV64I-CCMOV-NEXT: andi a0, a0, 1
2123
; RV64I-CCMOV-NEXT: mips.ccmov a0, a0, a1, a2
2224
; RV64I-CCMOV-NEXT: ret
25+
;
26+
; RV32IXQCI-LABEL: bare_select:
27+
; RV32IXQCI: # %bb.0:
28+
; RV32IXQCI-NEXT: andi a0, a0, 1
29+
; RV32IXQCI-NEXT: qc.mvnei a2, a0, 0, a1
30+
; RV32IXQCI-NEXT: mv a0, a2
31+
; RV32IXQCI-NEXT: ret
2332
%1 = select i1 %a, i32 %b, i32 %c
2433
ret i32 %1
2534
}
@@ -40,6 +49,13 @@ define float @bare_select_float(i1 %a, float %b, float %c) nounwind {
4049
; RV64I-CCMOV-NEXT: andi a0, a0, 1
4150
; RV64I-CCMOV-NEXT: mips.ccmov a0, a0, a1, a2
4251
; RV64I-CCMOV-NEXT: ret
52+
;
53+
; RV32IXQCI-LABEL: bare_select_float:
54+
; RV32IXQCI: # %bb.0:
55+
; RV32IXQCI-NEXT: andi a0, a0, 1
56+
; RV32IXQCI-NEXT: qc.mvnei a2, a0, 0, a1
57+
; RV32IXQCI-NEXT: mv a0, a2
58+
; RV32IXQCI-NEXT: ret
4359
%1 = select i1 %a, float %b, float %c
4460
ret float %1
4561
}

0 commit comments

Comments
 (0)