@@ -24899,16 +24899,31 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
24899
24899
SDValue SubsNode = N->getOperand(3);
24900
24900
if (SubsNode.getOpcode() != AArch64ISD::SUBS || !SubsNode.hasOneUse())
24901
24901
return SDValue();
24902
- auto *CmpOpConst = dyn_cast<ConstantSDNode>(SubsNode.getOperand(1));
24903
- if (!CmpOpConst)
24904
- return SDValue();
24905
24902
24903
+ SDValue CmpOpToMatch = SubsNode.getOperand(1);
24906
24904
SDValue CmpOpOther = SubsNode.getOperand(0);
24907
24905
EVT VT = N->getValueType(0);
24908
24906
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
+
24909
24924
// 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 )
24912
24927
return SDValue();
24913
24928
if (Op.getOperand(0).getOpcode() != ISD::ADD ||
24914
24929
!Op.getOperand(0).hasOneUse())
@@ -24919,24 +24934,21 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
24919
24934
std::swap(X, Y);
24920
24935
if (X != CmpOpOther)
24921
24936
return SDValue();
24922
- auto *AddOpConst = dyn_cast<ConstantSDNode>(Op.getOperand(1));
24923
- if (!AddOpConst || AddOpConst->getAPIntValue() != ExpectedConst)
24937
+ if (ExpectedOp != Op.getOperand(1))
24924
24938
return SDValue();
24925
24939
return Y;
24926
24940
};
24927
24941
24928
24942
// 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 );
24933
24947
if (!TReassocOp && !FReassocOp)
24934
24948
return SDValue();
24935
24949
24936
24950
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);
24940
24952
24941
24953
auto Reassociate = [&](SDValue ReassocOp, unsigned OpNum) {
24942
24954
if (!ReassocOp)
@@ -24958,9 +24970,19 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
24958
24970
24959
24971
// First, try to eliminate the compare instruction by searching for a
24960
24972
// subtraction with the same constant.
24961
- if (SDValue R = Fold(CmpOpConst->getAPIntValue(), CC ))
24973
+ if (SDValue R = Fold(CC, ExpectedOp, SubsOp ))
24962
24974
return R;
24963
24975
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
+
24964
24986
if ((CC == AArch64CC::EQ || CC == AArch64CC::NE) && !CmpOpConst->isZero())
24965
24987
return SDValue();
24966
24988
@@ -24972,7 +24994,11 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
24972
24994
// them here but check for them nevertheless to be on the safe side.
24973
24995
auto CheckedFold = [&](bool Check, APInt NewCmpConst,
24974
24996
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();
24976
25002
};
24977
25003
switch (CC) {
24978
25004
case AArch64CC::EQ:
0 commit comments