[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())
----------------
davemgreen wrote:
Can we handle eq and ne in the same way?
```
define i32 @src(i32 %x0, i32 %x1) {
%cmp = icmp eq i32 %x1, 7
%add = add i32 %x0, %x1
%sub = sub i32 %add, 7
%ret = select i1 %cmp, i32 0, i32 %sub
ret i32 %ret
}
define i32 @tgt(i32 %x0, i32 %x1) {
%cmp = icmp eq i32 %x1, 7
%add = sub i32 %x1, 7
%sub = add i32 %add, %x0
%ret = select i1 %cmp, i32 0, i32 %sub
ret i32 %ret
}
```
(I guess for all of those the constant isn't actually necessary and the basic pattern is that we can reassociate an add/sub to allow it to be shared with a sub. FYI There is a related but different patch to that (swapping conditions to allow sharing) added in https://github.com/llvm/llvm-project/pull/121412 (mostly for handling constants, for non-constants it already exists in a couple of places in llvm already). I understand this is getting further away from your motivating case. If we can fix the APInt issues then the follow on can easily be added in a later patch if that is simpler. Sometimes it is better to have smaller patches).
https://github.com/llvm/llvm-project/pull/121350
More information about the llvm-commits
mailing list