[llvm] [AArch64] Combine subtract with borrow to SBC. (PR #165271)

Ricardo Jesus via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 27 09:33:57 PDT 2025


================
@@ -22328,6 +22328,37 @@ static SDValue performExtBinopLoadFold(SDNode *N, SelectionDAG &DAG) {
   return DAG.getNode(N->getOpcode(), DL, VT, Ext0, NShift);
 }
 
+// Attempt to combine the following patterns:
+//   SUB x, (CSET LO, (CMP a, b)) -> SBC x, 0, (CMP a, b)
+//   SUB (SUB x, y), (CSET LO, (CMP a, b)) -> SBC x, y, (CMP a, b)
+// The CSET may be preceded by a ZEXT.
+static SDValue performSubWithBorrowCombine(SDNode *N, SelectionDAG &DAG) {
+  if (N->getOpcode() != ISD::SUB)
+    return SDValue();
+
+  EVT VT = N->getValueType(0);
+  if (VT != MVT::i32 && VT != MVT::i64)
+    return SDValue();
+
+  SDValue N1 = N->getOperand(1);
+  if (N1.getOpcode() == ISD::ZERO_EXTEND && N1.hasOneUse())
+    N1 = N1.getOperand(0);
+  if (!N1.hasOneUse() || getCSETCondCode(N1) != AArch64CC::LO)
+    return SDValue();
+
+  SDValue Flags = N1.getOperand(3);
+  if (Flags.getOpcode() != AArch64ISD::SUBS)
+    return SDValue();
+
+  SDLoc DL(N);
+  SDValue N0 = N->getOperand(0);
+  if (N0->getOpcode() != ISD::SUB)
+    return DAG.getNode(AArch64ISD::SBC, DL, VT, N0, DAG.getConstant(0, DL, VT),
+                       Flags);
+  return DAG.getNode(AArch64ISD::SBC, DL, VT, N0.getOperand(0),
+                     N0.getOperand(1), Flags);
----------------
rj-jesus wrote:

This could be a separate combine. I kept it here as it didn't seem to affect existing tests (other than the ones in this PR), but I'm happy to implement it separately if that's preferable.

https://github.com/llvm/llvm-project/pull/165271


More information about the llvm-commits mailing list