[llvm] [CGP] Reconstruct borrow chain from icmp pattern for subtract-with-carry (PR #189018)

Paweł Bylica via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 7 14:48:40 PDT 2026


================
@@ -1797,6 +1798,66 @@ bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp,
   return true;
 }
 
+/// FIXME: The name is similar to combineToUSubWithOverflow. Consider renaming
+/// one or both to better distinguish them.
+///
+/// Reconstruct a subtract-with-borrow chain from its canonicalized icmp form.
+///
+/// InstCombine simplifies chained usub.with.overflow intrinsics (used for
+/// multi-precision subtraction) into icmp patterns:
+///   carry_out = or(icmp ult A, B, and(icmp eq A, B, carry_in))
+///
+/// This is algebraically correct but prevents the backend from generating
+/// efficient subtract-with-borrow instructions (e.g. x86 sbb, aarch64 sbcs).
+///
+/// This function matches the pattern and reconstructs the chained
+/// usub.with.overflow form that the DAG combiner can lower to USUBO_CARRY.
+bool CodeGenPrepare::combineToUSubWithCarry(BinaryOperator *OrI) {
+  if (!OrI->getType()->isIntOrIntVectorTy(1))
+    return false;
+
+  assert(OrI->getOpcode() == Instruction::Or && "Expected or instruction");
+
+  // Match: or(icmp ult A, B, and(icmp eq A, B, carry_in))
+  // with all commuted variants of and and icmp eq operand order.
+  Value *A, *B, *CarryIn;
+  if (!match(
+          OrI,
+          m_c_BinOp(m_SpecificICmp(ICmpInst::ICMP_ULT, m_Value(A), m_Value(B)),
----------------
chfast wrote:

Fixed.

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


More information about the llvm-commits mailing list