[llvm] [VPlan] Perform optimizeMaskToEVL in terms of pattern matching (PR #155394)

Mel Chen via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 11 04:20:13 PDT 2025


================
@@ -587,6 +588,79 @@ m_DerivedIV(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
   return VPDerivedIV_match<Op0_t, Op1_t, Op2_t>({Op0, Op1, Op2});
 }
 
+template <typename Addr_t, typename Mask_t, bool Reverse> struct Load_match {
+  Addr_t Addr;
+  Mask_t Mask;
+
+  Load_match(Addr_t Addr, Mask_t Mask) : Addr(Addr), Mask(Mask) {}
+
+  template <typename OpTy> bool match(const OpTy *V) const {
+    auto *Load = dyn_cast<VPWidenLoadRecipe>(V);
+    if (!Load || Load->isReverse() != Reverse || !Addr.match(Load->getAddr()) ||
+        !Load->isMasked() || !Mask.match(Load->getMask()))
+      return false;
+    return true;
+  }
+};
+
+/// Match a non-reversed masked load.
+template <typename Addr_t, typename Mask_t>
+inline Load_match<Addr_t, Mask_t, false> m_Load(const Addr_t &Addr,
+                                                const Mask_t &Mask) {
+  return Load_match<Addr_t, Mask_t, false>(Addr, Mask);
+}
+
+/// Match a reversed masked load.
+template <typename Addr_t, typename Mask_t>
+inline Load_match<Addr_t, Mask_t, true> m_ReverseLoad(const Addr_t &Addr,
+                                                      const Mask_t &Mask) {
+  return Load_match<Addr_t, Mask_t, true>(Addr, Mask);
+}
+
+template <typename Addr_t, typename Val_t, typename Mask_t, bool Reverse>
+struct Store_match {
+  Addr_t Addr;
+  Val_t Val;
+  Mask_t Mask;
+
+  Store_match(Addr_t Addr, Val_t Val, Mask_t Mask)
+      : Addr(Addr), Val(Val), Mask(Mask) {}
+
+  template <typename OpTy> bool match(const OpTy *V) const {
+    auto *Store = dyn_cast<VPWidenStoreRecipe>(V);
+    if (!Store || Store->isReverse() != Reverse ||
----------------
Mel-Chen wrote:

This approach seems to work for now, but it’s not a long-term solution. In the future, a reverse recipe might be sunk, meaning the reverse recipe would no longer directly use the loaded result. For example, consider this simplification rule: `BinOp(reverse(V1), reverse(V2)) --> reverse(BinOp(V1, V2))`.

But you gave me a really good idea! This won’t happen with reverse stores. The reverse of a stored value will only be eliminated, not sunk. So this method should work for reverse stores, but I don’t think it will work for reverse loads.
https://github.com/llvm/llvm-project/pull/146525/commits/ef2d02745fa63a0c48836c4c5920711ef3ad786c


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


More information about the llvm-commits mailing list