[llvm] [LV][EVL] Reimplement method for extracting new mask. nfc (PR #156827)
Mel Chen via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 4 01:31:53 PDT 2025
https://github.com/Mel-Chen created https://github.com/llvm/llvm-project/pull/156827
During tail folding by EVL, the functionality of the header mask is replaced by EVL. Therefore, during EVL lowering, the header mask should be excluded from the mask AND-tree, and a new mask should be reconstructed.
>From bf8402892400dfb0f0d8e2132ece8145ea643c94 Mon Sep 17 00:00:00 2001
From: Mel Chen <mel.chen at sifive.com>
Date: Wed, 3 Sep 2025 03:23:03 -0700
Subject: [PATCH 1/2] evl, Rrefine get GetNewMask
---
.../Transforms/Vectorize/VPlanTransforms.cpp | 44 +++++++++++++++++--
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index c588453091fcc..c25dcc364171d 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -2403,10 +2403,46 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
auto GetNewMask = [&](VPValue *OrigMask) -> VPValue * {
assert(OrigMask && "Unmasked recipe when folding tail");
// HeaderMask will be handled using EVL.
- VPValue *Mask;
- if (match(OrigMask, m_LogicalAnd(m_Specific(HeaderMask), m_VPValue(Mask))))
- return Mask;
- return HeaderMask == OrigMask ? nullptr : OrigMask;
+ bool FoundHeaderMask = false;
+ SmallVector<VPValue *, 2> Operands, Worklist;
+ Worklist.push_back(OrigMask);
+ while (!Worklist.empty()) {
+ VPValue *Cur = Worklist.pop_back_val();
+ // Replace header mask with all-true mask.
+ if (Cur == HeaderMask) {
+ Operands.push_back(&AllOneMask);
+ FoundHeaderMask = true;
+ continue;
+ }
+
+ VPValue *Op1, *Op2;
+ if (match(Cur, m_LogicalAnd(m_VPValue(Op1), m_VPValue(Op2)))) {
+ Worklist.append({Op1, Op2});
+ continue;
+ }
+ // Stop to query if the value is not in the and-tree.
+ Operands.push_back(Cur);
+ }
+
+ // Return original mask if there is no header mask in the and-tree.
+ // FIXME: Should be assertion here?
+ if (!FoundHeaderMask)
+ return OrigMask;
+ // The new mask is all-true if the header mask is in the and-tree and there
+ // is only one operand we need to do logical-and.
+ if (Operands.size() == 1)
+ return nullptr;
+ // Otherwise, create the and-tree for new mask.
+ VPBuilder Builder(cast<VPInstruction>(OrigMask));
+ VPValue *NewMask = Operands.pop_back_val();
+ while (!Operands.empty()) {
+ VPValue *Op = Operands.pop_back_val();
+ // Skip the operand if it is all-true.
+ if (match(Op, m_True()))
+ continue;
+ NewMask = Builder.createLogicalAnd(NewMask, Op);
+ }
+ return NewMask;
};
/// Adjust any end pointers so that they point to the end of EVL lanes not VF.
>From 13fdece6be87b9e86760da3a82480eb77ae503f3 Mon Sep 17 00:00:00 2001
From: Mel Chen <mel.chen at sifive.com>
Date: Thu, 4 Sep 2025 00:53:02 -0700
Subject: [PATCH 2/2] refine code
---
llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index c25dcc364171d..388dc013acfc4 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -2408,9 +2408,8 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
Worklist.push_back(OrigMask);
while (!Worklist.empty()) {
VPValue *Cur = Worklist.pop_back_val();
- // Replace header mask with all-true mask.
+ // Skip the header mask, since it will be replaced by an all-true mask.
if (Cur == HeaderMask) {
- Operands.push_back(&AllOneMask);
FoundHeaderMask = true;
continue;
}
@@ -2420,7 +2419,7 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
Worklist.append({Op1, Op2});
continue;
}
- // Stop to query if the value is not in the and-tree.
+ // Stop to query if the value is leaf in the and-tree.
Operands.push_back(Cur);
}
@@ -2428,18 +2427,16 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
// FIXME: Should be assertion here?
if (!FoundHeaderMask)
return OrigMask;
- // The new mask is all-true if the header mask is in the and-tree and there
- // is only one operand we need to do logical-and.
- if (Operands.size() == 1)
+ // The new mask is all-true if there are no values to logical-and with,
+ // other than the header mask itself.
+ if (Operands.empty())
return nullptr;
// Otherwise, create the and-tree for new mask.
+ // TODO: Add a mask cache to avoid generating duplicate masks.
VPBuilder Builder(cast<VPInstruction>(OrigMask));
VPValue *NewMask = Operands.pop_back_val();
while (!Operands.empty()) {
VPValue *Op = Operands.pop_back_val();
- // Skip the operand if it is all-true.
- if (match(Op, m_True()))
- continue;
NewMask = Builder.createLogicalAnd(NewMask, Op);
}
return NewMask;
More information about the llvm-commits
mailing list