[llvm] [InstCombine] Simplify and/or of icmp eq with op replacement (PR #70335)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 26 11:24:45 PDT 2023


================
@@ -2025,6 +2025,50 @@ static Value *simplifyAndOrOfCmps(const SimplifyQuery &Q, Value *Op0,
   return nullptr;
 }
 
+static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
+                                     const SimplifyQuery &Q,
+                                     bool AllowRefinement,
+                                     SmallVectorImpl<Instruction *> *DropFlags,
+                                     unsigned MaxRecurse);
+
+static Value *simplifyAndOrWithICmpEq(unsigned Opcode, Value *Op0, Value *Op1,
+                                      const SimplifyQuery &Q,
+                                      unsigned MaxRecurse) {
+  assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&
+         "Must be and/or");
+  ICmpInst::Predicate Pred;
+  Value *A, *B;
+  if (!match(Op0, m_ICmp(Pred, m_Value(A), m_Value(B))) ||
+      !ICmpInst::isEquality(Pred) || !MaxRecurse--)
+    return nullptr;
+
+  auto Simplify = [&](Value *Res) -> Value * {
+    // and (icmp eq a, b), x implies (a==b) inside x.
+    // or (icmp ne a, b), x implies (a==b) inside x.
+    // If x simplifies to true/false, we can simplify the and/or.
+    if (Pred ==
+        (Opcode == Instruction::And ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE))
+      return simplifyBinOp(Opcode, Op0, Res, Q, MaxRecurse);
+    // If we have and (icmp ne a, b), x and for a==b we can simplify x to false,
+    // then we can drop the icmp, as x will already be false in the case where
+    // the icmp is false. Similar for or and true.
+    if (Res == ConstantExpr::getBinOpAbsorber(Opcode, Res->getType()))
+      return Op1;
+    return nullptr;
+  };
+
+  if (Value *Res =
+          simplifyWithOpReplaced(Op1, A, B, Q, /* AllowRefinement */ true,
+                                 /* DropFlags */ nullptr, MaxRecurse))
+    return Simplify(Res);
+  if (Value *Res =
+          simplifyWithOpReplaced(Op1, B, A, Q, /* AllowRefinement */ true,
+                                 /* DropFlags */ nullptr, MaxRecurse))
+    return Simplify(Res);
----------------
dtcxzyw wrote:

```suggestion
  if(!isa<Constant>(B))
  if (Value *Res =
          simplifyWithOpReplaced(Op1, B, A, Q, /* AllowRefinement */ true,
                                 /* DropFlags */ nullptr, MaxRecurse))
    return Simplify(Res);
```
I guess we can skip this if RHS is a constant.


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


More information about the llvm-commits mailing list