@@ -9075,18 +9075,51 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
9075
9075
if (isNullConstant(TrueV))
9076
9076
return DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, CondV);
9077
9077
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
+ };
9078
9088
// (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))
9079
9090
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
+ }
9081
9101
return DAG.getNode(
9082
9102
ISD::OR, DL, VT, TrueV,
9083
9103
DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, CondV));
9104
+ }
9105
+
9084
9106
// (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))
9085
9108
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
+ }
9087
9119
return DAG.getNode(
9088
9120
ISD::OR, DL, VT, FalseV,
9089
9121
DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV));
9122
+ }
9090
9123
9091
9124
// Try some other optimizations before falling back to generic lowering.
9092
9125
if (SDValue V = combineSelectToBinOp(Op.getNode(), DAG, Subtarget))
0 commit comments