Skip to content

Commit 511726c

Browse files
committed
[LV] Move getStepVector out of ILV (NFC).
First step to split up induction handling and move it outside ILV. Used in D116123 and following.
1 parent bf7f3dd commit 511726c

File tree

1 file changed

+70
-77
lines changed

1 file changed

+70
-77
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

+70-77
Original file line numberDiff line numberDiff line change
@@ -606,14 +606,6 @@ class InnerLoopVectorizer {
606606
/// represented as.
607607
void truncateToMinimalBitwidths(VPTransformState &State);
608608

609-
/// This function adds
610-
/// (StartIdx * Step, (StartIdx + 1) * Step, (StartIdx + 2) * Step, ...)
611-
/// to each vector element of Val. The sequence starts at StartIndex.
612-
/// \p Opcode is relevant for FP induction variable.
613-
virtual Value *
614-
getStepVector(Value *Val, Value *StartIdx, Value *Step,
615-
Instruction::BinaryOps Opcode = Instruction::BinaryOpsEnd);
616-
617609
/// Compute scalar induction steps. \p ScalarIV is the scalar induction
618610
/// variable on which to base the steps, \p Step is the size of the step, and
619611
/// \p EntryVal is the value from the original loop that maps to the steps.
@@ -856,9 +848,6 @@ class InnerLoopUnroller : public InnerLoopVectorizer {
856848

857849
private:
858850
Value *getBroadcastInstrs(Value *V) override;
859-
Value *getStepVector(
860-
Value *Val, Value *StartIdx, Value *Step,
861-
Instruction::BinaryOps Opcode = Instruction::BinaryOpsEnd) override;
862851
Value *reverseVector(Value *Vec) override;
863852
};
864853

@@ -2335,6 +2324,72 @@ Value *InnerLoopVectorizer::getBroadcastInstrs(Value *V) {
23352324
return Shuf;
23362325
}
23372326

2327+
/// This function adds
2328+
/// (StartIdx * Step, (StartIdx + 1) * Step, (StartIdx + 2) * Step, ...)
2329+
/// to each vector element of Val. The sequence starts at StartIndex.
2330+
/// \p Opcode is relevant for FP induction variable.
2331+
static Value *getStepVector(Value *Val, Value *StartIdx, Value *Step,
2332+
Instruction::BinaryOps BinOp, ElementCount VF,
2333+
IRBuilder<> &Builder) {
2334+
if (VF.isScalar()) {
2335+
// When unrolling and the VF is 1, we only need to add a simple scalar.
2336+
Type *Ty = Val->getType();
2337+
assert(!Ty->isVectorTy() && "Val must be a scalar");
2338+
2339+
if (Ty->isFloatingPointTy()) {
2340+
// Floating-point operations inherit FMF via the builder's flags.
2341+
Value *MulOp = Builder.CreateFMul(StartIdx, Step);
2342+
return Builder.CreateBinOp(BinOp, Val, MulOp);
2343+
}
2344+
return Builder.CreateAdd(Val, Builder.CreateMul(StartIdx, Step),
2345+
"induction");
2346+
}
2347+
2348+
// Create and check the types.
2349+
auto *ValVTy = cast<VectorType>(Val->getType());
2350+
ElementCount VLen = ValVTy->getElementCount();
2351+
2352+
Type *STy = Val->getType()->getScalarType();
2353+
assert((STy->isIntegerTy() || STy->isFloatingPointTy()) &&
2354+
"Induction Step must be an integer or FP");
2355+
assert(Step->getType() == STy && "Step has wrong type");
2356+
2357+
SmallVector<Constant *, 8> Indices;
2358+
2359+
// Create a vector of consecutive numbers from zero to VF.
2360+
VectorType *InitVecValVTy = ValVTy;
2361+
Type *InitVecValSTy = STy;
2362+
if (STy->isFloatingPointTy()) {
2363+
InitVecValSTy =
2364+
IntegerType::get(STy->getContext(), STy->getScalarSizeInBits());
2365+
InitVecValVTy = VectorType::get(InitVecValSTy, VLen);
2366+
}
2367+
Value *InitVec = Builder.CreateStepVector(InitVecValVTy);
2368+
2369+
// Splat the StartIdx
2370+
Value *StartIdxSplat = Builder.CreateVectorSplat(VLen, StartIdx);
2371+
2372+
if (STy->isIntegerTy()) {
2373+
InitVec = Builder.CreateAdd(InitVec, StartIdxSplat);
2374+
Step = Builder.CreateVectorSplat(VLen, Step);
2375+
assert(Step->getType() == Val->getType() && "Invalid step vec");
2376+
// FIXME: The newly created binary instructions should contain nsw/nuw
2377+
// flags, which can be found from the original scalar operations.
2378+
Step = Builder.CreateMul(InitVec, Step);
2379+
return Builder.CreateAdd(Val, Step, "induction");
2380+
}
2381+
2382+
// Floating point induction.
2383+
assert((BinOp == Instruction::FAdd || BinOp == Instruction::FSub) &&
2384+
"Binary Opcode should be specified for FP induction");
2385+
InitVec = Builder.CreateUIToFP(InitVec, ValVTy);
2386+
InitVec = Builder.CreateFAdd(InitVec, StartIdxSplat);
2387+
2388+
Step = Builder.CreateVectorSplat(VLen, Step);
2389+
Value *MulOp = Builder.CreateFMul(InitVec, Step);
2390+
return Builder.CreateBinOp(BinOp, Val, MulOp, "induction");
2391+
}
2392+
23382393
void InnerLoopVectorizer::createVectorIntOrFpInductionPHI(
23392394
const InductionDescriptor &II, Value *Step, Value *Start,
23402395
Instruction *EntryVal, VPValue *Def, VPTransformState &State) {
@@ -2355,8 +2410,8 @@ void InnerLoopVectorizer::createVectorIntOrFpInductionPHI(
23552410

23562411
Value *Zero = getSignedIntOrFpConstant(Start->getType(), 0);
23572412
Value *SplatStart = Builder.CreateVectorSplat(State.VF, Start);
2358-
Value *SteppedStart =
2359-
getStepVector(SplatStart, Zero, Step, II.getInductionOpcode());
2413+
Value *SteppedStart = getStepVector(
2414+
SplatStart, Zero, Step, II.getInductionOpcode(), State.VF, State.Builder);
23602415

23612416
// We create vector phi nodes for both integer and floating-point induction
23622417
// variables. Here, we determine the kind of arithmetic we will perform.
@@ -2502,7 +2557,8 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV,
25022557
StartIdx = getRuntimeVF(Builder, Step->getType(), State.VF * Part);
25032558

25042559
Value *EntryPart =
2505-
getStepVector(Broadcasted, StartIdx, Step, ID.getInductionOpcode());
2560+
getStepVector(Broadcasted, StartIdx, Step, ID.getInductionOpcode(),
2561+
State.VF, State.Builder);
25062562
State.set(Def, EntryPart, Part);
25072563
if (Trunc)
25082564
addMetadata(EntryPart, Trunc);
@@ -2554,54 +2610,6 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV,
25542610
buildScalarSteps(ScalarIV, Step, EntryVal, ID, Def, State);
25552611
}
25562612

2557-
Value *InnerLoopVectorizer::getStepVector(Value *Val, Value *StartIdx,
2558-
Value *Step,
2559-
Instruction::BinaryOps BinOp) {
2560-
// Create and check the types.
2561-
auto *ValVTy = cast<VectorType>(Val->getType());
2562-
ElementCount VLen = ValVTy->getElementCount();
2563-
2564-
Type *STy = Val->getType()->getScalarType();
2565-
assert((STy->isIntegerTy() || STy->isFloatingPointTy()) &&
2566-
"Induction Step must be an integer or FP");
2567-
assert(Step->getType() == STy && "Step has wrong type");
2568-
2569-
SmallVector<Constant *, 8> Indices;
2570-
2571-
// Create a vector of consecutive numbers from zero to VF.
2572-
VectorType *InitVecValVTy = ValVTy;
2573-
Type *InitVecValSTy = STy;
2574-
if (STy->isFloatingPointTy()) {
2575-
InitVecValSTy =
2576-
IntegerType::get(STy->getContext(), STy->getScalarSizeInBits());
2577-
InitVecValVTy = VectorType::get(InitVecValSTy, VLen);
2578-
}
2579-
Value *InitVec = Builder.CreateStepVector(InitVecValVTy);
2580-
2581-
// Splat the StartIdx
2582-
Value *StartIdxSplat = Builder.CreateVectorSplat(VLen, StartIdx);
2583-
2584-
if (STy->isIntegerTy()) {
2585-
InitVec = Builder.CreateAdd(InitVec, StartIdxSplat);
2586-
Step = Builder.CreateVectorSplat(VLen, Step);
2587-
assert(Step->getType() == Val->getType() && "Invalid step vec");
2588-
// FIXME: The newly created binary instructions should contain nsw/nuw flags,
2589-
// which can be found from the original scalar operations.
2590-
Step = Builder.CreateMul(InitVec, Step);
2591-
return Builder.CreateAdd(Val, Step, "induction");
2592-
}
2593-
2594-
// Floating point induction.
2595-
assert((BinOp == Instruction::FAdd || BinOp == Instruction::FSub) &&
2596-
"Binary Opcode should be specified for FP induction");
2597-
InitVec = Builder.CreateUIToFP(InitVec, ValVTy);
2598-
InitVec = Builder.CreateFAdd(InitVec, StartIdxSplat);
2599-
2600-
Step = Builder.CreateVectorSplat(VLen, Step);
2601-
Value *MulOp = Builder.CreateFMul(InitVec, Step);
2602-
return Builder.CreateBinOp(BinOp, Val, MulOp, "induction");
2603-
}
2604-
26052613
void InnerLoopVectorizer::buildScalarSteps(Value *ScalarIV, Value *Step,
26062614
Instruction *EntryVal,
26072615
const InductionDescriptor &ID,
@@ -8036,21 +8044,6 @@ Value *InnerLoopUnroller::reverseVector(Value *Vec) { return Vec; }
80368044

80378045
Value *InnerLoopUnroller::getBroadcastInstrs(Value *V) { return V; }
80388046

8039-
Value *InnerLoopUnroller::getStepVector(Value *Val, Value *StartIdx,
8040-
Value *Step,
8041-
Instruction::BinaryOps BinOp) {
8042-
// When unrolling and the VF is 1, we only need to add a simple scalar.
8043-
Type *Ty = Val->getType();
8044-
assert(!Ty->isVectorTy() && "Val must be a scalar");
8045-
8046-
if (Ty->isFloatingPointTy()) {
8047-
// Floating-point operations inherit FMF via the builder's flags.
8048-
Value *MulOp = Builder.CreateFMul(StartIdx, Step);
8049-
return Builder.CreateBinOp(BinOp, Val, MulOp);
8050-
}
8051-
return Builder.CreateAdd(Val, Builder.CreateMul(StartIdx, Step), "induction");
8052-
}
8053-
80548047
static void AddRuntimeUnrollDisableMetaData(Loop *L) {
80558048
SmallVector<Metadata *, 4> MDs;
80568049
// Reserve first location for self reference to the LoopID metadata node.

0 commit comments

Comments
 (0)