Skip to content

Commit 403bcaa

Browse files
- Removed Multiplier from existing ActiveLaneMask VPInstruction
- Moved ICMP optimisation to optimizeForVFAndUF - Remove preferTailFoldedLoop from selectInterleaveCount() - Add test with i32 trip count
1 parent 4b0ee0c commit 403bcaa

17 files changed

Lines changed: 378 additions & 168 deletions

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3633,7 +3633,7 @@ LoopVectorizationPlanner::selectInterleaveCount(VPlan &Plan, ElementCount VF,
36333633
// Do not interleave tail-folded loops, as the overhead of multiple
36343634
// instructions to calculate the predicate is likely not beneficial.
36353635
// If an epilogue is not allowed for any other reason, do not interleave.
3636-
if (!CM.isEpilogueAllowed() || CM.preferTailFoldedLoop())
3636+
if (!CM.isEpilogueAllowed())
36373637
return 1;
36383638

36393639
if (any_of(Plan.getVectorLoopRegion()->getEntryBasicBlock()->phis(),

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,8 +1232,13 @@ class LLVM_ABI_FOR_TEST VPInstruction : public VPRecipeWithIRFlags,
12321232
// Creates a mask where each lane is active (true) whilst the current
12331233
// counter (first operand + index) is less than the second operand. i.e.
12341234
// mask[i] = icmpt ult (op0 + i), op1
1235-
// The size of the mask returned is VF * Multiplier (UF, third op).
1235+
// The size of the mask returned is VF.
1236+
// When unrolled, ActiveLaneMask is duplicated.
12361237
ActiveLaneMask,
1238+
// As above, but takes an additional operand (Multiplier). The size of
1239+
// the mask returned is VF * Multiplier (UF, op2).
1240+
// WideActiveLaneMask is used for control flow and is unrolled by widening,
1241+
// with one extract vector created per unroll part.
12371242
WideActiveLaneMask,
12381243
// Extracts each unrolled part of a (VF * UF) widened vector/mask.
12391244
ExtractVectorForPart,

llvm/lib/Transforms/Vectorize/VPlanLowering.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,17 +150,15 @@ addVPLaneMaskPhiAndUpdateExitBranch(VPlan &Plan) {
150150
// TODO: Check if dropping the flags is needed.
151151
TopRegion->clearCanonicalIVNUW(CanonicalIVIncrement);
152152
DebugLoc DL = CanonicalIVIncrement->getDebugLoc();
153-
// We can't use StartV directly in the WideActiveLaneMask
154-
// VPInstruction, since we have to take unrolling into account.
155-
// Each part needs to start at Part * VF
156153
auto *VecPreheader = Plan.getVectorPreheader();
157154
VPBuilder Builder(VecPreheader);
158-
159-
// Create the WideActiveLaneMask instruction using the correct
160-
// start values.
161155
VPValue *TC = Plan.getTripCount();
162156
VPValue *VF = &Plan.getVF();
163157

158+
// We can't use StartV directly in the WideActiveLaneMask
159+
// VPInstruction, since we have to take unrolling into account.
160+
// CanonicalIVIncrementForPart is needed so that ExtractVectorForPart
161+
// is unrolled for each part, rather than each extract starting at 0.
164162
auto *EntryIncrement =
165163
Builder.createOverflowingOp(VPInstruction::CanonicalIVIncrementForPart,
166164
{StartV, VF}, {}, DL, "index.part.next");
@@ -224,12 +222,9 @@ void VPlanTransforms::materializeHeaderMask(
224222
VPIRFlags::WrapFlagsTy(/*HasNUW=*/true, /*HasNSW=*/false)));
225223
VPValue *Mask;
226224
if (UseActiveLaneMask) {
227-
VPValue *ALMMultiplier =
228-
Plan.getConstantInt(LoopRegion->getCanonicalIVType(), 1);
229-
Mask = Builder.createNaryOp(
230-
VPInstruction::ActiveLaneMask,
231-
{WideCanonicalIV, Plan.getTripCount(), ALMMultiplier}, nullptr,
232-
"active.lane.mask");
225+
Mask = Builder.createNaryOp(VPInstruction::ActiveLaneMask,
226+
{WideCanonicalIV, Plan.getTripCount()}, nullptr,
227+
"active.lane.mask");
233228
} else {
234229
Mask = Builder.createICmp(CmpInst::ICMP_ULE, WideCanonicalIV,
235230
Plan.getOrCreateBackedgeTakenCount());

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -454,12 +454,6 @@ m_ExtractPenultimateElement(const Op0_t &Op0) {
454454
return m_VPInstruction<VPInstruction::ExtractPenultimateElement>(Op0);
455455
}
456456

457-
template <typename Op0_t, typename Op1_t, typename Op2_t>
458-
inline VPInstruction_match<VPInstruction::ActiveLaneMask, Op0_t, Op1_t, Op2_t>
459-
m_ActiveLaneMask(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
460-
return m_VPInstruction<VPInstruction::ActiveLaneMask>(Op0, Op1, Op2);
461-
}
462-
463457
template <typename Op0_t, typename Op1_t, typename Op2_t>
464458
inline VPInstruction_match<VPInstruction::WideActiveLaneMask, Op0_t, Op1_t,
465459
Op2_t>

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ unsigned VPInstruction::getNumOperandsForOpcode() const {
649649
case Instruction::FCmp:
650650
case Instruction::ExtractElement:
651651
case Instruction::Store:
652+
case VPInstruction::ActiveLaneMask:
652653
case VPInstruction::BranchOnCount:
653654
case VPInstruction::BranchOnTwoConds:
654655
case VPInstruction::FirstOrderRecurrenceSplice:
@@ -663,7 +664,6 @@ unsigned VPInstruction::getNumOperandsForOpcode() const {
663664
return 2;
664665
case Instruction::InsertElement:
665666
case Instruction::Select:
666-
case VPInstruction::ActiveLaneMask:
667667
case VPInstruction::WideActiveLaneMask:
668668
case VPInstruction::ReductionStartVector:
669669
return 3;
@@ -795,9 +795,13 @@ Value *VPInstruction::generate(VPTransformState &State) {
795795
// Get the original loop tripcount.
796796
Value *ScalarTC = State.get(getOperand(1), VPLane(0));
797797

798+
unsigned Multiplier =
799+
getOpcode() == VPInstruction::ActiveLaneMask
800+
? 1
801+
: cast<VPConstantInt>(getOperand(2))->getZExtValue();
802+
798803
// If this part of the active lane mask is scalar, generate the CMP directly
799804
// to avoid unnecessary extracts.
800-
unsigned Multiplier = cast<VPConstantInt>(getOperand(2))->getZExtValue();
801805
if (State.VF.isScalar() && Multiplier == 1)
802806
return Builder.CreateCmp(CmpInst::Predicate::ICMP_ULT, VIVElem0, ScalarTC,
803807
Name);
@@ -1116,23 +1120,8 @@ Value *VPInstruction::generate(VPTransformState &State) {
11161120
if (Src->getType() == DstTy)
11171121
return Src;
11181122

1119-
// If the VF is scalar & this is an extract of an active lane mask,
1120-
// generate an ICMP directly.
1121-
VPValue *Start, *TC;
1122-
if (State.VF.isScalar() &&
1123-
match(getOperand(0),
1124-
m_WideActiveLaneMask(m_VPValue(Start), m_VPValue(TC),
1125-
m_VPValue()))) {
1126-
Value *StartV = State.get(Start);
1127-
if (Part > 0)
1128-
StartV = Builder.CreateAdd(StartV, State.get(getOperand(1)));
1129-
return Builder.CreateCmp(CmpInst::Predicate::ICMP_ULT, StartV,
1130-
State.get(TC));
1131-
}
1132-
1133-
auto *Idx = ConstantInt::get(Builder.getInt64Ty(),
1134-
State.VF.getKnownMinValue() * Part);
1135-
return Builder.CreateExtractVector(DstTy, Src, Idx);
1123+
return Builder.CreateExtractVector(
1124+
DstTy, Src, Builder.getInt64(State.VF.getKnownMinValue() * Part), Name);
11361125
}
11371126
default:
11381127
llvm_unreachable("Unsupported opcode for instruction");
@@ -1444,7 +1433,10 @@ InstructionCost VPInstruction::computeCost(ElementCount VF,
14441433
case VPInstruction::ActiveLaneMask:
14451434
case VPInstruction::WideActiveLaneMask: {
14461435
Type *ArgTy = getOperand(0)->getScalarType();
1447-
unsigned Multiplier = cast<VPConstantInt>(getOperand(2))->getZExtValue();
1436+
unsigned Multiplier =
1437+
getOpcode() == VPInstruction::ActiveLaneMask
1438+
? 1
1439+
: cast<VPConstantInt>(getOperand(2))->getZExtValue();
14481440
Type *RetTy = toVectorTy(Type::getInt1Ty(Ctx.LLVMCtx), VF * Multiplier);
14491441
IntrinsicCostAttributes Attrs(Intrinsic::get_active_lane_mask, RetTy,
14501442
{ArgTy, ArgTy});

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,43 @@ static bool isConditionTrueViaVFAndUF(VPValue *Cond, VPlan &Plan,
20352035
return SE.isKnownPredicate(CmpInst::ICMP_EQ, VectorTripCount, C);
20362036
}
20372037

2038+
static bool replaceMaskWithCompare(VPlan &Plan, ElementCount BestVF) {
2039+
if (!BestVF.isScalar())
2040+
return false;
2041+
2042+
bool MadeChange = false;
2043+
VPBuilder Builder;
2044+
VPRegionBlock *VectorRegion = Plan.getVectorLoopRegion();
2045+
VPBasicBlock *PreheaderVPBB = Plan.getVectorPreheader();
2046+
VPBasicBlock *ExitingVPBB = VectorRegion->getExitingBasicBlock();
2047+
2048+
VPValue *Start, *TC;
2049+
uint64_t Idx;
2050+
for (VPBasicBlock *VPBB : {PreheaderVPBB, ExitingVPBB}) {
2051+
for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
2052+
if (!match(&R, m_ExtractVectorForPart(
2053+
m_WideActiveLaneMask(m_VPValue(Start), m_VPValue(TC),
2054+
m_VPValue()),
2055+
m_ConstantInt(Idx))))
2056+
continue;
2057+
2058+
auto *Extract = cast<VPInstruction>(&R);
2059+
Builder.setInsertPoint(Extract);
2060+
2061+
if (Idx > 0)
2062+
Start = Builder.createAdd(
2063+
Start, Plan.getConstantInt(Start->getScalarType(), Idx));
2064+
2065+
VPValue *ICmp = Builder.createICmp(CmpInst::ICMP_ULT, Start, TC);
2066+
Extract->replaceAllUsesWith(ICmp);
2067+
Extract->eraseFromParent();
2068+
MadeChange = true;
2069+
}
2070+
}
2071+
2072+
return MadeChange;
2073+
}
2074+
20382075
/// Try to simplify the branch condition of \p Plan. This may restrict the
20392076
/// resulting plan to \p BestVF and \p BestUF.
20402077
static bool simplifyBranchConditionForVFAndUF(VPlan &Plan, ElementCount BestVF,
@@ -2050,16 +2087,13 @@ static bool simplifyBranchConditionForVFAndUF(VPlan &Plan, ElementCount BestVF,
20502087
if (match(Term, m_BranchOnCount(
20512088
m_CombineOr(m_CanIVInc, m_c_Add(m_CanIVInc, m_LiveIn())),
20522089
m_VPValue())) ||
2053-
match(Term, m_BranchOnCond(m_Not(m_ActiveLaneMask(
2054-
m_VPValue(), m_VPValue(), m_VPValue())))) ||
20552090
match(Term,
20562091
m_BranchOnCond(m_Not(m_ExtractVectorForPart(
20572092
m_WideActiveLaneMask(m_VPValue(), m_VPValue(), m_VPValue()),
20582093
m_ZeroInt()))))) {
20592094
// Try to simplify the branch condition if VectorTC <= VF * UF when the
2060-
// latch terminator is BranchOnCount, BranchOnCond(Not(ActiveLaneMask)) or
2061-
// BranchOnCond(Not(ExtractVectorForPart(WideActiveLaneMask),
2062-
// 0))
2095+
// latch terminator is BranchOnCount or
2096+
// BranchOnCond(Not(ExtractVectorForPart(WideActiveLaneMask), 0))
20632097
const SCEV *VectorTripCount =
20642098
vputils::getSCEVExprForVPValue(&Plan.getVectorTripCount(), PSE);
20652099
if (isa<SCEVCouldNotCompute>(VectorTripCount))
@@ -2103,8 +2137,8 @@ void VPlanTransforms::optimizeForVFAndUF(VPlan &Plan, ElementCount BestVF,
21032137
assert(Plan.hasVF(BestVF) && "BestVF is not available in Plan");
21042138
assert(Plan.hasUF(BestUF) && "BestUF is not available in Plan");
21052139

2106-
bool MadeChange =
2107-
simplifyBranchConditionForVFAndUF(Plan, BestVF, BestUF, PSE);
2140+
bool MadeChange = replaceMaskWithCompare(Plan, BestVF);
2141+
MadeChange |= simplifyBranchConditionForVFAndUF(Plan, BestVF, BestUF, PSE);
21082142
MadeChange |= optimizeVectorInductionWidthForTCAndVFUF(Plan, BestVF, BestUF);
21092143

21102144
if (MadeChange) {
@@ -3102,13 +3136,12 @@ static bool handleUncountableExitsWithSideEffects(
31023136
VPBuilder MaskBuilder(HeaderVPBB, InsertIt);
31033137
VPValue *FirstActive = MaskBuilder.createFirstActiveLane(*Cond);
31043138
Type *IVScalarTy = IV->getScalarType();
3105-
VPValue *ALMMultiplier = Plan.getConstantInt(IVScalarTy, 1);
31063139
VPValue *Zero = Plan.getZero(IVScalarTy);
31073140
FirstActive =
31083141
MaskBuilder.createScalarZExtOrTrunc(FirstActive, IVScalarTy, DebugLoc());
31093142
VPValue *Mask = MaskBuilder.createNaryOp(VPInstruction::ActiveLaneMask,
3110-
{Zero, FirstActive, ALMMultiplier},
3111-
DebugLoc(), "uncountable.exit.mask");
3143+
{Zero, FirstActive}, DebugLoc(),
3144+
"uncountable.exit.mask");
31123145

31133146
// Convert all other memory operations to use the mask.
31143147
for (VPBasicBlock *VPBB : vp_rpo_plain_cfg_loop_body(HeaderVPBB))

llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ void UnrollState::unrollBlock(VPBlockBase *VPB) {
481481
m_WideActiveLaneMask(m_VPValue(), m_VPValue(), m_VPValue()))) {
482482
auto *ALM = cast<VPInstruction>(&R);
483483
addUniformForAllParts(ALM);
484-
ALM->setOperand(2, Plan.getConstantInt(64, UF));
484+
ALM->setOperand(2, getConstantInt(UF));
485485
continue;
486486
}
487487

llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,6 @@ bool VPlanVerifier::verifyLastActiveLaneRecipe(
200200
match(Mask, m_VPInstruction<VPInstruction::WideActiveLaneMask>()))
201201
continue;
202202

203-
if (match(Mask, m_ActiveLaneMask(m_VPValue(), m_VPValue(), m_VPValue())) ||
204-
match(Mask,
205-
m_WideActiveLaneMask(m_VPValue(), m_VPValue(), m_VPValue())))
206-
continue;
207-
208203
CmpPredicate Pred;
209204
VPValue *LHS, *RHS;
210205
if (match(Mask, m_ICmp(Pred, m_VPValue(LHS), m_VPValue(RHS))) &&

0 commit comments

Comments
 (0)