Skip to content

Commit bf15f1e

Browse files
committed
Revert "[VPlan] Add VPDerivedIVRecipe, use for VPScalarIVStepsRecipe."
This reverts commit 0fa666e. This triggers an assertion during AArch64 stage2 builds. Revert while I investigate. See https://lab.llvm.org/buildbot/#/builders/179/builds/4967/steps/11/logs/stdio
1 parent 07008a8 commit bf15f1e

17 files changed

+121
-227
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,19 +2333,22 @@ static Value *getStepVector(Value *Val, Value *StartIdx, Value *Step,
23332333
/// variable on which to base the steps, \p Step is the size of the step.
23342334
static void buildScalarSteps(Value *ScalarIV, Value *Step,
23352335
const InductionDescriptor &ID, VPValue *Def,
2336-
VPTransformState &State) {
2336+
Type *TruncToTy, VPTransformState &State) {
23372337
IRBuilderBase &Builder = State.Builder;
2338-
2339-
// Ensure step has the same type as that of scalar IV.
23402338
Type *ScalarIVTy = ScalarIV->getType()->getScalarType();
2341-
if (ScalarIVTy != Step->getType()) {
2342-
// TODO: Also use VPDerivedIVRecipe when only the step needs truncating, to
2343-
// avoid separate truncate here.
2339+
if (TruncToTy) {
23442340
assert(Step->getType()->isIntegerTy() &&
23452341
"Truncation requires an integer step");
2346-
Step = State.Builder.CreateTrunc(Step, ScalarIVTy);
2342+
ScalarIV = State.Builder.CreateTrunc(ScalarIV, TruncToTy);
2343+
Step = State.Builder.CreateTrunc(Step, TruncToTy);
2344+
ScalarIVTy = ScalarIV->getType()->getScalarType();
23472345
}
23482346

2347+
// We shouldn't have to build scalar steps if we aren't vectorizing.
2348+
// Get the value type and ensure it and the step have the same integer type.
2349+
assert(ScalarIVTy == Step->getType() &&
2350+
"Val and Step should have the same type");
2351+
23492352
// We build scalar steps for both integer and floating-point induction
23502353
// variables. Here, we determine the kind of arithmetic we will perform.
23512354
Instruction::BinaryOps AddOp;
@@ -9530,32 +9533,6 @@ void VPWidenPointerInductionRecipe::execute(VPTransformState &State) {
95309533
}
95319534
}
95329535

9533-
void VPDerivedIVRecipe::execute(VPTransformState &State) {
9534-
assert(!State.Instance && "VPDerivedIVRecipe being replicated.");
9535-
9536-
// Fast-math-flags propagate from the original induction instruction.
9537-
IRBuilder<>::FastMathFlagGuard FMFG(State.Builder);
9538-
if (IndDesc.getInductionBinOp() &&
9539-
isa<FPMathOperator>(IndDesc.getInductionBinOp()))
9540-
State.Builder.setFastMathFlags(
9541-
IndDesc.getInductionBinOp()->getFastMathFlags());
9542-
9543-
Value *Step = State.get(getStepValue(), VPIteration(0, 0));
9544-
Value *CanonicalIV = State.get(getCanonicalIV(), VPIteration(0, 0));
9545-
Value *DerivedIV =
9546-
emitTransformedIndex(State.Builder, CanonicalIV,
9547-
getStartValue()->getLiveInIRValue(), Step, IndDesc);
9548-
DerivedIV->setName("offset.idx");
9549-
if (ResultTy != DerivedIV->getType()) {
9550-
assert(Step->getType()->isIntegerTy() &&
9551-
"Truncation requires an integer step");
9552-
DerivedIV = State.Builder.CreateTrunc(DerivedIV, ResultTy);
9553-
}
9554-
assert(DerivedIV != CanonicalIV && "IV didn't need transforming?");
9555-
9556-
State.set(this, DerivedIV, VPIteration(0, 0));
9557-
}
9558-
95599536
void VPScalarIVStepsRecipe::execute(VPTransformState &State) {
95609537
assert(!State.Instance && "VPScalarIVStepsRecipe being replicated.");
95619538

@@ -9566,10 +9543,21 @@ void VPScalarIVStepsRecipe::execute(VPTransformState &State) {
95669543
State.Builder.setFastMathFlags(
95679544
IndDesc.getInductionBinOp()->getFastMathFlags());
95689545

9569-
Value *BaseIV = State.get(getOperand(0), VPIteration(0, 0));
95709546
Value *Step = State.get(getStepValue(), VPIteration(0, 0));
9547+
auto CreateScalarIV = [&](Value *&Step) -> Value * {
9548+
Value *ScalarIV = State.get(getCanonicalIV(), VPIteration(0, 0));
9549+
auto *CanonicalIV = State.get(getParent()->getPlan()->getCanonicalIV(), 0);
9550+
if (!isCanonical() || CanonicalIV->getType() != Step->getType()) {
9551+
ScalarIV = emitTransformedIndex(State.Builder, ScalarIV,
9552+
getStartValue()->getLiveInIRValue(), Step,
9553+
IndDesc);
9554+
ScalarIV->setName("offset.idx");
9555+
}
9556+
return ScalarIV;
9557+
};
95719558

9572-
buildScalarSteps(BaseIV, Step, IndDesc, this, State);
9559+
Value *ScalarIV = CreateScalarIV(Step);
9560+
buildScalarSteps(ScalarIV, Step, IndDesc, this, TruncToTy, State);
95739561
}
95749562

95759563
void VPInterleaveRecipe::execute(VPTransformState &State) {

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,14 +648,12 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
648648

649649
// When vectorizing the epilogue loop, the canonical induction start value
650650
// needs to be changed from zero to the value after the main vector loop.
651-
// FIXME: Improve modeling for canonical IV start values in the epilogue loop.
652651
if (CanonicalIVStartValue) {
653652
VPValue *VPV = getOrAddExternalDef(CanonicalIVStartValue);
654653
auto *IV = getCanonicalIV();
655654
assert(all_of(IV->users(),
656655
[](const VPUser *U) {
657-
if (isa<VPScalarIVStepsRecipe>(U) ||
658-
isa<VPDerivedIVRecipe>(U))
656+
if (isa<VPScalarIVStepsRecipe>(U))
659657
return true;
660658
auto *VPI = cast<VPInstruction>(U);
661659
return VPI->getOpcode() ==

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 14 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,10 +1869,6 @@ class VPCanonicalIVPHIRecipe : public VPHeaderPHIRecipe {
18691869
"Op must be an operand of the recipe");
18701870
return true;
18711871
}
1872-
1873-
/// Check if the induction described by \p ID is canonical, i.e. has the same
1874-
/// start, step (of 1), and type as the canonical IV.
1875-
bool isCanonical(const InductionDescriptor &ID, Type *Ty) const;
18761872
};
18771873

18781874
/// A recipe for generating the active lane mask for the vector loop that is
@@ -1953,76 +1949,19 @@ class VPWidenCanonicalIVRecipe : public VPRecipeBase, public VPValue {
19531949
}
19541950
};
19551951

1956-
/// A recipe for converting the canonical IV value to the corresponding value of
1957-
/// an IV with different start and step values, using Start + CanonicalIV *
1958-
/// Step.
1959-
class VPDerivedIVRecipe : public VPRecipeBase, public VPValue {
1960-
/// The type of the result value. It may be smaller than the type of the
1961-
/// induction and in this case it will get truncated to ResultTy.
1962-
Type *ResultTy;
1963-
1964-
/// Induction descriptor for the induction the canonical IV is transformed to.
1965-
const InductionDescriptor &IndDesc;
1966-
1967-
public:
1968-
VPDerivedIVRecipe(const InductionDescriptor &IndDesc, VPValue *Start,
1969-
VPCanonicalIVPHIRecipe *CanonicalIV, VPValue *Step,
1970-
Type *ResultTy)
1971-
: VPRecipeBase(VPDerivedIVSC, {Start, CanonicalIV, Step}),
1972-
VPValue(VPVDerivedIVSC, nullptr, this), ResultTy(ResultTy),
1973-
IndDesc(IndDesc) {}
1974-
1975-
~VPDerivedIVRecipe() override = default;
1976-
1977-
/// Method to support type inquiry through isa, cast, and dyn_cast.
1978-
static inline bool classof(const VPDef *D) {
1979-
return D->getVPDefID() == VPRecipeBase::VPDerivedIVSC;
1980-
}
1981-
/// Extra classof implementations to allow directly casting from VPUser ->
1982-
/// VPDerivedIVRecipe.
1983-
static inline bool classof(const VPUser *U) {
1984-
auto *R = dyn_cast<VPRecipeBase>(U);
1985-
return R && R->getVPDefID() == VPRecipeBase::VPDerivedIVSC;
1986-
}
1987-
static inline bool classof(const VPRecipeBase *R) {
1988-
return R->getVPDefID() == VPRecipeBase::VPDerivedIVSC;
1989-
}
1990-
static inline bool classof(const VPValue *V) {
1991-
return V->getVPValueID() == VPValue::VPVDerivedIVSC;
1992-
}
1993-
1994-
/// Generate the transformed value of the induction at offset StartValue (1.
1995-
/// operand) + IV (2. operand) * StepValue (3, operand).
1996-
void execute(VPTransformState &State) override;
1997-
1998-
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1999-
/// Print the recipe.
2000-
void print(raw_ostream &O, const Twine &Indent,
2001-
VPSlotTracker &SlotTracker) const override;
2002-
#endif
2003-
2004-
VPValue *getStartValue() const { return getOperand(0); }
2005-
VPValue *getCanonicalIV() const { return getOperand(1); }
2006-
VPValue *getStepValue() const { return getOperand(2); }
2007-
2008-
/// Returns true if the recipe only uses the first lane of operand \p Op.
2009-
bool onlyFirstLaneUsed(const VPValue *Op) const override {
2010-
assert(is_contained(operands(), Op) &&
2011-
"Op must be an operand of the recipe");
2012-
return true;
2013-
}
2014-
};
2015-
20161952
/// A recipe for handling phi nodes of integer and floating-point inductions,
20171953
/// producing their scalar values.
20181954
class VPScalarIVStepsRecipe : public VPRecipeBase, public VPValue {
1955+
/// If not nullptr, truncate the generated values to TruncToTy.
1956+
Type *TruncToTy;
20191957
const InductionDescriptor &IndDesc;
20201958

20211959
public:
2022-
VPScalarIVStepsRecipe(const InductionDescriptor &IndDesc, VPValue *IV,
2023-
VPValue *Step)
2024-
: VPRecipeBase(VPScalarIVStepsSC, {IV, Step}), VPValue(nullptr, this),
2025-
IndDesc(IndDesc) {}
1960+
VPScalarIVStepsRecipe(const InductionDescriptor &IndDesc,
1961+
VPValue *CanonicalIV, VPValue *Start, VPValue *Step,
1962+
Type *TruncToTy)
1963+
: VPRecipeBase(VPScalarIVStepsSC, {CanonicalIV, Start, Step}),
1964+
VPValue(nullptr, this), TruncToTy(TruncToTy), IndDesc(IndDesc) {}
20261965

20271966
~VPScalarIVStepsRecipe() override = default;
20281967

@@ -2049,7 +1988,13 @@ class VPScalarIVStepsRecipe : public VPRecipeBase, public VPValue {
20491988
VPSlotTracker &SlotTracker) const override;
20501989
#endif
20511990

2052-
VPValue *getStepValue() const { return getOperand(1); }
1991+
/// Returns true if the induction is canonical, i.e. starting at 0 and
1992+
/// incremented by UF * VF (= the original IV is incremented by 1).
1993+
bool isCanonical() const;
1994+
1995+
VPCanonicalIVPHIRecipe *getCanonicalIV() const;
1996+
VPValue *getStartValue() const { return getOperand(1); }
1997+
VPValue *getStepValue() const { return getOperand(2); }
20531998

20541999
/// Returns true if the recipe only uses the first lane of operand \p Op.
20552000
bool onlyFirstLaneUsed(const VPValue *Op) const override {

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ bool VPRecipeBase::mayReadFromMemory() const {
103103

104104
bool VPRecipeBase::mayHaveSideEffects() const {
105105
switch (getVPDefID()) {
106-
case VPDerivedIVSC:
107106
case VPPredInstPHISC:
108107
return false;
109108
case VPWidenIntOrFpInductionSC:
@@ -713,22 +712,22 @@ bool VPWidenIntOrFpInductionRecipe::isCanonical() const {
713712
return StartC && StartC->isZero() && StepC && StepC->isOne();
714713
}
715714

716-
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
717-
void VPDerivedIVRecipe::print(raw_ostream &O, const Twine &Indent,
718-
VPSlotTracker &SlotTracker) const {
719-
O << Indent;
720-
printAsOperand(O, SlotTracker);
721-
O << Indent << "= DERIVED-IV ";
722-
getStartValue()->printAsOperand(O, SlotTracker);
723-
O << " + ";
724-
getCanonicalIV()->printAsOperand(O, SlotTracker);
725-
O << " * ";
726-
getStepValue()->printAsOperand(O, SlotTracker);
715+
VPCanonicalIVPHIRecipe *VPScalarIVStepsRecipe::getCanonicalIV() const {
716+
return cast<VPCanonicalIVPHIRecipe>(getOperand(0));
717+
}
727718

728-
if (IndDesc.getStep()->getType() != ResultTy)
729-
O << " (truncated to " << *ResultTy << ")";
719+
bool VPScalarIVStepsRecipe::isCanonical() const {
720+
auto *CanIV = getCanonicalIV();
721+
// The start value of the steps-recipe must match the start value of the
722+
// canonical induction and it must step by 1.
723+
if (CanIV->getStartValue() != getStartValue())
724+
return false;
725+
auto *StepVPV = getStepValue();
726+
if (StepVPV->hasDefiningRecipe())
727+
return false;
728+
auto *StepC = dyn_cast_or_null<ConstantInt>(StepVPV->getLiveInIRValue());
729+
return StepC && StepC->isOne();
730730
}
731-
#endif
732731

733732
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
734733
void VPScalarIVStepsRecipe::print(raw_ostream &O, const Twine &Indent,
@@ -1051,20 +1050,6 @@ void VPCanonicalIVPHIRecipe::print(raw_ostream &O, const Twine &Indent,
10511050
}
10521051
#endif
10531052

1054-
bool VPCanonicalIVPHIRecipe::isCanonical(const InductionDescriptor &ID,
1055-
Type *Ty) const {
1056-
if (Ty != getScalarType())
1057-
return false;
1058-
// The start value of ID must match the start value of this canonical
1059-
// induction.
1060-
if (getStartValue()->getLiveInIRValue() != ID.getStartValue())
1061-
return false;
1062-
1063-
ConstantInt *Step = ID.getConstIntStepValue();
1064-
// ID must also be incremented by one.
1065-
return ID.getInductionOpcode() == Instruction::Add && Step && Step->isOne();
1066-
}
1067-
10681053
bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(ElementCount VF) {
10691054
return IsScalarAfterVectorization &&
10701055
(!VF.isScalable() || vputils::onlyFirstLaneUsed(this));

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -382,40 +382,30 @@ void VPlanTransforms::optimizeInductions(VPlan &Plan, ScalarEvolution &SE) {
382382
VPBasicBlock *HeaderVPBB = Plan.getVectorLoopRegion()->getEntryBasicBlock();
383383
bool HasOnlyVectorVFs = !Plan.hasVF(ElementCount::getFixed(1));
384384
for (VPRecipeBase &Phi : HeaderVPBB->phis()) {
385-
auto *WideIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi);
386-
if (!WideIV)
385+
auto *IV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi);
386+
if (!IV)
387387
continue;
388-
if (HasOnlyVectorVFs && none_of(WideIV->users(), [WideIV](VPUser *U) {
389-
return U->usesScalars(WideIV);
390-
}))
388+
if (HasOnlyVectorVFs &&
389+
none_of(IV->users(), [IV](VPUser *U) { return U->usesScalars(IV); }))
391390
continue;
392391

393-
auto IP = HeaderVPBB->getFirstNonPhi();
394-
VPCanonicalIVPHIRecipe *CanonicalIV = Plan.getCanonicalIV();
395-
Type *ResultTy = WideIV->getPHINode()->getType();
396-
if (Instruction *TruncI = WideIV->getTruncInst())
397-
ResultTy = TruncI->getType();
398-
const InductionDescriptor &ID = WideIV->getInductionDescriptor();
392+
const InductionDescriptor &ID = IV->getInductionDescriptor();
399393
VPValue *Step =
400394
vputils::getOrCreateVPValueForSCEVExpr(Plan, ID.getStep(), SE);
401-
VPValue *BaseIV = CanonicalIV;
402-
if (!CanonicalIV->isCanonical(ID, ResultTy)) {
403-
BaseIV = new VPDerivedIVRecipe(ID, WideIV->getStartValue(), CanonicalIV,
404-
Step, ResultTy);
405-
HeaderVPBB->insert(BaseIV->getDefiningRecipe(), IP);
406-
}
407-
408-
VPScalarIVStepsRecipe *Steps = new VPScalarIVStepsRecipe(ID, BaseIV, Step);
409-
HeaderVPBB->insert(Steps, IP);
395+
Instruction *TruncI = IV->getTruncInst();
396+
VPScalarIVStepsRecipe *Steps = new VPScalarIVStepsRecipe(
397+
ID, Plan.getCanonicalIV(), IV->getStartValue(), Step,
398+
TruncI ? TruncI->getType() : nullptr);
399+
HeaderVPBB->insert(Steps, HeaderVPBB->getFirstNonPhi());
410400

411401
// Update scalar users of IV to use Step instead. Use SetVector to ensure
412402
// the list of users doesn't contain duplicates.
413-
SetVector<VPUser *> Users(WideIV->user_begin(), WideIV->user_end());
403+
SetVector<VPUser *> Users(IV->user_begin(), IV->user_end());
414404
for (VPUser *U : Users) {
415-
if (HasOnlyVectorVFs && !U->usesScalars(WideIV))
405+
if (HasOnlyVectorVFs && !U->usesScalars(IV))
416406
continue;
417407
for (unsigned I = 0, E = U->getNumOperands(); I != E; I++) {
418-
if (U->getOperand(I) != WideIV)
408+
if (U->getOperand(I) != IV)
419409
continue;
420410
U->setOperand(I, Steps);
421411
}

llvm/lib/Transforms/Vectorize/VPlanValue.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ class VPValue {
9090
/// type identification.
9191
enum {
9292
VPValueSC,
93-
VPVDerivedIVSC,
9493
VPVInstructionSC,
9594
VPVMemoryInstructionSC,
9695
VPVReductionSC,
@@ -356,7 +355,6 @@ class VPDef {
356355
/// type identification.
357356
using VPRecipeTy = enum {
358357
VPBranchOnMaskSC,
359-
VPDerivedIVSC,
360358
VPExpandSCEVSC,
361359
VPInstructionSC,
362360
VPInterleaveSC,

llvm/test/Transforms/LoopVectorize/AArch64/sve-tail-folding-forced.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ target triple = "aarch64-unknown-linux-gnu"
1919
; VPLANS-NEXT: vector.body:
2020
; VPLANS-NEXT: EMIT vp<%4> = CANONICAL-INDUCTION
2121
; VPLANS-NEXT: ACTIVE-LANE-MASK-PHI vp<%5> = phi vp<%3>, vp<%10>
22-
; VPLANS-NEXT: vp<%6> = SCALAR-STEPS vp<%4>, ir<1>
22+
; VPLANS-NEXT: vp<%6> = SCALAR-STEPS vp<%4>, ir<0>, ir<1>
2323
; VPLANS-NEXT: CLONE ir<%gep> = getelementptr ir<%ptr>, vp<%6>
2424
; VPLANS-NEXT: WIDEN store ir<%gep>, ir<%val>, vp<%5>
2525
; VPLANS-NEXT: EMIT vp<%8> = VF * UF + vp<%4>

llvm/test/Transforms/LoopVectorize/AArch64/widen-call-with-intrinsic-or-libfunc.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ target triple = "arm64-apple-ios"
1515
; CHECK-NEXT: <x1> vector loop: {
1616
; CHECK-NEXT: vector.body:
1717
; CHECK-NEXT: EMIT vp<%2> = CANONICAL-INDUCTION
18-
; CHECK-NEXT: vp<%3> = SCALAR-STEPS vp<%2>, ir<1>
18+
; CHECK-NEXT: vp<%3> = SCALAR-STEPS vp<%2>, ir<0>, ir<1>
1919
; CHECK-NEXT: CLONE ir<%gep.src> = getelementptr ir<%src>, vp<%3>
2020
; CHECK-NEXT: WIDEN ir<%l> = load ir<%gep.src>
2121
; CHECK-NEXT: WIDEN ir<%conv> = fpext ir<%l>
@@ -41,7 +41,7 @@ target triple = "arm64-apple-ios"
4141
; CHECK-NEXT: <x1> vector loop: {
4242
; CHECK-NEXT: vector.body:
4343
; CHECK-NEXT: EMIT vp<%2> = CANONICAL-INDUCTION
44-
; CHECK-NEXT: vp<%3> = SCALAR-STEPS vp<%2>, ir<1>
44+
; CHECK-NEXT: vp<%3> = SCALAR-STEPS vp<%2>, ir<0>, ir<1>
4545
; CHECK-NEXT: CLONE ir<%gep.src> = getelementptr ir<%src>, vp<%3>
4646
; CHECK-NEXT: WIDEN ir<%l> = load ir<%gep.src>
4747
; CHECK-NEXT: WIDEN ir<%conv> = fpext ir<%l>

0 commit comments

Comments
 (0)