[llvm] InstCombine: improve optimizations for ceiling division with no overflow (PR #142869)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 16 00:38:43 PDT 2025


================
@@ -1787,6 +1787,36 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
   if (Instruction *Ashr = foldAddToAshr(I))
     return Ashr;
 
+  // Ceiling division by power-of-2:
+  // (X >> log2(N)) + zext(X & (N-1) != 0) --> (X + (N-1)) >> log2(N)
+  // This is valid when adding (N-1) to X doesn't overflow.
+  {
+    Value *X = nullptr;
+    const APInt *ShiftAmt = nullptr, *Mask = nullptr;
+    CmpPredicate Pred;
+
+    // Match: (X >> C) + zext((X & Mask) != 0)
+    // or:    zext((X & Mask) != 0) + (X >> C)
+    if (match(&I, m_c_Add(m_OneUse(m_LShr(m_Value(X), m_APInt(ShiftAmt))),
+                          m_ZExt(m_SpecificICmp(
+                              ICmpInst::ICMP_NE,
+                              m_And(m_Deferred(X), m_LowBitMask(Mask)),
+                              m_ZeroInt())))) &&
+        Mask->popcount() == *ShiftAmt) {
+
+      // Check if X + Mask doesn't overflow
+      Constant *MaskC = ConstantInt::get(X->getType(), *Mask);
+      bool WillNotOverflowUnsigned = willNotOverflowUnsignedAdd(X, MaskC, I);
+
+      if (WillNotOverflowUnsigned) {
----------------
nikic wrote:

```suggestion
      if (willNotOverflowUnsignedAdd(X, MaskC, I)) {
```

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


More information about the llvm-commits mailing list