@@ -9075,18 +9075,51 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
90759075 if (isNullConstant(TrueV))
90769076 return DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, CondV);
90779077
9078+ // Check to see if a given operation is a 'NOT', if so return the negated
9079+ // operand
9080+ auto getNotOperand = [](const SDValue &Op) -> std::optional<const SDValue> {
9081+ using namespace llvm::SDPatternMatch;
9082+ SDValue Xor;
9083+ if (sd_match(Op, m_OneUse(m_Not(m_Value(Xor))))) {
9084+ return Xor;
9085+ }
9086+ return std::nullopt;
9087+ };
90789088 // (select c, (and f, x), f) -> (or (and f, x), (czero_nez f, c))
9089+ // (select c, (and f, ~x), f) -> (andn f, (czero_eqz x, c))
90799090 if (TrueV.getOpcode() == ISD::AND &&
9080- (TrueV.getOperand(0) == FalseV || TrueV.getOperand(1) == FalseV))
9091+ (TrueV.getOperand(0) == FalseV || TrueV.getOperand(1) == FalseV)) {
9092+ auto NotOperand = (TrueV.getOperand(0) == FalseV)
9093+ ? getNotOperand(TrueV.getOperand(1))
9094+ : getNotOperand(TrueV.getOperand(0));
9095+ if (NotOperand) {
9096+ SDValue CMOV =
9097+ DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, *NotOperand, CondV);
9098+ SDValue NOT = DAG.getNOT(DL, CMOV, VT);
9099+ return DAG.getNode(ISD::AND, DL, VT, FalseV, NOT);
9100+ }
90819101 return DAG.getNode(
90829102 ISD::OR, DL, VT, TrueV,
90839103 DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, CondV));
9104+ }
9105+
90849106 // (select c, t, (and t, x)) -> (or (czero_eqz t, c), (and t, x))
9107+ // (select c, t, (and t, ~x)) -> (andn t, (czero_nez x, c))
90859108 if (FalseV.getOpcode() == ISD::AND &&
9086- (FalseV.getOperand(0) == TrueV || FalseV.getOperand(1) == TrueV))
9109+ (FalseV.getOperand(0) == TrueV || FalseV.getOperand(1) == TrueV)) {
9110+ auto NotOperand = (FalseV.getOperand(0) == TrueV)
9111+ ? getNotOperand(FalseV.getOperand(1))
9112+ : getNotOperand(FalseV.getOperand(0));
9113+ if (NotOperand) {
9114+ SDValue CMOV =
9115+ DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, *NotOperand, CondV);
9116+ SDValue NOT = DAG.getNOT(DL, CMOV, VT);
9117+ return DAG.getNode(ISD::AND, DL, VT, TrueV, NOT);
9118+ }
90879119 return DAG.getNode(
90889120 ISD::OR, DL, VT, FalseV,
90899121 DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV));
9122+ }
90909123
90919124 // Try some other optimizations before falling back to generic lowering.
90929125 if (SDValue V = combineSelectToBinOp(Op.getNode(), DAG, Subtarget))
0 commit comments