@@ -9043,15 +9043,20 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
9043
9043
9044
9044
// (select c, c1, c2) -> (add (czero_nez c2 - c1, c), c1)
9045
9045
// (select c, c1, c2) -> (add (czero_eqz c1 - c2, c), c2)
9046
- if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
9047
- const APInt &TrueVal = TrueV->getAsAPIntVal();
9048
- const APInt &FalseVal = FalseV->getAsAPIntVal();
9046
+ // (select c, c1, t) -> (add (czero_nez t - c1, c), c1)
9047
+ // (select c, t, c1) -> (add (czero_eqz t - c1, c), c1)
9048
+ if (isa<ConstantSDNode>(TrueV) || isa<ConstantSDNode>(FalseV)) {
9049
+ bool BothAreConstant =
9050
+ isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV);
9049
9051
9050
9052
// Prefer these over Zicond to avoid materializing an immediate:
9051
9053
// (select (x < 0), y, z) -> x >> (XLEN - 1) & (y - z) + z
9052
9054
// (select (x > -1), z, y) -> x >> (XLEN - 1) & (y - z) + z
9053
9055
if (CondV.getOpcode() == ISD::SETCC &&
9054
- CondV.getOperand(0).getValueType() == VT && CondV.hasOneUse()) {
9056
+ CondV.getOperand(0).getValueType() == VT && CondV.hasOneUse() &&
9057
+ BothAreConstant) {
9058
+ const APInt &TrueVal = TrueV->getAsAPIntVal();
9059
+ const APInt &FalseVal = FalseV->getAsAPIntVal();
9055
9060
ISD::CondCode CCVal = cast<CondCodeSDNode>(CondV.getOperand(2))->get();
9056
9061
if ((CCVal == ISD::SETLT && isNullConstant(CondV.getOperand(1))) ||
9057
9062
(CCVal == ISD::SETGT && isAllOnesConstant(CondV.getOperand(1)))) {
@@ -9073,19 +9078,36 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
9073
9078
}
9074
9079
}
9075
9080
9076
- const int TrueValCost = RISCVMatInt::getIntMatCost(
9077
- TrueVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
9078
- const int FalseValCost = RISCVMatInt::getIntMatCost(
9079
- FalseVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
9080
- bool IsCZERO_NEZ = TrueValCost <= FalseValCost;
9081
- SDValue LHSVal = DAG.getConstant(
9082
- IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal, DL, VT);
9083
- SDValue RHSVal =
9084
- DAG.getConstant(IsCZERO_NEZ ? TrueVal : FalseVal, DL, VT);
9085
- SDValue CMOV =
9086
- DAG.getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
9087
- DL, VT, LHSVal, CondV);
9088
- return DAG.getNode(ISD::ADD, DL, VT, CMOV, RHSVal);
9081
+ bool IsCZERO_NEZ;
9082
+ SDValue ConstVal, SubOp;
9083
+ if (BothAreConstant) {
9084
+ const APInt &TrueVal = TrueV->getAsAPIntVal();
9085
+ const APInt &FalseVal = FalseV->getAsAPIntVal();
9086
+ const int TrueValCost = RISCVMatInt::getIntMatCost(
9087
+ TrueVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
9088
+ const int FalseValCost = RISCVMatInt::getIntMatCost(
9089
+ FalseVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
9090
+ IsCZERO_NEZ = TrueValCost <= FalseValCost;
9091
+
9092
+ SubOp = DAG.getConstant(
9093
+ IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal, DL, VT);
9094
+ ConstVal = DAG.getConstant(IsCZERO_NEZ ? TrueVal : FalseVal, DL, VT);
9095
+ } else {
9096
+ IsCZERO_NEZ = isa<ConstantSDNode>(TrueV);
9097
+ ConstVal = IsCZERO_NEZ ? TrueV : FalseV;
9098
+
9099
+ SDValue &RegV = IsCZERO_NEZ ? FalseV : TrueV;
9100
+ SubOp = DAG.getNode(ISD::SUB, DL, VT, RegV, ConstVal);
9101
+ }
9102
+ // The one constant case is only efficient is the constant fits into
9103
+ // `ADDI`
9104
+ if (BothAreConstant ||
9105
+ isInt<12>(dyn_cast<ConstantSDNode>(ConstVal)->getSExtValue())) {
9106
+ SDValue CMOV =
9107
+ DAG.getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
9108
+ DL, VT, SubOp, CondV);
9109
+ return DAG.getNode(ISD::ADD, DL, VT, CMOV, ConstVal);
9110
+ }
9089
9111
}
9090
9112
9091
9113
// (select c, t, f) -> (or (czero_eqz t, c), (czero_nez f, c))
0 commit comments