[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
Mon Jul 7 09:05:31 PDT 2025


================
@@ -3659,6 +3659,32 @@ static std::optional<DecomposedBitMaskMul> matchBitmaskMul(Value *V) {
   return std::nullopt;
 }
 
+/// 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;
+  Constant *C1, *C2;
+  if (match(&I, m_c_Or(m_OneUse(m_ExtractValue<1>(
+                           m_CombineAnd(m_WithOverflowInst(WO), m_Value(WOV)))),
+                       m_OneUse(m_SpecificCmp(
+                           ICmpInst::ICMP_UGT,
+                           m_OneUse(m_ExtractValue<0>(m_Deferred(WOV))),
+                           m_ImmConstant(C2))))) &&
+      WO->getIntrinsicID() == Intrinsic::umul_with_overflow &&
+      match(WO->getRHS(), m_ImmConstant(C1)) && WO->hasNUses(2)) {
+    assert(!C1->isNullValue()); // This should have been folded away.
----------------
nikic wrote:

I don't think this will do the right thing for a vector constant, which may include zero elements? You either need to limit to splats or check that there are no zero elements.

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


More information about the llvm-commits mailing list