@@ -17194,12 +17194,58 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
1719417194 return true;
1719517195 }
1719617196
17197+ // If XOR is reused and has an immediate that will fit in XORI,
17198+ // do not fold.
17199+ auto IsXorImmediate = [](const SDValue &Op) -> bool {
17200+ if (const auto XorCnst = dyn_cast<ConstantSDNode>(Op))
17201+ return isInt<12>(XorCnst->getSExtValue());
17202+ return false;
17203+ };
17204+ // Fold (X(i1) ^ 1) == 0 -> X != 0
17205+ auto SingleBitOp = [&DAG](const SDValue &VarOp,
17206+ const SDValue &ConstOp) -> bool {
17207+ if (const auto XorCnst = dyn_cast<ConstantSDNode>(ConstOp)) {
17208+ const APInt Mask = APInt::getBitsSetFrom(VarOp.getValueSizeInBits(), 1);
17209+ return (XorCnst->getSExtValue() == 1) &&
17210+ DAG.MaskedValueIsZero(VarOp, Mask);
17211+ }
17212+ return false;
17213+ };
17214+ auto OnlyUsedBySelectOrBR = [](const SDValue &Op) -> bool {
17215+ for (const SDNode *UserNode : Op->users()) {
17216+ const unsigned Opcode = UserNode->getOpcode();
17217+ if (Opcode != RISCVISD::SELECT_CC && Opcode != RISCVISD::BR_CC)
17218+ return false;
17219+ }
17220+ return true;
17221+ };
17222+ auto IsFoldableXorEq = [IsXorImmediate, SingleBitOp, OnlyUsedBySelectOrBR](
17223+ const SDValue &LHS, const SDValue &RHS) -> bool {
17224+ return LHS.getOpcode() == ISD::XOR && isNullConstant(RHS) &&
17225+ (!IsXorImmediate(LHS.getOperand(1)) ||
17226+ SingleBitOp(LHS.getOperand(0), LHS.getOperand(1)) ||
17227+ OnlyUsedBySelectOrBR(LHS));
17228+ };
1719717229 // Fold ((xor X, Y), 0, eq/ne) -> (X, Y, eq/ne)
17198- if (LHS.getOpcode() == ISD::XOR && isNullConstant( RHS)) {
17230+ if (IsFoldableXorEq(LHS, RHS)) {
1719917231 RHS = LHS.getOperand(1);
1720017232 LHS = LHS.getOperand(0);
1720117233 return true;
1720217234 }
17235+ // Fold ((sext (xor X, C)), 0, eq/ne) -> ((sext(X), C, eq/ne)
17236+ if (LHS.getOpcode() == ISD::SIGN_EXTEND_INREG) {
17237+ const SDValue LHS0 = LHS.getOperand(0);
17238+ if (IsFoldableXorEq(LHS0, RHS) && isa<ConstantSDNode>(LHS0.getOperand(1))) {
17239+ // SEXT(XOR(X, Y)) -> XOR(SEXT(X), SEXT(Y)))
17240+ RHS = DAG.getNode(
17241+ ISD::SIGN_EXTEND_INREG, DL, LHS.getValueType(), LHS0.getOperand(1),
17242+ DAG.getValueType(cast<VTSDNode>(LHS.getOperand(1))->getVT()));
17243+ LHS = DAG.getNode(
17244+ ISD::SIGN_EXTEND_INREG, DL, LHS.getValueType(), LHS0.getOperand(0),
17245+ DAG.getValueType(cast<VTSDNode>(LHS.getOperand(1))->getVT()));
17246+ return true;
17247+ }
17248+ }
1720317249
1720417250 // Fold ((srl (and X, 1<<C), C), 0, eq/ne) -> ((shl X, XLen-1-C), 0, ge/lt)
1720517251 if (isNullConstant(RHS) && LHS.getOpcode() == ISD::SRL && LHS.hasOneUse() &&
0 commit comments