[llvm] [InstCombine] Generalize `icmp (shl nuw C2, Y), C -> icmp Y, C3` (PR #104696)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 18 03:31:09 PDT 2024


================
@@ -2227,18 +2227,24 @@ Instruction *InstCombinerImpl::foldICmpMulConstant(ICmpInst &Cmp,
   return NewC ? new ICmpInst(Pred, X, NewC) : nullptr;
 }
 
-/// Fold icmp (shl 1, Y), C.
-static Instruction *foldICmpShlOne(ICmpInst &Cmp, Instruction *Shl,
-                                   const APInt &C) {
+/// Fold icmp (shl nuw C2, Y), C.
+static Instruction *foldICmpShlLHSC(ICmpInst &Cmp, Instruction *Shl,
+                                    const APInt &C) {
   Value *Y;
-  if (!match(Shl, m_Shl(m_One(), m_Value(Y))))
+  const APInt *C2;
+  if (!match(Shl, m_NUWShl(m_APInt(C2), m_Value(Y))))
     return nullptr;
 
   Type *ShiftType = Shl->getType();
   unsigned TypeBits = C.getBitWidth();
-  bool CIsPowerOf2 = C.isPowerOf2();
   ICmpInst::Predicate Pred = Cmp.getPredicate();
   if (Cmp.isUnsigned()) {
+    APInt Div, Rem;
+    APInt::udivrem(C, *C2, Div, Rem);
+    if (!Rem.isZero())
+      return nullptr;
----------------
dtcxzyw wrote:

> Can this be generalized to the non-rem-0 case? Taking your example, `icmp ult (shl nuw C2, X), 64 -> icmp ult X, 2` holds for any C2 in [16,31].

Do you have any ideas to handle these non-rem-0 cases? If not, I will convert `icmp ugt (shl nuw C2, X), C3 -> icmp uge (shl nuw C2, X), C3 + 1` to cover more real-world cases.
 


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


More information about the llvm-commits mailing list