Skip to content

Commit e235fd2

Browse files
committed
[VPlan] Move findCommonEdgeMask optimization to simplifyBlends
Following up from llvm#150368, this moves folding common edge masks into simplifyBlends. One test in uniform-blend.ll ended up regressing but after looking at it closely, it came from a weird (x && !x) edge mask. So I've just included a simplifcation in this PR to fold that to false. This is an alternative to llvm#150369.
1 parent 020dff4 commit e235fd2

File tree

4 files changed

+34
-31
lines changed

4 files changed

+34
-31
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,6 +2413,12 @@ class LLVM_ABI_FOR_TEST VPBlendRecipe : public VPSingleDefRecipe {
24132413
return Idx == 0 ? getOperand(1) : getOperand(Idx * 2 + !isNormalized());
24142414
}
24152415

2416+
/// Set mask number \p Idx to \p V.
2417+
void setMask(unsigned Idx, VPValue *V) {
2418+
assert((Idx > 0 || !isNormalized()) && "First index has no mask!");
2419+
Idx == 0 ? setOperand(1, V) : setOperand(Idx * 2 + !isNormalized(), V);
2420+
}
2421+
24162422
void execute(VPTransformState &State) override {
24172423
llvm_unreachable("VPBlendRecipe should be expanded by simplifyBlends");
24182424
}

llvm/lib/Transforms/Vectorize/VPlanPredicator.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ class VPPredicator {
6767
return EdgeMaskCache[{Src, Dst}] = Mask;
6868
}
6969

70-
/// Given a phi \p PhiR, try to see if its incoming blocks all share a common
71-
/// edge and return its mask.
72-
VPValue *findCommonEdgeMask(const VPPhi *PhiR) const;
73-
7470
public:
7571
/// Returns the precomputed predicate of the edge from \p Src to \p Dst.
7672
VPValue *getEdgeMask(const VPBasicBlock *Src, const VPBasicBlock *Dst) const {
@@ -232,21 +228,6 @@ void VPPredicator::createSwitchEdgeMasks(VPInstruction *SI) {
232228
setEdgeMask(Src, DefaultDst, DefaultMask);
233229
}
234230

235-
VPValue *VPPredicator::findCommonEdgeMask(const VPPhi *PhiR) const {
236-
VPValue *EdgeMask = getEdgeMask(PhiR->getIncomingBlock(0), PhiR->getParent());
237-
VPValue *CommonEdgeMask;
238-
if (!EdgeMask ||
239-
!match(EdgeMask, m_LogicalAnd(m_VPValue(CommonEdgeMask), m_VPValue())))
240-
return nullptr;
241-
for (const VPBasicBlock *InVPBB : drop_begin(PhiR->incoming_blocks())) {
242-
EdgeMask = getEdgeMask(InVPBB, PhiR->getParent());
243-
assert(EdgeMask && "Both null and non-null edge masks found");
244-
if (!match(EdgeMask, m_LogicalAnd(m_Specific(CommonEdgeMask), m_VPValue())))
245-
return nullptr;
246-
}
247-
return CommonEdgeMask;
248-
}
249-
250231
void VPPredicator::convertPhisToBlends(VPBasicBlock *VPBB) {
251232
SmallVector<VPPhi *> Phis;
252233
for (VPRecipeBase &R : VPBB->phis())
@@ -258,7 +239,6 @@ void VPPredicator::convertPhisToBlends(VPBasicBlock *VPBB) {
258239
// be duplications since this is a simple recursive scan, but future
259240
// optimizations will clean it up.
260241

261-
VPValue *CommonEdgeMask = findCommonEdgeMask(PhiR);
262242
SmallVector<VPValue *, 2> OperandsWithMask;
263243
for (const auto &[InVPV, InVPBB] : PhiR->incoming_values_and_blocks()) {
264244
OperandsWithMask.push_back(InVPV);
@@ -269,14 +249,6 @@ void VPPredicator::convertPhisToBlends(VPBasicBlock *VPBB) {
269249
break;
270250
}
271251

272-
// If all incoming blocks share a common edge, remove it from the mask.
273-
if (CommonEdgeMask) {
274-
VPValue *X;
275-
if (match(EdgeMask,
276-
m_LogicalAnd(m_Specific(CommonEdgeMask), m_VPValue(X))))
277-
EdgeMask = X;
278-
}
279-
280252
OperandsWithMask.push_back(EdgeMask);
281253
}
282254
PHINode *IRPhi = cast_or_null<PHINode>(PhiR->getUnderlyingValue());

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,13 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
10921092
return;
10931093
}
10941094

1095+
// x && !x -> 0
1096+
if (match(&R, m_LogicalAnd(m_VPValue(X), m_Not(m_Deferred(X))))) {
1097+
Def->replaceAllUsesWith(Plan->getOrAddLiveIn(
1098+
ConstantInt::getFalse(VPTypeAnalysis(*Plan).inferScalarType(Def))));
1099+
return;
1100+
}
1101+
10951102
if (match(Def, m_Select(m_VPValue(), m_VPValue(X), m_Deferred(X))))
10961103
return Def->replaceAllUsesWith(X);
10971104

@@ -1293,6 +1300,23 @@ static void narrowToSingleScalarRecipes(VPlan &Plan) {
12931300
}
12941301
}
12951302

1303+
/// Try to see if all of \p Blend's masks share a common value logically and'ed
1304+
/// and remove it from the masks.
1305+
static void removeCommonBlendMask(VPBlendRecipe *Blend) {
1306+
if (Blend->isNormalized())
1307+
return;
1308+
VPValue *CommonEdgeMask;
1309+
if (!match(Blend->getMask(0),
1310+
m_LogicalAnd(m_VPValue(CommonEdgeMask), m_VPValue())))
1311+
return;
1312+
for (unsigned I = 0; I < Blend->getNumIncomingValues(); I++)
1313+
if (!match(Blend->getMask(I),
1314+
m_LogicalAnd(m_Specific(CommonEdgeMask), m_VPValue())))
1315+
return;
1316+
for (unsigned I = 0; I < Blend->getNumIncomingValues(); I++)
1317+
Blend->setMask(I, Blend->getMask(I)->getDefiningRecipe()->getOperand(1));
1318+
}
1319+
12961320
/// Normalize and simplify VPBlendRecipes. Should be run after simplifyRecipes
12971321
/// to make sure the masks are simplified.
12981322
static void simplifyBlends(VPlan &Plan) {
@@ -1303,6 +1327,8 @@ static void simplifyBlends(VPlan &Plan) {
13031327
if (!Blend)
13041328
continue;
13051329

1330+
removeCommonBlendMask(Blend);
1331+
13061332
// Try to remove redundant blend recipes.
13071333
SmallPtrSet<VPValue *, 4> UniqueValues;
13081334
if (Blend->isNormalized() || !match(Blend->getMask(0), m_False()))

llvm/test/Transforms/LoopVectorize/uniform-blend.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ define void @blend_chain_iv(i1 %c) {
130130
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
131131
; CHECK: [[VECTOR_BODY]]:
132132
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
133-
; CHECK-NEXT: [[PREDPHI:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
134-
; CHECK-NEXT: [[PREDPHI1:%.*]] = select <4 x i1> [[BROADCAST_SPLAT]], <4 x i64> [[PREDPHI]], <4 x i64> undef
133+
; CHECK-NEXT: [[PREDPHI1:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
135134
; CHECK-NEXT: [[PREDPHI2:%.*]] = select <4 x i1> [[BROADCAST_SPLAT]], <4 x i64> [[PREDPHI1]], <4 x i64> undef
136135
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i64> [[PREDPHI2]], i32 0
137136
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [32 x i16], ptr @dst, i16 0, i64 [[TMP1]]
@@ -146,7 +145,7 @@ define void @blend_chain_iv(i1 %c) {
146145
; CHECK-NEXT: store i16 0, ptr [[TMP6]], align 2
147146
; CHECK-NEXT: store i16 0, ptr [[TMP8]], align 2
148147
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
149-
; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[PREDPHI]], splat (i64 4)
148+
; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[PREDPHI1]], splat (i64 4)
150149
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], 32
151150
; CHECK-NEXT: br i1 [[TMP9]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
152151
; CHECK: [[MIDDLE_BLOCK]]:

0 commit comments

Comments
 (0)