[llvm] [AArch64] Eliminate Common Subexpression of CSEL by Reassociation (PR #121350)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 7 13:02:39 PST 2025
================
@@ -24838,6 +24838,122 @@ static SDValue foldCSELOfCSEL(SDNode *Op, SelectionDAG &DAG) {
return DAG.getNode(AArch64ISD::CSEL, DL, VT, L, R, CCValue, Cond);
}
+// Reassociate the true/false expressions of a CSEL instruction to obtain a
+// common subexpression with the comparison instruction. For example, change
+// (CSEL (ADD (ADD x y) -c) f LO (SUBS x c)) to
+// (CSEL (ADD (SUBS x c) y) f LO (SUBS x c)) such that (SUBS x c) is a common
+// subexpression.
+static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
+ SDValue SubsNode = N->getOperand(3);
+ if (SubsNode.getOpcode() != AArch64ISD::SUBS || !SubsNode.hasOneUse())
+ return SDValue();
+ auto *CmpOpConst = dyn_cast<ConstantSDNode>(SubsNode.getOperand(1));
+ if (!CmpOpConst)
+ return SDValue();
+
+ auto CC = static_cast<AArch64CC::CondCode>(N->getConstantOperandVal(2));
+ bool IsEquality = CC == AArch64CC::EQ || CC == AArch64CC::NE;
+ if (IsEquality && !CmpOpConst->isZero())
+ return SDValue();
+
+ SDValue CmpOpOther = SubsNode.getOperand(0);
+ EVT VT = N->getValueType(0);
+
+ auto Reassociate = [&](SDValue Op, APInt ExpectedConst, SDValue NewCmp) {
+ if (Op.getOpcode() != ISD::ADD)
+ return SDValue();
+ auto *AddOpConst = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+ if (!AddOpConst)
+ return SDValue();
+ if (AddOpConst->getAPIntValue() != ExpectedConst)
+ return SDValue();
+ if (Op.getOperand(0).getOpcode() != ISD::ADD ||
+ !Op.getOperand(0).hasOneUse())
+ return SDValue();
+ SDValue X = Op.getOperand(0).getOperand(0);
+ SDValue Y = Op.getOperand(0).getOperand(1);
+ if (X != CmpOpOther)
+ std::swap(X, Y);
+ if (X != CmpOpOther)
+ return SDValue();
+ SDNodeFlags Flags;
+ if (Op.getOperand(0).getNode()->getFlags().hasNoUnsignedWrap())
+ Flags.setNoUnsignedWrap(true);
+ return DAG.getNode(ISD::ADD, SDLoc(Op), VT, NewCmp.getValue(0), Y, Flags);
+ };
+
+ auto Fold = [&](APInt NewCmpConst, AArch64CC::CondCode NewCC) {
+ SDValue NewCmp = DAG.getNode(AArch64ISD::SUBS, SDLoc(SubsNode),
----------------
davemgreen wrote:
It is best to only create nodes if we know they are needed, if possible.
https://github.com/llvm/llvm-project/pull/121350
More information about the llvm-commits
mailing list