@@ -2763,6 +2763,47 @@ bool RISCVTargetLowering::mergeStoresAfterLegalization(EVT VT) const {
27632763 (VT.isFixedLengthVector() && VT.getVectorElementType() == MVT::i1);
27642764}
27652765
2766+ // Can the given operation be interchanged with a Zicond::CZERO operation
2767+ // Must be:
2768+ // - a SETCC instruction
2769+ // - Must compare a value for [in]equality against 0
2770+ static bool isCzeroCompatible(const SDValue Op) {
2771+ if (Op.getValueType() == MVT::i1 && Op.getOpcode() == ISD::SETCC &&
2772+ isNullConstant(Op.getOperand(1))) {
2773+ ISD::CondCode CondCode = cast<CondCodeSDNode>(Op.getOperand(2))->get();
2774+ return CondCode == ISD::SETNE || CondCode == ISD::SETEQ;
2775+ }
2776+ return false;
2777+ }
2778+
2779+ // Disable normalizing for most cases
2780+ // select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and
2781+ // select(N0|N1, X, Y) => select(N0, Y, select(N1, X, Y))
2782+ // For select(N0, select(N1, X, Y), Y), if Y=0 and N0=setcc(eqz || nez):
2783+ // %N1 = setcc [any_cond] %A, %B
2784+ // %CZ = czero.eqz %N1, X
2785+ // %Res = czero.eqz %N0, %CZ
2786+ // ...
2787+ // But for select(N0&N1, X, Y):
2788+ // %N0 = setcc [eq/ne] %C, 0
2789+ // %N1 = setcc [any_cond] %A, %B
2790+ // %And = and %N0, %N1
2791+ // %Res = czero.eqz %And, %X
2792+ bool RISCVTargetLowering::shouldNormalizeToSelectSequence(LLVMContext &, EVT VT,
2793+ SDNode *N) const {
2794+ if (Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps()) {
2795+ assert(
2796+ N->getOpcode() == ISD::SELECT &&
2797+ "shouldNormalizeToSelectSequence() called with non-SELECT operation");
2798+ const SDValue &CondV = N->getOperand(0);
2799+ const SDValue &TrueV = N->getOperand(1);
2800+ const SDValue &FalseV = N->getOperand(2);
2801+ if (CondV.hasOneUse() && isCzeroCompatible(CondV) && isNullConstant(FalseV))
2802+ return true;
2803+ }
2804+ return false;
2805+ }
2806+
27662807bool RISCVTargetLowering::hasConditionalZero() const {
27672808 return Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps();
27682809}
@@ -16121,6 +16162,25 @@ static SDValue reverseZExtICmpCombine(SDNode *N, SelectionDAG &DAG,
1612116162 return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Res);
1612216163}
1612316164
16165+ static SDValue reduceANDOfSetCC(SDNode *N, SelectionDAG &DAG,
16166+ const RISCVSubtarget &Subtarget) {
16167+ if (Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps()) {
16168+ // (and (i1) f, (setcc c, 0, ne)) -> (select c, f, 0) -> (czero.nez f, c)
16169+ // (and (i1) f, (setcc c, 0, eq)) -> (select c, 0, f) -> (czero.eqz f, c)
16170+ // (and (setcc c, 0, ne), (i1) g) -> (select c, g, 0) -> (czero.nez g, c)
16171+ // (and (setcc c, 0, eq), (i1) g) -> (select c, 0, g) -> (czero.eqz g, c)
16172+ const bool CzeroOp1 = isCzeroCompatible(N->getOperand(1));
16173+ if (CzeroOp1 || isCzeroCompatible(N->getOperand(0))) {
16174+ const SDValue I1Op = CzeroOp1 ? N->getOperand(0) : N->getOperand(1);
16175+ const SDValue SetCCOp = CzeroOp1 ? N->getOperand(1) : N->getOperand(0);
16176+ SDLoc DL(N);
16177+ return DAG.getNode(ISD::SELECT, DL, MVT::i1, SetCCOp, I1Op,
16178+ DAG.getConstant(0, DL, MVT::i1));
16179+ }
16180+ }
16181+ return SDValue();
16182+ }
16183+
1612416184static SDValue reduceANDOfAtomicLoad(SDNode *N,
1612516185 TargetLowering::DAGCombinerInfo &DCI) {
1612616186 SelectionDAG &DAG = DCI.DAG;
@@ -16184,7 +16244,8 @@ static SDValue performANDCombine(SDNode *N,
1618416244
1618516245 if (SDValue V = reverseZExtICmpCombine(N, DAG, Subtarget))
1618616246 return V;
16187-
16247+ if (SDValue V = reduceANDOfSetCC(N, DAG, Subtarget))
16248+ return V;
1618816249 if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
1618916250 return V;
1619016251 if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
0 commit comments