[NFC][VPlan] Rename VPEVLBasedIVPHIRecipe to VPCurrentIterationPHIRecipe (#177114)
This is groundwork for #151300, which aims to support first-faulting loads in non-tail-folded early-exit loops. Per #175900, we need a variable-length stepping transform that can shared between EVL and non-EVL loops. The idea is to have an EVL-independent counter and transform for tracking the cumulative number of processed elements. This patch renames the existing counter (VPEVLBasedIVPHIRecipe) and transform (canonicalizeEVLLoops) to be EVL-independent: - Rename VPEVLBasedIVPHIRecipe to VPCurrentIterationRecipe to reflect its general purpose of tracking processed element count. - Rename canonicalizeEVLLoops to convertToVariableLengthStep. This is NFC.
This commit is contained in:
@@ -4139,10 +4139,10 @@ static bool willGenerateVectors(VPlan &Plan, ElementCount VF,
|
||||
case VPRecipeBase::VPReplicateSC:
|
||||
case VPRecipeBase::VPInstructionSC:
|
||||
case VPRecipeBase::VPCanonicalIVPHISC:
|
||||
case VPRecipeBase::VPCurrentIterationPHISC:
|
||||
case VPRecipeBase::VPVectorPointerSC:
|
||||
case VPRecipeBase::VPVectorEndPointerSC:
|
||||
case VPRecipeBase::VPExpandSCEVSC:
|
||||
case VPRecipeBase::VPEVLBasedIVPHISC:
|
||||
case VPRecipeBase::VPPredInstPHISC:
|
||||
case VPRecipeBase::VPBranchOnMaskSC:
|
||||
continue;
|
||||
@@ -4672,8 +4672,8 @@ LoopVectorizationPlanner::selectInterleaveCount(VPlan &Plan, ElementCount VF,
|
||||
return 1;
|
||||
|
||||
if (any_of(Plan.getVectorLoopRegion()->getEntryBasicBlock()->phis(),
|
||||
IsaPred<VPEVLBasedIVPHIRecipe>)) {
|
||||
LLVM_DEBUG(dbgs() << "LV: Preference for VP intrinsics indicated. "
|
||||
IsaPred<VPCurrentIterationPHIRecipe>)) {
|
||||
LLVM_DEBUG(dbgs() << "LV: Loop requires variable-length step. "
|
||||
"Unroll factor forced to be 1.\n");
|
||||
return 1;
|
||||
}
|
||||
@@ -7461,8 +7461,8 @@ DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan(
|
||||
// Expand BranchOnTwoConds after dissolution, when latch has direct access to
|
||||
// its successors.
|
||||
VPlanTransforms::expandBranchOnTwoConds(BestVPlan);
|
||||
// Canonicalize EVL loops after regions are dissolved.
|
||||
VPlanTransforms::canonicalizeEVLLoops(BestVPlan);
|
||||
// Convert loops with variable-length stepping after regions are dissolved.
|
||||
VPlanTransforms::convertToVariableLengthStep(BestVPlan);
|
||||
VPlanTransforms::materializeBackedgeTakenCount(BestVPlan, VectorPH);
|
||||
VPlanTransforms::materializeVectorTripCount(
|
||||
BestVPlan, VectorPH, CM.foldTailByMasking(),
|
||||
|
||||
@@ -435,8 +435,8 @@ public:
|
||||
// START: SubclassID for recipes that inherit VPHeaderPHIRecipe.
|
||||
// VPHeaderPHIRecipe need to be kept together.
|
||||
VPCanonicalIVPHISC,
|
||||
VPCurrentIterationPHISC,
|
||||
VPActiveLaneMaskPHISC,
|
||||
VPEVLBasedIVPHISC,
|
||||
VPFirstOrderRecurrencePHISC,
|
||||
VPWidenIntOrFpInductionSC,
|
||||
VPWidenPointerInductionSC,
|
||||
@@ -598,7 +598,6 @@ public:
|
||||
static inline bool classof(const VPRecipeBase *R) {
|
||||
switch (R->getVPRecipeID()) {
|
||||
case VPRecipeBase::VPDerivedIVSC:
|
||||
case VPRecipeBase::VPEVLBasedIVPHISC:
|
||||
case VPRecipeBase::VPExpandSCEVSC:
|
||||
case VPRecipeBase::VPExpressionSC:
|
||||
case VPRecipeBase::VPInstructionSC:
|
||||
@@ -617,6 +616,7 @@ public:
|
||||
case VPRecipeBase::VPBlendSC:
|
||||
case VPRecipeBase::VPPredInstPHISC:
|
||||
case VPRecipeBase::VPCanonicalIVPHISC:
|
||||
case VPRecipeBase::VPCurrentIterationPHISC:
|
||||
case VPRecipeBase::VPActiveLaneMaskPHISC:
|
||||
case VPRecipeBase::VPFirstOrderRecurrencePHISC:
|
||||
case VPRecipeBase::VPWidenPHISC:
|
||||
@@ -3829,30 +3829,30 @@ protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
/// A recipe for generating the phi node for the current index of elements,
|
||||
/// adjusted in accordance with EVL value. It starts at the start value of the
|
||||
/// canonical induction and gets incremented by EVL in each iteration of the
|
||||
/// vector loop.
|
||||
class VPEVLBasedIVPHIRecipe : public VPHeaderPHIRecipe {
|
||||
/// A recipe for generating the phi node tracking the current scalar iteration
|
||||
/// index. It starts at the start value of the canonical induction and gets
|
||||
/// incremented by the number of scalar iterations processed by the vector loop
|
||||
/// iteration. The increment does not have to be loop invariant.
|
||||
class VPCurrentIterationPHIRecipe : public VPHeaderPHIRecipe {
|
||||
public:
|
||||
VPEVLBasedIVPHIRecipe(VPValue *StartIV, DebugLoc DL)
|
||||
: VPHeaderPHIRecipe(VPRecipeBase::VPEVLBasedIVPHISC, nullptr, StartIV,
|
||||
DL) {}
|
||||
VPCurrentIterationPHIRecipe(VPValue *StartIV, DebugLoc DL)
|
||||
: VPHeaderPHIRecipe(VPRecipeBase::VPCurrentIterationPHISC, nullptr,
|
||||
StartIV, DL) {}
|
||||
|
||||
~VPEVLBasedIVPHIRecipe() override = default;
|
||||
~VPCurrentIterationPHIRecipe() override = default;
|
||||
|
||||
VPEVLBasedIVPHIRecipe *clone() override {
|
||||
VPCurrentIterationPHIRecipe *clone() override {
|
||||
llvm_unreachable("cloning not implemented yet");
|
||||
}
|
||||
|
||||
VP_CLASSOF_IMPL(VPRecipeBase::VPEVLBasedIVPHISC)
|
||||
VP_CLASSOF_IMPL(VPRecipeBase::VPCurrentIterationPHISC)
|
||||
|
||||
void execute(VPTransformState &State) override {
|
||||
llvm_unreachable("cannot execute this recipe, should be replaced by a "
|
||||
"scalar phi recipe");
|
||||
}
|
||||
|
||||
/// Return the cost of this VPEVLBasedIVPHIRecipe.
|
||||
/// Return the cost of this VPCurrentIterationPHIRecipe.
|
||||
InstructionCost computeCost(ElementCount VF,
|
||||
VPCostContext &Ctx) const override {
|
||||
// For now, match the behavior of the legacy cost model.
|
||||
|
||||
@@ -286,7 +286,7 @@ Type *VPTypeAnalysis::inferScalarType(const VPValue *V) {
|
||||
TypeSwitch<const VPRecipeBase *, Type *>(V->getDefiningRecipe())
|
||||
.Case<VPActiveLaneMaskPHIRecipe, VPCanonicalIVPHIRecipe,
|
||||
VPFirstOrderRecurrencePHIRecipe, VPReductionPHIRecipe,
|
||||
VPWidenPointerInductionRecipe, VPEVLBasedIVPHIRecipe>(
|
||||
VPWidenPointerInductionRecipe, VPCurrentIterationPHIRecipe>(
|
||||
[this](const auto *R) {
|
||||
// Handle header phi recipes, except VPWidenIntOrFpInduction
|
||||
// which needs special handling due it being possibly truncated.
|
||||
@@ -559,7 +559,7 @@ SmallVector<VPRegisterUsage, 8> llvm::calculateRegisterUsageForPlan(
|
||||
|
||||
if (VFs[J].isScalar() ||
|
||||
isa<VPCanonicalIVPHIRecipe, VPReplicateRecipe, VPDerivedIVRecipe,
|
||||
VPEVLBasedIVPHIRecipe, VPScalarIVStepsRecipe>(VPV) ||
|
||||
VPCurrentIterationPHIRecipe, VPScalarIVStepsRecipe>(VPV) ||
|
||||
(isa<VPInstruction>(VPV) && vputils::onlyScalarValuesUsed(VPV)) ||
|
||||
(isa<VPReductionPHIRecipe>(VPV) &&
|
||||
(cast<VPReductionPHIRecipe>(VPV))->isInLoop())) {
|
||||
|
||||
@@ -75,6 +75,7 @@ bool VPRecipeBase::mayWriteToMemory() const {
|
||||
return cast<VPWidenIntrinsicRecipe>(this)->mayWriteToMemory();
|
||||
case VPActiveLaneMaskPHISC:
|
||||
case VPCanonicalIVPHISC:
|
||||
case VPCurrentIterationPHISC:
|
||||
case VPBranchOnMaskSC:
|
||||
case VPDerivedIVSC:
|
||||
case VPFirstOrderRecurrencePHISC:
|
||||
@@ -4673,9 +4674,9 @@ void VPActiveLaneMaskPHIRecipe::printRecipe(raw_ostream &O, const Twine &Indent,
|
||||
#endif
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
void VPEVLBasedIVPHIRecipe::printRecipe(raw_ostream &O, const Twine &Indent,
|
||||
VPSlotTracker &SlotTracker) const {
|
||||
O << Indent << "EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI ";
|
||||
void VPCurrentIterationPHIRecipe::printRecipe(
|
||||
raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const {
|
||||
O << Indent << "CURRENT-ITERATION-PHI ";
|
||||
|
||||
printAsOperand(O, SlotTracker);
|
||||
O << " = phi ";
|
||||
|
||||
@@ -2107,7 +2107,7 @@ static bool simplifyBranchConditionForVFAndUF(VPlan &Plan, ElementCount BestVF,
|
||||
if (all_of(Header->phis(), [](VPRecipeBase &Phi) {
|
||||
if (auto *R = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi))
|
||||
return R->isCanonical();
|
||||
return isa<VPCanonicalIVPHIRecipe, VPEVLBasedIVPHIRecipe,
|
||||
return isa<VPCanonicalIVPHIRecipe, VPCurrentIterationPHIRecipe,
|
||||
VPFirstOrderRecurrencePHIRecipe, VPPhi>(&Phi);
|
||||
})) {
|
||||
for (VPRecipeBase &HeaderR : make_early_inc_range(Header->phis())) {
|
||||
@@ -3211,9 +3211,9 @@ static void fixupVFUsersForEVL(VPlan &Plan, VPValue &EVL) {
|
||||
/// VPInstruction::ExplicitVectorLength elements instead of VF elements each
|
||||
/// iteration.
|
||||
///
|
||||
/// - Add a VPEVLBasedIVPHIRecipe and related recipes to \p Plan and
|
||||
/// - Add a VPCurrentIterationPHIRecipe and related recipes to \p Plan and
|
||||
/// replaces all uses except the canonical IV increment of
|
||||
/// VPCanonicalIVPHIRecipe with a VPEVLBasedIVPHIRecipe.
|
||||
/// VPCanonicalIVPHIRecipe with a VPCurrentIterationPHIRecipe.
|
||||
/// VPCanonicalIVPHIRecipe is used only for loop iterations counting after
|
||||
/// this transformation.
|
||||
///
|
||||
@@ -3233,13 +3233,13 @@ static void fixupVFUsersForEVL(VPlan &Plan, VPValue &EVL) {
|
||||
///
|
||||
/// vector.body:
|
||||
/// ...
|
||||
/// %EVLPhi = EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI [ %StartV, %vector.ph ],
|
||||
/// [ %NextEVLIV, %vector.body ]
|
||||
/// %CurrentIter = CURRENT-ITERATION-PHI [ %StartV, %vector.ph ],
|
||||
/// [ %NextIter, %vector.body ]
|
||||
/// %AVL = phi [ trip-count, %vector.ph ], [ %NextAVL, %vector.body ]
|
||||
/// %VPEVL = EXPLICIT-VECTOR-LENGTH %AVL
|
||||
/// ...
|
||||
/// %OpEVL = cast i32 %VPEVL to IVSize
|
||||
/// %NextEVLIV = add IVSize %OpEVL, %EVLPhi
|
||||
/// %NextIter = add IVSize %OpEVL, %CurrentIter
|
||||
/// %NextAVL = sub IVSize nuw %AVL, %OpEVL
|
||||
/// ...
|
||||
///
|
||||
@@ -3249,15 +3249,15 @@ static void fixupVFUsersForEVL(VPlan &Plan, VPValue &EVL) {
|
||||
///
|
||||
/// vector.body:
|
||||
/// ...
|
||||
/// %EVLPhi = EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI [ %StartV, %vector.ph ],
|
||||
/// [ %NextEVLIV, %vector.body ]
|
||||
/// %CurrentIter = CURRENT-ITERATION-PHI [ %StartV, %vector.ph ],
|
||||
/// [ %NextIter, %vector.body ]
|
||||
/// %AVL = phi [ trip-count, %vector.ph ], [ %NextAVL, %vector.body ]
|
||||
/// %cmp = cmp ult %AVL, MaxSafeElements
|
||||
/// %SAFE_AVL = select %cmp, %AVL, MaxSafeElements
|
||||
/// %VPEVL = EXPLICIT-VECTOR-LENGTH %SAFE_AVL
|
||||
/// ...
|
||||
/// %OpEVL = cast i32 %VPEVL to IVSize
|
||||
/// %NextEVLIV = add IVSize %OpEVL, %EVLPhi
|
||||
/// %NextIter = add IVSize %OpEVL, %CurrentIter
|
||||
/// %NextAVL = sub IVSize nuw %AVL, %OpEVL
|
||||
/// ...
|
||||
///
|
||||
@@ -3272,9 +3272,10 @@ void VPlanTransforms::addExplicitVectorLength(
|
||||
auto *CanIVTy = LoopRegion->getCanonicalIVType();
|
||||
VPValue *StartV = CanonicalIVPHI->getStartValue();
|
||||
|
||||
// Create the ExplicitVectorLengthPhi recipe in the main loop.
|
||||
auto *EVLPhi = new VPEVLBasedIVPHIRecipe(StartV, DebugLoc::getUnknown());
|
||||
EVLPhi->insertAfter(CanonicalIVPHI);
|
||||
// Create the CurrentIteration recipe in the vector loop.
|
||||
auto *CurrentIteration =
|
||||
new VPCurrentIterationPHIRecipe(StartV, DebugLoc::getUnknown());
|
||||
CurrentIteration->insertAfter(CanonicalIVPHI);
|
||||
VPBuilder Builder(Header, Header->getFirstNonPhi());
|
||||
// Create the AVL (application vector length), starting from TC -> 0 in steps
|
||||
// of EVL.
|
||||
@@ -3301,11 +3302,12 @@ void VPlanTransforms::addExplicitVectorLength(
|
||||
OpVPEVL = Builder.createScalarZExtOrTrunc(
|
||||
OpVPEVL, CanIVTy, I32Ty, CanonicalIVIncrement->getDebugLoc());
|
||||
|
||||
auto *NextEVLIV = Builder.createAdd(
|
||||
OpVPEVL, EVLPhi, CanonicalIVIncrement->getDebugLoc(), "index.evl.next",
|
||||
{CanonicalIVIncrement->hasNoUnsignedWrap(),
|
||||
CanonicalIVIncrement->hasNoSignedWrap()});
|
||||
EVLPhi->addOperand(NextEVLIV);
|
||||
auto *NextIter = Builder.createAdd(OpVPEVL, CurrentIteration,
|
||||
CanonicalIVIncrement->getDebugLoc(),
|
||||
"current.iteration.next",
|
||||
{CanonicalIVIncrement->hasNoUnsignedWrap(),
|
||||
CanonicalIVIncrement->hasNoSignedWrap()});
|
||||
CurrentIteration->addOperand(NextIter);
|
||||
|
||||
VPValue *NextAVL =
|
||||
Builder.createSub(AVLPhi, OpVPEVL, DebugLoc::getCompilerGenerated(),
|
||||
@@ -3316,47 +3318,50 @@ void VPlanTransforms::addExplicitVectorLength(
|
||||
removeDeadRecipes(Plan);
|
||||
|
||||
// Replace all uses of VPCanonicalIVPHIRecipe by
|
||||
// VPEVLBasedIVPHIRecipe except for the canonical IV increment.
|
||||
CanonicalIVPHI->replaceAllUsesWith(EVLPhi);
|
||||
// VPCurrentIterationPHIRecipe except for the canonical IV increment.
|
||||
CanonicalIVPHI->replaceAllUsesWith(CurrentIteration);
|
||||
CanonicalIVIncrement->setOperand(0, CanonicalIVPHI);
|
||||
// TODO: support unroll factor > 1.
|
||||
Plan.setUF(1);
|
||||
}
|
||||
|
||||
void VPlanTransforms::canonicalizeEVLLoops(VPlan &Plan) {
|
||||
// Find EVL loop entries by locating VPEVLBasedIVPHIRecipe.
|
||||
// There should be only one EVL PHI in the entire plan.
|
||||
VPEVLBasedIVPHIRecipe *EVLPhi = nullptr;
|
||||
void VPlanTransforms::convertToVariableLengthStep(VPlan &Plan) {
|
||||
// Find the vector loop entry by locating VPCurrentIterationPHIRecipe.
|
||||
// There should be only one VPCurrentIteration in the entire plan.
|
||||
VPCurrentIterationPHIRecipe *CurrentIteration = nullptr;
|
||||
|
||||
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
|
||||
vp_depth_first_shallow(Plan.getEntry())))
|
||||
for (VPRecipeBase &R : VPBB->phis())
|
||||
if (auto *PhiR = dyn_cast<VPEVLBasedIVPHIRecipe>(&R)) {
|
||||
assert(!EVLPhi && "Found multiple EVL PHIs. Only one expected");
|
||||
EVLPhi = PhiR;
|
||||
if (auto *PhiR = dyn_cast<VPCurrentIterationPHIRecipe>(&R)) {
|
||||
assert(!CurrentIteration &&
|
||||
"Found multiple CurrentIteration. Only one expected");
|
||||
CurrentIteration = PhiR;
|
||||
}
|
||||
|
||||
// Early return if no EVL PHI is found.
|
||||
if (!EVLPhi)
|
||||
// Early return if it is not variable-length stepping.
|
||||
if (!CurrentIteration)
|
||||
return;
|
||||
|
||||
VPBasicBlock *HeaderVPBB = EVLPhi->getParent();
|
||||
VPValue *EVLIncrement = EVLPhi->getBackedgeValue();
|
||||
VPBasicBlock *HeaderVPBB = CurrentIteration->getParent();
|
||||
VPValue *CurrentIterationIncr = CurrentIteration->getBackedgeValue();
|
||||
|
||||
// Convert EVLPhi to concrete recipe.
|
||||
// Convert CurrentIteration to concrete recipe.
|
||||
auto *ScalarR =
|
||||
VPBuilder(EVLPhi).createScalarPhi({EVLPhi->getStartValue(), EVLIncrement},
|
||||
EVLPhi->getDebugLoc(), "evl.based.iv");
|
||||
EVLPhi->replaceAllUsesWith(ScalarR);
|
||||
EVLPhi->eraseFromParent();
|
||||
VPBuilder(CurrentIteration)
|
||||
.createScalarPhi(
|
||||
{CurrentIteration->getStartValue(), CurrentIterationIncr},
|
||||
CurrentIteration->getDebugLoc(), "current.iteration.iv");
|
||||
CurrentIteration->replaceAllUsesWith(ScalarR);
|
||||
CurrentIteration->eraseFromParent();
|
||||
|
||||
// Replace CanonicalIVInc with EVL-PHI increment.
|
||||
// Replace CanonicalIVInc with CurrentIteration increment.
|
||||
auto *CanonicalIV = cast<VPPhi>(&*HeaderVPBB->begin());
|
||||
VPValue *Backedge = CanonicalIV->getIncomingValue(1);
|
||||
assert(match(Backedge, m_c_Add(m_Specific(CanonicalIV),
|
||||
m_Specific(&Plan.getVFxUF()))) &&
|
||||
"Unexpected canonical iv");
|
||||
Backedge->replaceAllUsesWith(EVLIncrement);
|
||||
Backedge->replaceAllUsesWith(CurrentIterationIncr);
|
||||
|
||||
// Remove unused phi and increment.
|
||||
VPRecipeBase *CanonicalIVIncrement = Backedge->getDefiningRecipe();
|
||||
@@ -3374,8 +3379,8 @@ void VPlanTransforms::convertEVLExitCond(VPlan &Plan) {
|
||||
if (std::next(CanIV->getIterator()) == CanIV->getParent()->end())
|
||||
return;
|
||||
// The EVL IV is always immediately after the canonical IV.
|
||||
auto *EVLPhi =
|
||||
dyn_cast_or_null<VPEVLBasedIVPHIRecipe>(std::next(CanIV->getIterator()));
|
||||
auto *EVLPhi = dyn_cast_or_null<VPCurrentIterationPHIRecipe>(
|
||||
std::next(CanIV->getIterator()));
|
||||
if (!EVLPhi)
|
||||
return;
|
||||
|
||||
|
||||
@@ -285,9 +285,9 @@ struct VPlanTransforms {
|
||||
VPlan &Plan,
|
||||
const std::function<bool(BasicBlock *)> &BlockNeedsPredication);
|
||||
|
||||
/// Add a VPEVLBasedIVPHIRecipe and related recipes to \p Plan and
|
||||
/// Add a VPCurrentIterationPHIRecipe and related recipes to \p Plan and
|
||||
/// replaces all uses except the canonical IV increment of
|
||||
/// VPCanonicalIVPHIRecipe with a VPEVLBasedIVPHIRecipe.
|
||||
/// VPCanonicalIVPHIRecipe with a VPCurrentIterationPHIRecipe.
|
||||
/// VPCanonicalIVPHIRecipe is only used to control the loop after
|
||||
/// this transformation.
|
||||
static void
|
||||
@@ -336,14 +336,14 @@ struct VPlanTransforms {
|
||||
/// BranchOnCond instructions. Should be called after dissolveLoopRegions.
|
||||
static void expandBranchOnTwoConds(VPlan &Plan);
|
||||
|
||||
/// Transform EVL loops to use variable-length stepping after region
|
||||
/// Transform loops with variable-length stepping after region
|
||||
/// dissolution.
|
||||
///
|
||||
/// Once loop regions are replaced with explicit CFG, EVL loops can step with
|
||||
/// Once loop regions are replaced with explicit CFG, loops can step with
|
||||
/// variable vector lengths instead of fixed lengths. This transformation:
|
||||
/// * Makes EVL-Phi concrete.
|
||||
/// * Makes CurrentIteration-Phi concrete.
|
||||
// * Removes CanonicalIV and increment.
|
||||
static void canonicalizeEVLLoops(VPlan &Plan);
|
||||
static void convertToVariableLengthStep(VPlan &Plan);
|
||||
|
||||
/// Lower abstract recipes to concrete ones, that can be codegen'd.
|
||||
static void convertToConcreteRecipes(VPlan &Plan);
|
||||
|
||||
@@ -103,9 +103,9 @@ bool VPlanVerifier::verifyPhiRecipes(const VPBasicBlock *VPBB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isa<VPEVLBasedIVPHIRecipe>(RecipeI) &&
|
||||
if (isa<VPCurrentIterationPHIRecipe>(RecipeI) &&
|
||||
!isa_and_nonnull<VPCanonicalIVPHIRecipe>(std::prev(RecipeI))) {
|
||||
errs() << "EVL based IV is not immediately after canonical IV\n";
|
||||
errs() << "CurrentIteration PHI is not immediately after canonical IV\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -233,9 +233,10 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
|
||||
errs() << "EVL used by unexpected VPInstruction\n";
|
||||
return false;
|
||||
}
|
||||
if (!VerifyLate && !isa<VPEVLBasedIVPHIRecipe>(*I->users().begin())) {
|
||||
if (!VerifyLate &&
|
||||
!isa<VPCurrentIterationPHIRecipe>(*I->users().begin())) {
|
||||
errs() << "Result of VPInstruction::Add with EVL operand is "
|
||||
"not used by VPEVLBasedIVPHIRecipe\n";
|
||||
"not used by VPCurrentIterationPHIRecipe\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -24,7 +24,7 @@ define void @vector_reverse_i64(ptr nocapture noundef writeonly %A, ptr nocaptur
|
||||
; CHECK-NEXT: <x1> vector loop: {
|
||||
; CHECK-NEXT: vector.body:
|
||||
; CHECK-NEXT: EMIT vp<[[INDUCTION:%.+]]> = CANONICAL-INDUCTION ir<0>, vp<[[INDEX_NEXT:%.+]]>
|
||||
; CHECK-NEXT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI vp<[[EVL_PHI:%.+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; CHECK-NEXT: CURRENT-ITERATION-PHI vp<[[EVL_PHI:%.+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; CHECK-NEXT: EMIT-SCALAR vp<[[AVL:%.+]]> = phi [ vp<[[OTC]]>, vector.ph ], [ vp<[[AVL_NEXT:%.+]]>, vector.body ]
|
||||
; CHECK-NEXT: EMIT-SCALAR vp<[[EVL:%.+]]> = EXPLICIT-VECTOR-LENGTH vp<[[AVL]]>
|
||||
; CHECK-NEXT: vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<%n> + vp<[[EVL_PHI]]> * ir<-1>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
define void @first_order_recurrence(ptr noalias %A, ptr noalias %B, i64 %TC) {
|
||||
; IF-EVL: VPlan 'Initial VPlan for VF={1},UF>=1'
|
||||
; IF-EVL-NOT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI
|
||||
; IF-EVL-NOT: CURRENT-ITERATION-PHI
|
||||
;
|
||||
; IF-EVL: VPlan 'Initial VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF={1}' {
|
||||
; IF-EVL-NEXT: Live-in vp<[[VF:%[0-9]+]]> = VF
|
||||
@@ -22,7 +22,7 @@ define void @first_order_recurrence(ptr noalias %A, ptr noalias %B, i64 %TC) {
|
||||
; IF-EVL: <x1> vector loop: {
|
||||
; IF-EVL-NEXT: vector.body:
|
||||
; IF-EVL-NEXT: EMIT vp<[[IV:%[0-9]+]]> = CANONICAL-INDUCTION
|
||||
; IF-EVL-NEXT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; IF-EVL-NEXT: CURRENT-ITERATION-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; IF-EVL-NEXT: FIRST-ORDER-RECURRENCE-PHI ir<[[FOR_PHI:%.+]]> = phi ir<33>, ir<[[LD:%.+]]>
|
||||
; IF-EVL-NEXT: EMIT-SCALAR vp<[[AVL:%.+]]> = phi [ ir<%TC>, vector.ph ], [ vp<[[AVL_NEXT:%.+]]>, vector.body ]
|
||||
; IF-EVL-NEXT: EMIT-SCALAR vp<[[PREV_EVL:%.+]]> = phi [ vp<[[VF32]]>, vector.ph ], [ vp<[[EVL:%.+]]>, vector.body ]
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
define i32 @reduction(ptr %a, i64 %n, i32 %start) {
|
||||
; IF-EVL: VPlan 'Initial VPlan for VF={1},UF>=1'
|
||||
; IF-EVL-NOT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI
|
||||
; IF-EVL-NOT: CURRENT-ITERATION-PHI
|
||||
|
||||
; IF-EVL-OUTLOOP: VPlan 'Initial VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF={1}' {
|
||||
; IF-EVL-OUTLOOP-NEXT: Live-in vp<[[VFUF:%[0-9]+]]> = VF * UF
|
||||
@@ -36,7 +36,7 @@ define i32 @reduction(ptr %a, i64 %n, i32 %start) {
|
||||
; IF-EVL-OUTLOOP-NEXT: <x1> vector loop: {
|
||||
; IF-EVL-OUTLOOP-NEXT: vector.body:
|
||||
; IF-EVL-OUTLOOP-NEXT: EMIT vp<[[IV:%[0-9]+]]> = CANONICAL-INDUCTION
|
||||
; IF-EVL-OUTLOOP-NEXT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; IF-EVL-OUTLOOP-NEXT: CURRENT-ITERATION-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; IF-EVL-OUTLOOP-NEXT: WIDEN-REDUCTION-PHI ir<[[RDX_PHI:%.+]]> = phi vp<[[RDX_START]]>, vp<[[RDX_SELECT:%.+]]>
|
||||
; IF-EVL-OUTLOOP-NEXT: EMIT-SCALAR vp<[[AVL:%.+]]> = phi [ ir<%n>, vector.ph ], [ vp<[[AVL_NEXT:%.+]]>, vector.body ]
|
||||
; IF-EVL-OUTLOOP-NEXT: EMIT-SCALAR vp<[[EVL:%.+]]> = EXPLICIT-VECTOR-LENGTH vp<[[AVL]]>
|
||||
@@ -76,7 +76,7 @@ define i32 @reduction(ptr %a, i64 %n, i32 %start) {
|
||||
; IF-EVL-INLOOP-NEXT: <x1> vector loop: {
|
||||
; IF-EVL-INLOOP-NEXT: vector.body:
|
||||
; IF-EVL-INLOOP-NEXT: EMIT vp<[[IV:%[0-9]+]]> = CANONICAL-INDUCTION
|
||||
; IF-EVL-INLOOP-NEXT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; IF-EVL-INLOOP-NEXT: CURRENT-ITERATION-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; IF-EVL-INLOOP-NEXT: WIDEN-REDUCTION-PHI ir<[[RDX_PHI:%.+]]> = phi vp<[[RDX_START]]>, ir<[[RDX_NEXT:%.+]]>
|
||||
; IF-EVL-INLOOP-NEXT: EMIT-SCALAR vp<[[AVL:%.+]]> = phi [ ir<%n>, vector.ph ], [ vp<[[AVL_NEXT:%.+]]>, vector.body ]
|
||||
; IF-EVL-INLOOP-NEXT: EMIT-SCALAR vp<[[EVL:%.+]]> = EXPLICIT-VECTOR-LENGTH vp<[[AVL]]>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
define void @foo(ptr noalias %a, ptr noalias %b, ptr noalias %c, i64 %N) {
|
||||
; IF-EVL: VPlan 'Initial VPlan for VF={1},UF>=1'
|
||||
; IF-EVL-NOT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI
|
||||
; IF-EVL-NOT: CURRENT-ITERATION-PHI
|
||||
;
|
||||
; IF-EVL: VPlan 'Initial VPlan for VF={vscale x 1,vscale x 2,vscale x 4},UF={1}' {
|
||||
; IF-EVL-NEXT: Live-in vp<[[VFUF:%[0-9]+]]> = VF * UF
|
||||
@@ -21,7 +21,7 @@ define void @foo(ptr noalias %a, ptr noalias %b, ptr noalias %c, i64 %N) {
|
||||
; IF-EVL-NEXT: <x1> vector loop: {
|
||||
; IF-EVL-NEXT: vector.body:
|
||||
; IF-EVL-NEXT: EMIT vp<[[IV:%[0-9]+]]> = CANONICAL-INDUCTION
|
||||
; IF-EVL-NEXT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; IF-EVL-NEXT: CURRENT-ITERATION-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
|
||||
; IF-EVL-NEXT: EMIT-SCALAR vp<[[AVL:%.+]]> = phi [ ir<%N>, vector.ph ], [ vp<[[AVL_NEXT:%.+]]>, vector.body ]
|
||||
; IF-EVL-NEXT: EMIT-SCALAR vp<%evl> = EXPLICIT-VECTOR-LENGTH vp<[[AVL]]>
|
||||
; IF-EVL-NEXT: vp<[[ST:%[0-9]+]]> = SCALAR-STEPS vp<[[EVL_PHI]]>, ir<1>, vp<%evl>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
; The target does not support predicated vectorization.
|
||||
define void @foo(ptr noalias %a, ptr noalias %b, ptr noalias %c, i64 %N) {
|
||||
; NO-VP-NOT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI
|
||||
; NO-VP-NOT: CURRENT-ITERATION-PHI
|
||||
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
@@ -1739,7 +1739,7 @@ TEST(VPDoubleValueDefTest, traverseUseLists) {
|
||||
TEST_F(VPRecipeTest, CastToVPSingleDefRecipe) {
|
||||
IntegerType *Int32 = IntegerType::get(C, 32);
|
||||
VPValue *Start = getPlan().getOrAddLiveIn(ConstantInt::get(Int32, 0));
|
||||
VPEVLBasedIVPHIRecipe R(Start, {});
|
||||
VPCurrentIterationPHIRecipe R(Start, {});
|
||||
VPRecipeBase *B = &R;
|
||||
EXPECT_TRUE(isa<VPSingleDefRecipe>(B));
|
||||
// TODO: check other VPSingleDefRecipes.
|
||||
|
||||
Reference in New Issue
Block a user