[llvm] [AArch64] fuse constant addition after sbb (PR #185117)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 8 00:32:32 PST 2026
================
@@ -23346,6 +23346,36 @@ static SDValue performAddTruncShiftCombine(SDNode *N, SelectionDAG &DAG) {
return DAG.getNode(ISD::ADD, DL, VT, Trunc, Shift);
}
+// Fold ADD(SBC(Y, 0, W), C) -> SBC(Y, -C, W)
+// SBC(Y, 0, W) = Y - 0 - ~carry = Y + carry - 1
+// Adding C: Y + carry - 1 + C = Y - (-C) - ~carry = SBC(Y, -C, W)
+static SDValue performAddWithSBCCombine(SDNode *N, SelectionDAG &DAG) {
+ if (N->getOpcode() != ISD::ADD)
+ return SDValue();
+ EVT VT = N->getValueType(0);
+ if (VT != MVT::i32 && VT != MVT::i64)
+ return SDValue();
+
+ SDValue SBC = N->getOperand(0);
+ SDValue C = N->getOperand(1);
+ // ADD is commutative; constant may be on either side.
+ if (SBC.getOpcode() != AArch64ISD::SBC)
+ std::swap(SBC, C);
+ if (SBC.getOpcode() != AArch64ISD::SBC || !SBC.hasOneUse())
+ return SDValue();
+ if (!isNullConstant(SBC.getOperand(1)))
+ return SDValue();
+ // AArch64 SBC (non-flag-setting) has only one output; no flags guard needed.
+ auto *CC = dyn_cast<ConstantSDNode>(C);
----------------
davemgreen wrote:
Is it worth doing it for non-const too, to allow the neg to start earlier and create a possibly shorted critical path?
https://github.com/llvm/llvm-project/pull/185117
More information about the llvm-commits
mailing list