Skip to content

Commit ead88c7

Browse files
authored
[RISCV] Prefer (select (x < 0), y, z) -> x >> (XLEN - 1) & (y - z) + z even with Zicond. (#125772)
The Zicond version of this requires an li instruction and an additional register. Without Zicond we match this in a DAGCombine on RISCVISD::SELECT_CC. This PR has 2 commits. I'll pre-commit the test change if this looks good.
1 parent 6e17ed9 commit ead88c7

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8460,6 +8460,33 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
84608460
if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
84618461
const APInt &TrueVal = TrueV->getAsAPIntVal();
84628462
const APInt &FalseVal = FalseV->getAsAPIntVal();
8463+
8464+
// Prefer these over Zicond to avoid materializing an immediate:
8465+
// (select (x < 0), y, z) -> x >> (XLEN - 1) & (y - z) + z
8466+
// (select (x > -1), z, y) -> x >> (XLEN - 1) & (y - z) + z
8467+
if (CondV.getOpcode() == ISD::SETCC &&
8468+
CondV.getOperand(0).getValueType() == VT && CondV.hasOneUse()) {
8469+
ISD::CondCode CCVal = cast<CondCodeSDNode>(CondV.getOperand(2))->get();
8470+
if ((CCVal == ISD::SETLT && isNullConstant(CondV.getOperand(1))) ||
8471+
(CCVal == ISD::SETGT && isAllOnesConstant(CondV.getOperand(1)))) {
8472+
int64_t TrueImm = TrueVal.getSExtValue();
8473+
int64_t FalseImm = FalseVal.getSExtValue();
8474+
if (CCVal == ISD::SETGT)
8475+
std::swap(TrueImm, FalseImm);
8476+
if (isInt<12>(TrueImm) && isInt<12>(FalseImm) &&
8477+
isInt<12>(TrueImm - FalseImm)) {
8478+
SDValue SRA =
8479+
DAG.getNode(ISD::SRA, DL, VT, CondV.getOperand(0),
8480+
DAG.getConstant(Subtarget.getXLen() - 1, DL, VT));
8481+
SDValue AND =
8482+
DAG.getNode(ISD::AND, DL, VT, SRA,
8483+
DAG.getSignedConstant(TrueImm - FalseImm, DL, VT));
8484+
return DAG.getNode(ISD::ADD, DL, VT, AND,
8485+
DAG.getSignedConstant(FalseImm, DL, VT));
8486+
}
8487+
}
8488+
}
8489+
84638490
const int TrueValCost = RISCVMatInt::getIntMatCost(
84648491
TrueVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
84658492
const int FalseValCost = RISCVMatInt::getIntMatCost(

0 commit comments

Comments
 (0)