[llvm] [VPlan] Allow folding not (cmp eq) -> icmp ne with other select users (PR #154497)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 20 11:19:52 PDT 2025


================
@@ -1107,13 +1107,30 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
       return Def->replaceAllUsesWith(A);
 
     // Try to fold Not into compares by adjusting the predicate in-place.
-    if (isa<VPWidenRecipe>(A) && A->getNumUsers() == 1) {
+    auto CanFold = [&A](VPUser *U) {
+      return match(
+          U, m_CombineOr(m_Not(m_Specific(A)),
+                         m_Select(m_Specific(A), m_VPValue(), m_VPValue())));
+    };
+    if (isa<VPWidenRecipe>(A) && all_of(A->users(), CanFold)) {
----------------
artagnon wrote:

I only have one idea to improve this for clarity, maybe worth pursuing?

```cpp
CmpPredicate Pred;
if (match(A, m_Cmp(Pred, m_VPValue(), m_VPValue()) {
  auto NotUsers = filter_range(A->users(), [&A](VPUser *U) { match(U, m_Not(m_Specific(A))); };
  auto SelectUsers = filter_range(A->users(), [&A](VPUser *U) { match(U, m_Select(m_Specific(A), m_VPValue(), m_VPValue())); };
  if (size(NotUsers) + size(SelectUsers) == A->getNumUsers()) {
    A->setPredicate(CmpInst::getInversePredicate(Pred));
    for_each(NotUsers, [](VPUser *U) { cast<VPSingleDefRecipe>(U)->replaceAllUsesWith(A); });
    for_each(SelectUsers, [](VPUser *U) { auto *R = cast<VPSingleDefRecipe>(U); match(U, m_Select(m_VPValue(), m_VPValue(X), m_VPValue(Y))); R->setOperand(0, Y); R->setOperand(1, X); }
  }
}
```

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


More information about the llvm-commits mailing list