[llvm] [InstCombine] Fold `ceil(X / (2 ^ C)) == 0` -> `X == 0` (PR #143683)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 13 06:05:29 PDT 2025


================
@@ -1300,17 +1300,16 @@ Instruction *InstCombinerImpl::foldICmpWithZero(ICmpInst &Cmp) {
     // will fold to a constant elsewhere.
   }
 
-  // (X >> C) + ((X & ((1 << C) - 1)) != 0) == 0 -> X == 0
-  if (Pred == ICmpInst::ICMP_EQ) {
+  // (X >> C) | ((X & ((1 << C) - 1)) != 0) == 0 -> X == 0
+  if (ICmpInst::isEquality(Pred)) {
     Value *X;
     const APInt *C1, *C2;
-    CmpPredicate PredNE;
     if (match(Cmp.getOperand(0),
-              m_OneUse(
-                  m_Add(m_LShr(m_Value(X), m_APInt(C1)),
-                        m_ZExt(m_ICmp(PredNE, m_And(m_Deferred(X), m_APInt(C2)),
-                                      m_Zero()))))) &&
-        PredNE == CmpInst::ICMP_NE &&
+              m_OneUse(m_c_Or(
+                  m_LShr(m_Value(X), m_APInt(C1)),
+                  m_ZExt(m_SpecificICmp(ICmpInst::ICMP_NE,
+                                        m_And(m_Deferred(X), m_APInt(C2)),
+                                        m_Zero()))))) &&
         *C2 == APInt::getLowBitsSet(C2->getBitWidth(), C1->getZExtValue()))
----------------
dtcxzyw wrote:

```suggestion
              m_OneUse(m_c_Or(
                  m_LShr(m_Value(X), m_APInt(C1)),
                  m_ZExt(m_SpecificICmp(ICmpInst::ICMP_NE,
                                        m_And(m_Deferred(X), m_LowBitMask(C2)),
                                        m_Zero()))))) &&
        C2->popcount() == C1->getZExtValue())
```
`getLowBitsSet` may assert when C1 is out of bounds. I think this one is safer.


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


More information about the llvm-commits mailing list