[llvm] [InstCombine] Make the `(icmp eq/ne (and X, Y), X)` canonicalization work for non-const operands (PR #84688)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 22 06:38:48 PDT 2024


================
@@ -4709,6 +4709,26 @@ static Instruction *foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q,
   if (Pred == ICmpInst::ICMP_UGE)
     return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
 
+  if (ICmpInst::isEquality(Pred) && Op0->hasOneUse()) {
+    // icmp (X & Y) eq/ne Y --> (X | ~Y) eq/ne -1 if Y is freely invertible and
+    // Y is non-constant. If Y is constant this form is preferable (and
+    // canonicalize too it elsewhere).
+    if (!match(Op1, m_ImmConstant()))
+      if (auto *NotOp1 =
+              IC.getFreelyInverted(Op1, !Op1->hasNUsesOrMore(3), &IC.Builder))
+        return new ICmpInst(Pred, IC.Builder.CreateOr(A, NotOp1),
+                            Constant::getAllOnesValue(Op1->getType()));
+    // icmp (X & Y) eq/ne Y --> (~X & Y) eq/ne 0 if X  is freely invertible.
+    // Since we may be consuming a `not` here, first check if we match
+    // `foldICmpWithLowBitMaskedVal` as it is a "better" user of `not`
+    // instructions.
+    if (Value *R = foldICmpWithLowBitMaskedVal(Pred, Op0, Op1, Q, IC))
----------------
dtcxzyw wrote:

Please add some tests to demonstrate this behavior.

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


More information about the llvm-commits mailing list