@@ -9064,18 +9064,51 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
90649064 if (isNullConstant(TrueV))
90659065 return DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, CondV);
90669066
9067+ // Check to see if a given operation is a 'NOT', if so return the negated
9068+ // operand
9069+ auto getNotOperand = [](const SDValue &Op) -> std::optional<const SDValue> {
9070+ using namespace llvm::SDPatternMatch;
9071+ SDValue Xor;
9072+ if (sd_match(Op, m_OneUse(m_Not(m_Value(Xor))))) {
9073+ return Xor;
9074+ }
9075+ return std::nullopt;
9076+ };
90679077 // (select c, (and f, x), f) -> (or (and f, x), (czero_nez f, c))
9078+ // (select c, (and f, ~x), f) -> (andn f, (czero_eqz x, c))
90689079 if (TrueV.getOpcode() == ISD::AND &&
9069- (TrueV.getOperand(0) == FalseV || TrueV.getOperand(1) == FalseV))
9080+ (TrueV.getOperand(0) == FalseV || TrueV.getOperand(1) == FalseV)) {
9081+ auto NotOperand = (TrueV.getOperand(0) == FalseV)
9082+ ? getNotOperand(TrueV.getOperand(1))
9083+ : getNotOperand(TrueV.getOperand(0));
9084+ if (NotOperand) {
9085+ SDValue CMOV =
9086+ DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, *NotOperand, CondV);
9087+ SDValue NOT = DAG.getNOT(DL, CMOV, VT);
9088+ return DAG.getNode(ISD::AND, DL, VT, FalseV, NOT);
9089+ }
90709090 return DAG.getNode(
90719091 ISD::OR, DL, VT, TrueV,
90729092 DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, CondV));
9093+ }
9094+
90739095 // (select c, t, (and t, x)) -> (or (czero_eqz t, c), (and t, x))
9096+ // (select c, t, (and t, ~x)) -> (andn t, (czero_nez x, c))
90749097 if (FalseV.getOpcode() == ISD::AND &&
9075- (FalseV.getOperand(0) == TrueV || FalseV.getOperand(1) == TrueV))
9098+ (FalseV.getOperand(0) == TrueV || FalseV.getOperand(1) == TrueV)) {
9099+ auto NotOperand = (FalseV.getOperand(0) == TrueV)
9100+ ? getNotOperand(FalseV.getOperand(1))
9101+ : getNotOperand(FalseV.getOperand(0));
9102+ if (NotOperand) {
9103+ SDValue CMOV =
9104+ DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, *NotOperand, CondV);
9105+ SDValue NOT = DAG.getNOT(DL, CMOV, VT);
9106+ return DAG.getNode(ISD::AND, DL, VT, TrueV, NOT);
9107+ }
90769108 return DAG.getNode(
90779109 ISD::OR, DL, VT, FalseV,
90789110 DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV));
9111+ }
90799112
90809113 // Try some other optimizations before falling back to generic lowering.
90819114 if (SDValue V = combineSelectToBinOp(Op.getNode(), DAG, Subtarget))
0 commit comments