[llvm] [InstCombine] Div ceil optimizations (PR #190175)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 5 12:21:38 PDT 2026
================
@@ -1523,6 +1523,68 @@ static Instruction *foldBoxMultiply(BinaryOperator &I) {
return nullptr;
}
+// Return true if X + (Y-1) is provably non-wrapping in X's type
+static bool checkDivCeilNUW(Value *X, Value *Y, BinaryOperator &I,
+ AssumptionCache &AC, DominatorTree &DT) {
+ ConstantRange CRX = computeConstantRange(X, /*ForSigned=*/false,
+ /*UseInstrInfo=*/true, &AC, &I, &DT);
+ ConstantRange CRY = computeConstantRange(Y, /*ForSigned=*/false,
+ /*UseInstrInfo=*/true, &AC, &I, &DT);
+ APInt MaxX = CRX.getUnsignedMax();
+ APInt MaxY = CRY.getUnsignedMax();
+ unsigned BitWidth = MaxX.getBitWidth();
+ // MaxX + (MaxY - 1) <= UINT_MAX <==> MaxX <= UINT_MAX - (MaxY - 1)
+ return !MaxX.ugt(APInt::getMaxValue(BitWidth) - (MaxY - 1));
+}
+
+// Fold the same-type form of the div_ceil idiom:
+// add(udiv(X, Y), zext(icmp ne(urem(X, Y), 0)))
+// -> udiv(add nuw(X, Y - 1), Y)
+// where udiv and urem are the same type as the add.
+Instruction *InstCombinerImpl::foldSameTypeDivCeil(BinaryOperator &I) {
+ Value *X, *X2, *Y, *Y2;
+ CmpPredicate Pred;
+
+ auto UDivPat = m_OneUse(m_UDiv(m_Value(X), m_Value(Y)));
+ auto URemPat = m_OneUse(m_URem(m_Value(X2), m_Value(Y2)));
+ auto ICmpPat = m_OneUse(m_ICmp(Pred, URemPat, m_Zero()));
+ auto ZExtCmpPat = m_OneUse(m_ZExt(ICmpPat));
+
+ if (!match(&I, m_c_Add(UDivPat, ZExtCmpPat)) || Pred != ICmpInst::ICMP_NE ||
+ X != X2 || Y != Y2 || !checkDivCeilNUW(X, Y, I, AC, DT))
+ return nullptr;
+
+ Value *YMinusOne = Builder.CreateSub(Y, ConstantInt::get(Y->getType(), 1));
+ Value *NUWAdd = Builder.CreateAdd(X, YMinusOne, "", /*HasNUW=*/true);
+ return BinaryOperator::CreateUDiv(NUWAdd, Y);
+}
+
+// Fold the zext form of the div_ceil idiom:
+// add(zext(udiv(X, Y)), zext(icmp ne(urem(X, Y), 0)))
----------------
dtcxzyw wrote:
I'd expect some general transformations like `binop(zext(X), zext(Y)) -> zext(binop(X, Y))`.
https://github.com/llvm/llvm-project/pull/190175
More information about the llvm-commits
mailing list