[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