[llvm] [InstCombine] Fold umul.overflow(x, c1) | (x*c1 > c2) to x > c2/c1 (PR #147327)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 9 12:56:07 PDT 2025
================
@@ -3717,6 +3717,30 @@ Value *InstCombinerImpl::reassociateDisjointOr(Value *LHS, Value *RHS) {
return nullptr;
}
+/// Fold Res, Overflow = (umul.with.overflow x c1); (or Overflow (ugt Res c2))
+/// --> (ugt x (c2/c1)). This code checks whether a multiplication of two
+/// unsigned numbers (one is a constant) is mathematically greater than a
+/// second constant.
+static Value *foldOrUnsignedUMulOverflowICmp(BinaryOperator &I,
+ InstCombiner::BuilderTy &Builder,
+ const DataLayout &DL) {
+ const WithOverflowInst *WO;
+ const Value *WOV;
+ const APInt *C1, *C2;
+ if (match(&I,
+ m_c_Or(m_ExtractValue<1>(
+ m_CombineAnd(m_WithOverflowInst(WO), m_Value(WOV))),
+ m_OneUse(m_SpecificCmp(ICmpInst::ICMP_UGT,
+ m_ExtractValue<0>(m_Deferred(WOV)),
+ m_APInt(C2))))) &&
+ WO->getIntrinsicID() == Intrinsic::umul_with_overflow &&
+ match(WO->getRHS(), m_APInt(C1)) && !C1->isZero() && WO->hasNUses(2)) {
----------------
nikic wrote:
For the same reason as the others, I'd drop the use check on WO as well. Even if there are other uses, we still at least simplify or+icmp to icmp.
(More than two uses would be somewhat unusual anyway, because it means there are redundant extracts. May happen if they don't dominate each other.)
https://github.com/llvm/llvm-project/pull/147327
More information about the llvm-commits
mailing list