@@ -24899,16 +24899,31 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2489924899 SDValue SubsNode = N->getOperand(3);
2490024900 if (SubsNode.getOpcode() != AArch64ISD::SUBS || !SubsNode.hasOneUse())
2490124901 return SDValue();
24902- auto *CmpOpConst = dyn_cast<ConstantSDNode>(SubsNode.getOperand(1));
24903- if (!CmpOpConst)
24904- return SDValue();
2490524902
24903+ SDValue CmpOpToMatch = SubsNode.getOperand(1);
2490624904 SDValue CmpOpOther = SubsNode.getOperand(0);
2490724905 EVT VT = N->getValueType(0);
2490824906
24907+ unsigned ExpectedOpcode;
24908+ SDValue ExpectedOp;
24909+ SDValue SubsOp;
24910+ auto *CmpOpConst = dyn_cast<ConstantSDNode>(CmpOpToMatch);
24911+ if (CmpOpConst) {
24912+ ExpectedOpcode = ISD::ADD;
24913+ ExpectedOp =
24914+ DAG.getConstant(-CmpOpConst->getAPIntValue(), SDLoc(CmpOpConst),
24915+ CmpOpConst->getValueType(0));
24916+ SubsOp = DAG.getConstant(CmpOpConst->getAPIntValue(), SDLoc(CmpOpConst),
24917+ CmpOpConst->getValueType(0));
24918+ } else {
24919+ ExpectedOpcode = ISD::SUB;
24920+ ExpectedOp = CmpOpToMatch;
24921+ SubsOp = CmpOpToMatch;
24922+ }
24923+
2490924924 // Get the operand that can be reassociated with the SUBS instruction.
24910- auto GetReassociationOp = [&](SDValue Op, APInt ExpectedConst ) {
24911- if (Op.getOpcode() != ISD::ADD )
24925+ auto GetReassociationOp = [&](SDValue Op, SDValue ExpectedOp ) {
24926+ if (Op.getOpcode() != ExpectedOpcode )
2491224927 return SDValue();
2491324928 if (Op.getOperand(0).getOpcode() != ISD::ADD ||
2491424929 !Op.getOperand(0).hasOneUse())
@@ -24919,24 +24934,21 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2491924934 std::swap(X, Y);
2492024935 if (X != CmpOpOther)
2492124936 return SDValue();
24922- auto *AddOpConst = dyn_cast<ConstantSDNode>(Op.getOperand(1));
24923- if (!AddOpConst || AddOpConst->getAPIntValue() != ExpectedConst)
24937+ if (ExpectedOp != Op.getOperand(1))
2492424938 return SDValue();
2492524939 return Y;
2492624940 };
2492724941
2492824942 // Try the reassociation using the given constant and condition code.
24929- auto Fold = [&](APInt NewCmpConst, AArch64CC::CondCode NewCC) {
24930- APInt ExpectedConst = -NewCmpConst;
24931- SDValue TReassocOp = GetReassociationOp(N->getOperand(0), ExpectedConst );
24932- SDValue FReassocOp = GetReassociationOp(N->getOperand(1), ExpectedConst );
24943+ auto Fold = [&](AArch64CC::CondCode NewCC, SDValue ExpectedOp,
24944+ SDValue SubsOp) {
24945+ SDValue TReassocOp = GetReassociationOp(N->getOperand(0), ExpectedOp );
24946+ SDValue FReassocOp = GetReassociationOp(N->getOperand(1), ExpectedOp );
2493324947 if (!TReassocOp && !FReassocOp)
2493424948 return SDValue();
2493524949
2493624950 SDValue NewCmp = DAG.getNode(AArch64ISD::SUBS, SDLoc(SubsNode),
24937- DAG.getVTList(VT, MVT_CC), CmpOpOther,
24938- DAG.getConstant(NewCmpConst, SDLoc(CmpOpConst),
24939- CmpOpConst->getValueType(0)));
24951+ DAG.getVTList(VT, MVT_CC), CmpOpOther, SubsOp);
2494024952
2494124953 auto Reassociate = [&](SDValue ReassocOp, unsigned OpNum) {
2494224954 if (!ReassocOp)
@@ -24958,9 +24970,19 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2495824970
2495924971 // First, try to eliminate the compare instruction by searching for a
2496024972 // subtraction with the same constant.
24961- if (SDValue R = Fold(CmpOpConst->getAPIntValue(), CC ))
24973+ if (SDValue R = Fold(CC, ExpectedOp, SubsOp ))
2496224974 return R;
2496324975
24976+ if (!CmpOpConst) {
24977+ // Try again with the operands of the SUBS instruction and the condition
24978+ // swapped. Due to canonicalization, this only helps for non-constant
24979+ // operands of the SUBS instruction.
24980+ std::swap(CmpOpToMatch, CmpOpOther);
24981+ if (SDValue R = Fold(getSwappedCondition(CC), CmpOpToMatch, CmpOpToMatch))
24982+ return R;
24983+ return SDValue();
24984+ }
24985+
2496424986 if ((CC == AArch64CC::EQ || CC == AArch64CC::NE) && !CmpOpConst->isZero())
2496524987 return SDValue();
2496624988
@@ -24972,7 +24994,11 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2497224994 // them here but check for them nevertheless to be on the safe side.
2497324995 auto CheckedFold = [&](bool Check, APInt NewCmpConst,
2497424996 AArch64CC::CondCode NewCC) {
24975- return Check ? Fold(NewCmpConst, NewCC) : SDValue();
24997+ auto ExpectedOp = DAG.getConstant(-NewCmpConst, SDLoc(CmpOpConst),
24998+ CmpOpConst->getValueType(0));
24999+ auto SubsOp = DAG.getConstant(NewCmpConst, SDLoc(CmpOpConst),
25000+ CmpOpConst->getValueType(0));
25001+ return Check ? Fold(NewCC, ExpectedOp, SubsOp) : SDValue();
2497625002 };
2497725003 switch (CC) {
2497825004 case AArch64CC::EQ:
0 commit comments