[llvm] [InstCombine] Fold `(x == A) || (x & -Pow2) == A + 1` into range check (PR #153842)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 21 08:37:47 PDT 2025


================
@@ -1338,16 +1338,51 @@ Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(ICmpInst *ICmp1,
       V2 = X;
   }
 
+  // Look through and with a negative power of 2 mask on V1 or V2. This
+  // detects idioms of the form `(x == A) || ((x & Mask) == A + 1)` where A + 1
+  // is aligned to the mask and A + 1 >= |Mask|. This pattern corresponds to a
+  // contiguous range check, which can be folded into an addition and compare.
+  // The same applies for `(x != A) && ((x & Mask) != A + 1)`.
+  auto AreContiguousRangePredicates = [](CmpPredicate Pred1, CmpPredicate Pred2,
+                                         bool IsAnd) {
+    if (IsAnd)
+      return Pred1 == ICmpInst::ICMP_NE && Pred2 == ICmpInst::ICMP_NE;
+    return Pred1 == ICmpInst::ICMP_EQ && Pred2 == ICmpInst::ICMP_EQ;
+  };
+  const APInt *Mask1 = nullptr, *Mask2 = nullptr;
+  bool MatchedAnd1 = false, MatchedAnd2 = false;
+  if (V1 != V2 && AreContiguousRangePredicates(Pred1, Pred2, IsAnd)) {
+    Value *X;
+    if (match(V1, m_OneUse(m_And(m_Value(X), m_NegatedPower2(Mask1)))) &&
+        C1->getBitWidth() == C2->getBitWidth() && *C1 == *C2 + 1 &&
+        C1->uge(Mask1->abs()) && C1->isPowerOf2()) {
+      MatchedAnd1 = true;
+      V1 = X;
+    }
+    if (match(V2, m_OneUse(m_And(m_Value(X), m_NegatedPower2(Mask2)))) &&
+        C1->getBitWidth() == C2->getBitWidth() && *C2 == *C1 + 1 &&
+        C2->uge(Mask2->abs()) && C2->isPowerOf2()) {
+      MatchedAnd2 = true;
+      V2 = X;
+    }
+  }
+
   if (V1 != V2)
     return nullptr;
 
-  ConstantRange CR1 = ConstantRange::makeExactICmpRegion(
-      IsAnd ? ICmpInst::getInverseCmpPredicate(Pred1) : Pred1, *C1);
+  ConstantRange CR1 =
+      MatchedAnd1
+          ? ConstantRange(*C1, *C1 - *Mask1)
----------------
dtcxzyw wrote:

Doesn't it need to be inverted when `IsAnd` is true?



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


More information about the llvm-commits mailing list