@@ -17400,12 +17400,56 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
1740017400 return true;
1740117401 }
1740217402
17403+ // If XOR is reused and has an immediate that will fit in XORI,
17404+ // do not fold.
17405+ auto isXorImmediate = [](const SDValue &Op) -> bool {
17406+ if (const auto *XorCnst = dyn_cast<ConstantSDNode>(Op))
17407+ return isInt<12>(XorCnst->getSExtValue());
17408+ return false;
17409+ };
17410+ // Fold (X(i1) ^ 1) == 0 -> X != 0
17411+ auto singleBitOp = [&DAG](const SDValue &VarOp,
17412+ const SDValue &ConstOp) -> bool {
17413+ if (const auto *XorCnst = dyn_cast<ConstantSDNode>(ConstOp)) {
17414+ const APInt Mask = APInt::getBitsSetFrom(VarOp.getValueSizeInBits(), 1);
17415+ return (XorCnst->getSExtValue() == 1) &&
17416+ DAG.MaskedValueIsZero(VarOp, Mask);
17417+ }
17418+ return false;
17419+ };
17420+ auto onlyUsedBySelectOrBR = [](const SDValue &Op) -> bool {
17421+ for (const SDNode *UserNode : Op->users()) {
17422+ const unsigned Opcode = UserNode->getOpcode();
17423+ if (Opcode != RISCVISD::SELECT_CC && Opcode != RISCVISD::BR_CC)
17424+ return false;
17425+ }
17426+ return true;
17427+ };
17428+ auto isFoldableXorEq = [isXorImmediate, singleBitOp, onlyUsedBySelectOrBR](
17429+ const SDValue &LHS, const SDValue &RHS) -> bool {
17430+ return LHS.getOpcode() == ISD::XOR && isNullConstant(RHS) &&
17431+ (!isXorImmediate(LHS.getOperand(1)) ||
17432+ singleBitOp(LHS.getOperand(0), LHS.getOperand(1)) ||
17433+ onlyUsedBySelectOrBR(LHS));
17434+ };
1740317435 // Fold ((xor X, Y), 0, eq/ne) -> (X, Y, eq/ne)
17404- if (LHS.getOpcode() == ISD::XOR && isNullConstant( RHS)) {
17436+ if (isFoldableXorEq(LHS, RHS)) {
1740517437 RHS = LHS.getOperand(1);
1740617438 LHS = LHS.getOperand(0);
1740717439 return true;
1740817440 }
17441+ // Fold ((sext (xor X, C)), 0, eq/ne) -> ((sext(X), C, eq/ne)
17442+ if (LHS.getOpcode() == ISD::SIGN_EXTEND_INREG) {
17443+ const SDValue LHS0 = LHS.getOperand(0);
17444+ if (isFoldableXorEq(LHS0, RHS) && isa<ConstantSDNode>(LHS0.getOperand(1))) {
17445+ // SEXT(XOR(X, Y)) -> XOR(SEXT(X), SEXT(Y)))
17446+ RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, LHS.getValueType(),
17447+ LHS0.getOperand(1), LHS.getOperand(1));
17448+ LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, LHS.getValueType(),
17449+ LHS0.getOperand(0), LHS.getOperand(1));
17450+ return true;
17451+ }
17452+ }
1740917453
1741017454 // Fold ((srl (and X, 1<<C), C), 0, eq/ne) -> ((shl X, XLen-1-C), 0, ge/lt)
1741117455 if (isNullConstant(RHS) && LHS.getOpcode() == ISD::SRL && LHS.hasOneUse() &&
0 commit comments