[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