[llvm] [InstCombine]: Replace overflow calculation with intrinsic (PR #168195)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 4 03:07:33 PST 2025
================
@@ -7161,6 +7164,66 @@ Instruction *InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) {
return nullptr;
}
+/// Fold icmp(ult, sub(add(sext(X), Cst1), sext(Y)), Cst2) -->
+/// extract(__builtin_ssub_overflow(X, Y), 1)
+Instruction *InstCombinerImpl::foldICmpsToSignedSubOverflow(Instruction &I) {
+ CmpPredicate Pred;
+ ConstantInt *Cst1, *Cst2;
+ Value *X, *Y;
+
+ /*
+ This transformation detects the pattern used to check for
+ a signed subtraction overflow.
+
+ The matched sequence performs the following steps:
+
+ 1. X = sext(x)
+ Y = sext(y)
+ // Sign-extend 32-bit operands to 64 bits.
+
+ 2. Shifted = X + Cst1
+ // Shift the signed range [-2^31, 2^31-1] by adding the minimum
+ // signed value (Cst1 = INT_MIN), producing an unsigned range
+ // [0, 2^32).
+
+ 3. Sub = Shifted - Y
+ // Compute the shifted subtraction result.
+
+ 4. icmp ult Sub, Cst2
+ // Check whether the result fits in [0, 2^32).
+ // If not, the subtraction overflowed.
+ */
+
+ auto SExtX = m_SExt(m_Value(X));
+ auto SExtY = m_SExt(m_Value(Y));
+ auto Shifted = m_Add(SExtX, m_ConstantInt(Cst1));
+ auto Sub = m_Sub(Shifted, SExtY);
+
+ if (!match(&I, m_ICmp(Pred, Sub, m_ConstantInt(Cst2))) ||
+ Pred != CmpInst::ICMP_ULT)
+ return nullptr;
+
+ const auto SignedMin =
+ APInt::getSignedMinValue(X->getType()->getScalarSizeInBits());
+ const auto ExpectedRange = SignedMin.getSExtValue() << 1;
+
+ // Cst1 must equal to SignedMin
+ // Cst2 must equal to ExpectedRange
+ if (SignedMin.getSExtValue() != Cst1->getValue().getSExtValue() ||
+ ExpectedRange != Cst2->getValue().getSExtValue())
+ return nullptr;
+
+ Module *M = I.getModule();
+ Function *F = Intrinsic::getOrInsertDeclaration(
+ M, Intrinsic::ssub_with_overflow, X->getType());
+
+ Builder.SetInsertPoint(&I);
----------------
nikic wrote:
There should be no need to explicitly set the insert point.
https://github.com/llvm/llvm-project/pull/168195
More information about the llvm-commits
mailing list