Skip to content

Commit 2d0d65b

Browse files
committed
[VPlan] Create edge masks all cases up front needed.(NFC)
Similarly to how block masks are created up front and later only retrieved also make sure masks are created in cases where edge masks are needed, i.e. blend recipes. Creating block-in masks for all blocks in the loop also ensures edge masks for all relevant edges have been created. Later, the new getEdgeMask can be used to look up cached edge masks. This makes sure edge masks are available in all cases for #76090.
1 parent a7cfff8 commit 2d0d65b

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8038,6 +8038,17 @@ VPValue *VPRecipeBuilder::createEdgeMask(BasicBlock *Src, BasicBlock *Dst,
80388038
return EdgeMaskCache[Edge] = EdgeMask;
80398039
}
80408040

8041+
VPValue *VPRecipeBuilder::getEdgeMask(BasicBlock *Src, BasicBlock *Dst) const {
8042+
assert(is_contained(predecessors(Dst), Src) && "Invalid edge");
8043+
8044+
// Look for cached value.
8045+
std::pair<BasicBlock *, BasicBlock *> Edge(Src, Dst);
8046+
EdgeMaskCacheTy::const_iterator ECEntryIt = EdgeMaskCache.find(Edge);
8047+
assert(ECEntryIt != EdgeMaskCache.end() &&
8048+
"looking up mask for edge which has not been created");
8049+
return ECEntryIt->second;
8050+
}
8051+
80418052
void VPRecipeBuilder::createHeaderMask(VPlan &Plan) {
80428053
BasicBlock *Header = OrigLoop->getHeader();
80438054

@@ -8728,10 +8739,13 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
87288739
DFS.perform(LI);
87298740

87308741
VPBasicBlock *VPBB = HeaderVPBB;
8731-
bool NeedsMasks = CM.foldTailByMasking() ||
8732-
any_of(OrigLoop->blocks(), [this](BasicBlock *BB) {
8733-
return Legal->blockNeedsPredication(BB);
8734-
});
8742+
BasicBlock *HeaderBB = OrigLoop->getHeader();
8743+
bool NeedsMasks =
8744+
CM.foldTailByMasking() ||
8745+
any_of(OrigLoop->blocks(), [this, HeaderBB](BasicBlock *BB) {
8746+
bool NeedsBlends = BB != HeaderBB && !BB->phis().empty();
8747+
return Legal->blockNeedsPredication(BB) || NeedsBlends;
8748+
});
87358749
for (BasicBlock *BB : make_range(DFS.beginRPO(), DFS.endRPO())) {
87368750
// Relevant instructions from basic block BB will be grouped into VPRecipe
87378751
// ingredients and fill a new VPBasicBlock.
@@ -8750,7 +8764,7 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
87508764
Instruction *Instr = &I;
87518765
SmallVector<VPValue *, 4> Operands;
87528766
auto *Phi = dyn_cast<PHINode>(Instr);
8753-
if (Phi && Phi->getParent() == OrigLoop->getHeader()) {
8767+
if (Phi && Phi->getParent() == HeaderBB) {
87548768
Operands.push_back(Plan->getVPValueOrAddLiveIn(
87558769
Phi->getIncomingValueForBlock(OrigLoop->getLoopPreheader())));
87568770
} else {

llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ class VPRecipeBuilder {
148148
/// and DST.
149149
VPValue *createEdgeMask(BasicBlock *Src, BasicBlock *Dst, VPlan &Plan);
150150

151+
/// A helper that returns the previously computed predicate of the edge
152+
/// between SRC and DST.
153+
VPValue *getEdgeMask(BasicBlock *Src, BasicBlock *Dst) const;
154+
151155
/// Mark given ingredient for recording its recipe once one is created for
152156
/// it.
153157
void recordRecipeOf(Instruction *I) {

0 commit comments

Comments
 (0)