@@ -8430,6 +8430,33 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
8430
8430
if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
8431
8431
const APInt &TrueVal = TrueV->getAsAPIntVal();
8432
8432
const APInt &FalseVal = FalseV->getAsAPIntVal();
8433
+
8434
+ // Prefer these over Zicond to avoid materializing an immediate:
8435
+ // (select (x < 0), y, z) -> x >> (XLEN - 1) & (y - z) + z
8436
+ // (select (x > -1), z, y) -> x >> (XLEN - 1) & (y - z) + z
8437
+ if (CondV.getOpcode() == ISD::SETCC &&
8438
+ CondV.getOperand(0).getValueType() == VT && CondV.hasOneUse()) {
8439
+ ISD::CondCode CCVal = cast<CondCodeSDNode>(CondV.getOperand(2))->get();
8440
+ if ((CCVal == ISD::SETLT && isNullConstant(CondV.getOperand(1))) ||
8441
+ (CCVal == ISD::SETGT && isAllOnesConstant(CondV.getOperand(1)))) {
8442
+ int64_t TrueImm = TrueVal.getSExtValue();
8443
+ int64_t FalseImm = FalseVal.getSExtValue();
8444
+ if (CCVal == ISD::SETGT)
8445
+ std::swap(TrueImm, FalseImm);
8446
+ if (isInt<12>(TrueImm) && isInt<12>(FalseImm) &&
8447
+ isInt<12>(TrueImm - FalseImm)) {
8448
+ SDValue SRA =
8449
+ DAG.getNode(ISD::SRA, DL, VT, CondV.getOperand(0),
8450
+ DAG.getConstant(Subtarget.getXLen() - 1, DL, VT));
8451
+ SDValue AND =
8452
+ DAG.getNode(ISD::AND, DL, VT, SRA,
8453
+ DAG.getSignedConstant(TrueImm - FalseImm, DL, VT));
8454
+ return DAG.getNode(ISD::ADD, DL, VT, AND,
8455
+ DAG.getSignedConstant(FalseImm, DL, VT));
8456
+ }
8457
+ }
8458
+ }
8459
+
8433
8460
const int TrueValCost = RISCVMatInt::getIntMatCost(
8434
8461
TrueVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
8435
8462
const int FalseValCost = RISCVMatInt::getIntMatCost(
0 commit comments