Skip to content

Commit d74aca2

Browse files
committed
Merge branch 'vpwideninductionrecipe' into vplan-compute-iv-end-values
2 parents 8a1748a + 89a1b3a commit d74aca2

File tree

6 files changed

+79
-71
lines changed

6 files changed

+79
-71
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10181,13 +10181,7 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
1018110181
} else {
1018210182
// Retrieve the induction resume values for wide inductions from
1018310183
// their original phi nodes in the scalar loop.
10184-
PHINode *IndPhi = nullptr;
10185-
if (auto *Ind = dyn_cast<VPWidenPointerInductionRecipe>(&R)) {
10186-
IndPhi = cast<PHINode>(Ind->getUnderlyingValue());
10187-
} else {
10188-
auto *WidenInd = cast<VPWidenIntOrFpInductionRecipe>(&R);
10189-
IndPhi = WidenInd->getPHINode();
10190-
}
10184+
PHINode *IndPhi = dyn_cast<VPWidenInductionRecipe>(&R)->getPHINode();
1019110185
// Hook up to the PHINode generated by a ResumePhi recipe of main
1019210186
// loop VPlan, which feeds the scalar loop.
1019310187
ResumeV = IndPhi->getIncomingValueForBlock(L->getLoopPreheader());

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ void VPlan::execute(VPTransformState *State) {
10471047
if (isa<VPWidenPHIRecipe>(&R))
10481048
continue;
10491049

1050-
if (isa<VPWidenPointerInductionRecipe, VPWidenIntOrFpInductionRecipe>(&R)) {
1050+
if (isa<VPWidenInductionRecipe>(&R)) {
10511051
PHINode *Phi = nullptr;
10521052
if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
10531053
Phi = cast<PHINode>(State->get(R.getVPSingleValue()));

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 61 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,38 +2099,81 @@ class VPHeaderPHIRecipe : public VPSingleDefRecipe {
20992099
}
21002100
};
21012101

2102+
/// Base class for widened induction (VPWidenIntOrFpInductionRecipe and
2103+
/// VPWidenPointerInductionRecipe), providing shared functionality, including
2104+
/// retrieving the step value, induction descriptor and original phi node.
2105+
class VPWidenInductionRecipe : public VPHeaderPHIRecipe {
2106+
const InductionDescriptor &IndDesc;
2107+
2108+
public:
2109+
VPWidenInductionRecipe(unsigned char Kind, PHINode *IV, VPValue *Start,
2110+
VPValue *Step, const InductionDescriptor &IndDesc,
2111+
DebugLoc DL)
2112+
: VPHeaderPHIRecipe(Kind, IV, Start, DL), IndDesc(IndDesc) {
2113+
addOperand(Step);
2114+
}
2115+
2116+
static inline bool classof(const VPRecipeBase *R) {
2117+
return R->getVPDefID() == VPDef::VPWidenIntOrFpInductionSC ||
2118+
R->getVPDefID() == VPDef::VPWidenPointerInductionSC;
2119+
}
2120+
2121+
virtual void execute(VPTransformState &State) override = 0;
2122+
2123+
/// Returns the step value of the induction.
2124+
VPValue *getStepValue() { return getOperand(1); }
2125+
const VPValue *getStepValue() const { return getOperand(1); }
2126+
2127+
PHINode *getPHINode() const { return cast<PHINode>(getUnderlyingValue()); }
2128+
2129+
/// Returns the induction descriptor for the recipe.
2130+
const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
2131+
2132+
VPValue *getBackedgeValue() override {
2133+
// TODO: All operands of base recipe must exist and be at same index in
2134+
// derived recipe.
2135+
llvm_unreachable(
2136+
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
2137+
}
2138+
2139+
VPRecipeBase &getBackedgeRecipe() override {
2140+
// TODO: All operands of base recipe must exist and be at same index in
2141+
// derived recipe.
2142+
llvm_unreachable(
2143+
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
2144+
}
2145+
};
2146+
21022147
/// A recipe for handling phi nodes of integer and floating-point inductions,
21032148
/// producing their vector values.
2104-
class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
2105-
PHINode *IV;
2149+
class VPWidenIntOrFpInductionRecipe : public VPWidenInductionRecipe {
21062150
TruncInst *Trunc;
2107-
const InductionDescriptor &IndDesc;
21082151

21092152
public:
21102153
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
21112154
VPValue *VF, const InductionDescriptor &IndDesc,
21122155
DebugLoc DL)
2113-
: VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start, DL),
2114-
IV(IV), Trunc(nullptr), IndDesc(IndDesc) {
2115-
addOperand(Step);
2156+
: VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start,
2157+
Step, IndDesc, DL),
2158+
Trunc(nullptr) {
21162159
addOperand(VF);
21172160
}
21182161

21192162
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
21202163
VPValue *VF, const InductionDescriptor &IndDesc,
21212164
TruncInst *Trunc, DebugLoc DL)
2122-
: VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, Trunc, Start, DL),
2123-
IV(IV), Trunc(Trunc), IndDesc(IndDesc) {
2124-
addOperand(Step);
2165+
: VPWidenInductionRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start,
2166+
Step, IndDesc, DL),
2167+
Trunc(Trunc) {
21252168
addOperand(VF);
21262169
}
21272170

21282171
~VPWidenIntOrFpInductionRecipe() override = default;
21292172

21302173
VPWidenIntOrFpInductionRecipe *clone() override {
2131-
return new VPWidenIntOrFpInductionRecipe(IV, getStartValue(),
2132-
getStepValue(), getVFValue(),
2133-
IndDesc, Trunc, getDebugLoc());
2174+
return new VPWidenIntOrFpInductionRecipe(
2175+
getPHINode(), getStartValue(), getStepValue(), getVFValue(),
2176+
getInductionDescriptor(), Trunc, getDebugLoc());
21342177
}
21352178

21362179
VP_CLASSOF_IMPL(VPDef::VPWidenIntOrFpInductionSC)
@@ -2145,24 +2188,6 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
21452188
VPSlotTracker &SlotTracker) const override;
21462189
#endif
21472190

2148-
VPValue *getBackedgeValue() override {
2149-
// TODO: All operands of base recipe must exist and be at same index in
2150-
// derived recipe.
2151-
llvm_unreachable(
2152-
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
2153-
}
2154-
2155-
VPRecipeBase &getBackedgeRecipe() override {
2156-
// TODO: All operands of base recipe must exist and be at same index in
2157-
// derived recipe.
2158-
llvm_unreachable(
2159-
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
2160-
}
2161-
2162-
/// Returns the step value of the induction.
2163-
VPValue *getStepValue() { return getOperand(1); }
2164-
const VPValue *getStepValue() const { return getOperand(1); }
2165-
21662191
VPValue *getVFValue() { return getOperand(2); }
21672192
const VPValue *getVFValue() const { return getOperand(2); }
21682193

@@ -2177,19 +2202,14 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
21772202
TruncInst *getTruncInst() { return Trunc; }
21782203
const TruncInst *getTruncInst() const { return Trunc; }
21792204

2180-
PHINode *getPHINode() { return IV; }
2181-
2182-
/// Returns the induction descriptor for the recipe.
2183-
const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
2184-
21852205
/// Returns true if the induction is canonical, i.e. starting at 0 and
21862206
/// incremented by UF * VF (= the original IV is incremented by 1) and has the
21872207
/// same type as the canonical induction.
21882208
bool isCanonical() const;
21892209

21902210
/// Returns the scalar type of the induction.
21912211
Type *getScalarType() const {
2192-
return Trunc ? Trunc->getType() : IV->getType();
2212+
return Trunc ? Trunc->getType() : getPHINode()->getType();
21932213
}
21942214

21952215
/// Returns the VPValue representing the value of this induction at
@@ -2200,10 +2220,8 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
22002220
}
22012221
};
22022222

2203-
class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe,
2223+
class VPWidenPointerInductionRecipe : public VPWidenInductionRecipe,
22042224
public VPUnrollPartAccessor<3> {
2205-
const InductionDescriptor &IndDesc;
2206-
22072225
bool IsScalarAfterVectorization;
22082226

22092227
public:
@@ -2212,19 +2230,16 @@ class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe,
22122230
VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, VPValue *Step,
22132231
const InductionDescriptor &IndDesc,
22142232
bool IsScalarAfterVectorization, DebugLoc DL)
2215-
: VPHeaderPHIRecipe(VPDef::VPWidenPointerInductionSC, Phi, nullptr, DL),
2216-
IndDesc(IndDesc),
2217-
IsScalarAfterVectorization(IsScalarAfterVectorization) {
2218-
addOperand(Start);
2219-
addOperand(Step);
2220-
}
2233+
: VPWidenInductionRecipe(VPDef::VPWidenPointerInductionSC, Phi, Start,
2234+
Step, IndDesc, DL),
2235+
IsScalarAfterVectorization(IsScalarAfterVectorization) {}
22212236

22222237
~VPWidenPointerInductionRecipe() override = default;
22232238

22242239
VPWidenPointerInductionRecipe *clone() override {
22252240
return new VPWidenPointerInductionRecipe(
22262241
cast<PHINode>(getUnderlyingInstr()), getOperand(0), getOperand(1),
2227-
IndDesc, IsScalarAfterVectorization, getDebugLoc());
2242+
getInductionDescriptor(), IsScalarAfterVectorization, getDebugLoc());
22282243
}
22292244

22302245
VP_CLASSOF_IMPL(VPDef::VPWidenPointerInductionSC)
@@ -2235,9 +2250,6 @@ class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe,
22352250
/// Returns true if only scalar values will be generated.
22362251
bool onlyScalarsGenerated(bool IsScalable);
22372252

2238-
/// Returns the induction descriptor for the recipe.
2239-
const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
2240-
22412253
/// Returns the VPValue representing the value of this induction at
22422254
/// the first unrolled part, if it exists. Returns itself if unrolling did not
22432255
/// take place.

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,12 +1660,13 @@ void VPWidenIntOrFpInductionRecipe::execute(VPTransformState &State) {
16601660
const InductionDescriptor &ID = getInductionDescriptor();
16611661
TruncInst *Trunc = getTruncInst();
16621662
IRBuilderBase &Builder = State.Builder;
1663-
assert(IV->getType() == ID.getStartValue()->getType() && "Types must match");
1663+
assert(getPHINode()->getType() == ID.getStartValue()->getType() &&
1664+
"Types must match");
16641665
assert(State.VF.isVector() && "must have vector VF");
16651666

16661667
// The value from the original loop to which we are mapping the new induction
16671668
// variable.
1668-
Instruction *EntryVal = Trunc ? cast<Instruction>(Trunc) : IV;
1669+
Instruction *EntryVal = Trunc ? cast<Instruction>(Trunc) : getPHINode();
16691670

16701671
// Fast-math-flags propagate from the original induction instruction.
16711672
IRBuilder<>::FastMathFlagGuard FMFG(Builder);
@@ -1755,13 +1756,12 @@ void VPWidenIntOrFpInductionRecipe::execute(VPTransformState &State) {
17551756
void VPWidenIntOrFpInductionRecipe::print(raw_ostream &O, const Twine &Indent,
17561757
VPSlotTracker &SlotTracker) const {
17571758
O << Indent << "WIDEN-INDUCTION";
1758-
if (getTruncInst()) {
1759+
if (auto *TI = getTruncInst()) {
17591760
O << "\\l\"";
1760-
O << " +\n" << Indent << "\" " << VPlanIngredient(IV) << "\\l\"";
1761-
O << " +\n" << Indent << "\" ";
1762-
getVPValue(0)->printAsOperand(O, SlotTracker);
1761+
O << " +\n" << Indent << "\" " << VPlanIngredient(getPHINode()) << "\\l\"";
1762+
O << " +\n" << Indent << "\" " << VPlanIngredient(TI);
17631763
} else
1764-
O << " " << VPlanIngredient(IV);
1764+
O << " " << VPlanIngredient(getPHINode());
17651765

17661766
O << ", ";
17671767
getStepValue()->printAsOperand(O, SlotTracker);
@@ -3157,7 +3157,8 @@ bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(bool IsScalable) {
31573157
}
31583158

31593159
void VPWidenPointerInductionRecipe::execute(VPTransformState &State) {
3160-
assert(IndDesc.getKind() == InductionDescriptor::IK_PtrInduction &&
3160+
assert(getInductionDescriptor().getKind() ==
3161+
InductionDescriptor::IK_PtrInduction &&
31613162
"Not a pointer induction according to InductionDescriptor!");
31623163
assert(cast<PHINode>(getUnderlyingInstr())->getType()->isPointerTy() &&
31633164
"Unexpected type.");
@@ -3193,8 +3194,8 @@ void VPWidenPointerInductionRecipe::execute(VPTransformState &State) {
31933194

31943195
// A pointer induction, performed by using a gep
31953196
BasicBlock::iterator InductionLoc = State.Builder.GetInsertPoint();
3196-
Value *ScalarStepValue = State.get(getOperand(1), VPLane(0));
3197-
Type *PhiType = IndDesc.getStep()->getType();
3197+
Value *ScalarStepValue = State.get(getStepValue(), VPLane(0));
3198+
Type *PhiType = State.TypeAnalysis.inferScalarType(getStepValue());
31983199
Value *RuntimeVF = getRuntimeVF(State.Builder, PhiType, State.VF);
31993200
// Add induction update using an incorrect block temporarily. The phi node
32003201
// will be fixed after VPlan execution. Note that at this point the latch
@@ -3246,7 +3247,8 @@ void VPWidenPointerInductionRecipe::print(raw_ostream &O, const Twine &Indent,
32463247
printAsOperand(O, SlotTracker);
32473248
O << " = WIDEN-POINTER-INDUCTION ";
32483249
getStartValue()->printAsOperand(O, SlotTracker);
3249-
O << ", " << *IndDesc.getStep();
3250+
O << ", ";
3251+
getStepValue()->printAsOperand(O, SlotTracker);
32503252
if (getNumOperands() == 4) {
32513253
O << ", ";
32523254
getOperand(2)->printAsOperand(O, SlotTracker);

llvm/test/Transforms/LoopVectorize/AArch64/sve-widen-gep.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ target triple = "aarch64-unknown-linux-gnu"
2424
; CHECK-NEXT: <x1> vector loop: {
2525
; CHECK-NEXT: vector.body:
2626
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
27-
; CHECK-NEXT: EMIT ir<%ptr.iv.2> = WIDEN-POINTER-INDUCTION ir<%start.2>, 1
27+
; CHECK-NEXT: EMIT ir<%ptr.iv.2> = WIDEN-POINTER-INDUCTION ir<%start.2>, ir<1>
2828
; CHECK-NEXT: vp<[[PTR_IDX:%.+]]> = DERIVED-IV ir<0> + vp<[[CAN_IV]]> * ir<8>
2929
; CHECK-NEXT: vp<[[PTR_IDX_STEPS:%.+]]> = SCALAR-STEPS vp<[[PTR_IDX]]>, ir<8>
3030
; CHECK-NEXT: EMIT vp<[[PTR_IV_1:%.+]]> = ptradd ir<%start.1>, vp<[[PTR_IDX_STEPS]]>

llvm/test/Transforms/LoopVectorize/vplan-printing.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,10 +665,10 @@ define void @print_expand_scev(i64 %y, ptr %ptr) {
665665
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION ir<0>, vp<[[CAN_IV_NEXT:%.+]]>
666666
; CHECK-NEXT: WIDEN-INDUCTION\l" +
667667
; CHECK-NEXT: " %iv = phi %iv.next, 0\l" +
668-
; CHECK-NEXT: " ir<%v2>, vp<[[EXP_SCEV]]>, vp<[[VF]]>
668+
; CHECK-NEXT: " %v2 = trunc %iv, vp<[[EXP_SCEV]]>, vp<[[VF]]>
669669
; CHECK-NEXT: vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<0> + vp<[[CAN_IV]]> * vp<[[EXP_SCEV]]>
670670
; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[DERIVED_IV]]>, vp<[[EXP_SCEV]]>
671-
; CHECK-NEXT: WIDEN ir<%v3> = add nuw ir<%v2>, ir<1>
671+
; CHECK-NEXT: WIDEN ir<%v3> = add nuw ir<%iv>, ir<1>
672672
; CHECK-NEXT: REPLICATE ir<%gep> = getelementptr inbounds ir<%ptr>, vp<[[STEPS]]>
673673
; CHECK-NEXT: REPLICATE store ir<%v3>, ir<%gep>
674674
; CHECK-NEXT: EMIT vp<[[CAN_IV_NEXT]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>

0 commit comments

Comments
 (0)