Skip to content

Commit 06d7ea2

Browse files
committed
[VPlan] Add verifier check for EVL, introduce m_SpecificSInt
1 parent 09a9de9 commit 06d7ea2

File tree

6 files changed

+71
-26
lines changed

6 files changed

+71
-26
lines changed

llvm/include/llvm/ADT/APInt.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,18 @@ class [[nodiscard]] APInt {
561561
return I1.zext(I2.getBitWidth()) == I2;
562562
}
563563

564+
/// Determine if two APInts have the same value, after sign-extending
565+
/// one of them (if needed!) to ensure that the bit-widths match.
566+
static bool isSameSignedValue(const APInt &I1, const APInt &I2) {
567+
if (I1.getBitWidth() == I2.getBitWidth())
568+
return I1 == I2;
569+
570+
if (I1.getBitWidth() > I2.getBitWidth())
571+
return I1 == I2.sext(I1.getBitWidth());
572+
573+
return I1.sext(I2.getBitWidth()) == I2;
574+
}
575+
564576
/// Overload to compute a hash_code for an APInt value.
565577
LLVM_ABI friend hash_code hash_value(const APInt &Arg);
566578

llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ class VPBuilder {
7878
setInsertPoint(TheBB, IP);
7979
}
8080

81-
VPlan &getPlan() const { return *getInsertBlock()->getPlan(); }
81+
VPlan &getPlan() const {
82+
assert(getInsertBlock() && "Expected insert point to be set");
83+
return *getInsertBlock()->getPlan();
84+
}
8285

8386
/// Clear the insertion point: created instructions will not be inserted into
8487
/// a block.
@@ -355,9 +358,8 @@ class VPBuilder {
355358
FPBinOp ? FPBinOp->getFastMathFlags() : FastMathFlags(), DL));
356359
}
357360

358-
/// Create and insert a VectorEndPointerRecipe, with an optional \p
359-
/// VFReplacement parameter, which is used in place of the VF recipe: useful
360-
/// when there is an EVL recipe instead.
361+
/// Create and insert a VectorEndPointerRecipe: requires insert-point to be
362+
/// set.
361363
VPVectorEndPointerRecipe *
362364
createVectorEndPointerRecipe(VPValue *Ptr, Type *SourceElementType,
363365
int64_t Stride, GEPNoWrapFlags GEPFlags,

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8313,7 +8313,7 @@ VPRecipeBuilder::tryToCreatePartialReduction(VPInstruction *Reduction,
83138313
}
83148314

83158315
VPVectorEndPointerRecipe *
8316-
VPBuilder::createVectorEndPointerRecipe(VPValue *Ptr, Type *SourceElementType,
8316+
VPBuilder::createVectorEndPointerRecipe(VPValue *Ptr, Type *SourceElementTy,
83178317
int64_t Stride, GEPNoWrapFlags GEPFlags,
83188318
VPValue *VF, DebugLoc DbgLoc) {
83198319
// Offset for Part 0 = Stride * (VF - 1).
@@ -8325,14 +8325,14 @@ VPBuilder::createVectorEndPointerRecipe(VPValue *Ptr, Type *SourceElementType,
83258325
Type *VFTy = TypeInfo.inferScalarType(VF);
83268326
VPValue *VFCast =
83278327
createScalarZExtOrTrunc(VF, IndexTy, VFTy, DebugLoc::getUnknown());
8328-
VPValue *VFMinusOne = createOverflowingOp(
8328+
VPInstruction *VFMinusOne = createOverflowingOp(
83298329
Instruction::Sub, {VFCast, Plan.getConstantInt(IndexTy, 1u)},
83308330
{true, true});
8331-
VPValue *StridexVFMinusOne = createOverflowingOp(
8331+
VPInstruction *StridexVFMinusOne = createOverflowingOp(
83328332
Instruction::Mul,
83338333
{VFMinusOne, Plan.getConstantInt(IndexTy, Stride, /*IsSigned=*/true)});
83348334
auto *VEPR = tryInsertInstruction(new VPVectorEndPointerRecipe(
8335-
Ptr, StridexVFMinusOne, SourceElementType, Stride, GEPFlags, DbgLoc));
8335+
Ptr, StridexVFMinusOne, SourceElementTy, Stride, GEPFlags, DbgLoc));
83368336
return VEPR;
83378337
}
83388338

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,9 @@ struct deferredval_ty {
9393
/// whichever value m_VPValue(X) populated.
9494
inline deferredval_ty m_Deferred(VPValue *const &V) { return V; }
9595

96-
/// Match an integer constant or vector of constants if Pred::isValue returns
97-
/// true for the APInt. \p BitWidth optionally specifies the bitwidth the
98-
/// matched constant must have. If it is 0, the matched constant can have any
99-
/// bitwidth.
96+
/// Match an integer constant if Pred::isValue returns true for the APInt. \p
97+
/// BitWidth optionally specifies the bitwidth the matched constant must have.
98+
/// If it is 0, the matched constant can have any bitwidth.
10099
template <typename Pred, unsigned BitWidth = 0> struct int_pred_ty {
101100
Pred P;
102101

@@ -117,15 +116,18 @@ template <typename Pred, unsigned BitWidth = 0> struct int_pred_ty {
117116
}
118117
};
119118

120-
/// Match a specified integer value or vector of all elements of that
121-
/// value. \p BitWidth optionally specifies the bitwidth the matched constant
122-
/// must have. If it is 0, the matched constant can have any bitwidth.
119+
/// Match a specified signed or unsigned integer value.
123120
struct is_specific_int {
124121
APInt Val;
122+
bool IsSigned;
125123

126-
is_specific_int(APInt Val) : Val(std::move(Val)) {}
124+
is_specific_int(APInt Val, bool IsSigned = false)
125+
: Val(std::move(Val)), IsSigned(IsSigned) {}
127126

128-
bool isValue(const APInt &C) const { return APInt::isSameValue(Val, C); }
127+
bool isValue(const APInt &C) const {
128+
return IsSigned ? APInt::isSameSignedValue(Val, C)
129+
: APInt::isSameValue(Val, C);
130+
}
129131
};
130132

131133
template <unsigned Bitwidth = 0>
@@ -135,6 +137,11 @@ inline specific_intval<0> m_SpecificInt(uint64_t V) {
135137
return specific_intval<0>(is_specific_int(APInt(64, V)));
136138
}
137139

140+
inline specific_intval<0> m_SpecificSInt(int64_t V) {
141+
return specific_intval<0>(
142+
is_specific_int(APInt(64, V, /*isSigned=*/true), /*IsSigned=*/true));
143+
}
144+
138145
inline specific_intval<1> m_False() {
139146
return specific_intval<1>(is_specific_int(APInt(64, 0)));
140147
}

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2931,11 +2931,11 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
29312931
VEPR->getGEPNoWrapFlags(), &EVL, VEPR->getDebugLoc());
29322932
};
29332933

2934-
auto m_VecEndPtrVF = [&Plan](VPValue *&Addr) { // NOLINT
2934+
auto m_VecEndPtrVF = [&Plan](VPValue *&Addr, int64_t Stride) { // NOLINT
29352935
return m_VecEndPtr(
29362936
m_VPValue(Addr),
29372937
m_c_Mul(
2938-
m_VPValue(),
2938+
m_SpecificSInt(Stride),
29392939
m_Sub(m_ZExtOrTruncOrSelf(m_Specific(&Plan->getVF())), m_One())));
29402940
};
29412941

@@ -2949,7 +2949,10 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
29492949
if (match(&CurRecipe, m_Reverse(m_VPValue(ReversedVal))) &&
29502950
match(ReversedVal,
29512951
m_MaskedLoad(m_VPValue(EndPtr), m_RemoveMask(HeaderMask, Mask))) &&
2952-
match(EndPtr, m_VecEndPtrVF(Addr)) &&
2952+
isa<VPVectorEndPointerRecipe>(EndPtr) &&
2953+
match(EndPtr,
2954+
m_VecEndPtrVF(
2955+
Addr, cast<VPVectorEndPointerRecipe>(EndPtr)->getStride())) &&
29532956
cast<VPWidenLoadRecipe>(ReversedVal)->isReverse()) {
29542957
auto *LoadR = new VPWidenLoadEVLRecipe(
29552958
*cast<VPWidenLoadRecipe>(ReversedVal), AdjustEndPtr(EndPtr), EVL, Mask);
@@ -2969,7 +2972,10 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
29692972
if (match(&CurRecipe,
29702973
m_MaskedStore(m_VPValue(EndPtr), m_Reverse(m_VPValue(ReversedVal)),
29712974
m_RemoveMask(HeaderMask, Mask))) &&
2972-
match(EndPtr, m_VecEndPtrVF(Addr)) &&
2975+
isa<VPVectorEndPointerRecipe>(EndPtr) &&
2976+
match(EndPtr,
2977+
m_VecEndPtrVF(
2978+
Addr, cast<VPVectorEndPointerRecipe>(EndPtr)->getStride())) &&
29732979
cast<VPWidenStoreRecipe>(CurRecipe).isReverse()) {
29742980
auto *NewReverse = new VPWidenIntrinsicRecipe(
29752981
Intrinsic::experimental_vp_reverse,
@@ -3557,10 +3563,9 @@ void VPlanTransforms::createInterleaveGroups(
35573563
// the pointer operand of the interleaved access is supposed to be uniform.
35583564
if (IG->isReverse()) {
35593565
B.setInsertPoint(InsertPos);
3560-
auto *ReversePtr = B.createVectorEndPointerRecipe(
3566+
Addr = B.createVectorEndPointerRecipe(
35613567
Addr, getLoadStoreType(IRInsertPos), -(int64_t)IG->getFactor(), NW,
35623568
&Plan.getVF(), InsertPos->getDebugLoc());
3563-
Addr = ReversePtr;
35643569
}
35653570
auto *VPIG = new VPInterleaveRecipe(IG, Addr, StoredValues,
35663571
InsertPos->getMask(), NeedsMaskForGaps,

llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,17 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
156156
}
157157
return true;
158158
};
159-
return all_of(EVL.users(), [this, &VerifyEVLUse](VPUser *U) {
159+
auto VerifyEVLUseInVecEndPtr = [&EVL](auto &VEPRs) {
160+
if (all_of(VEPRs, [&EVL](VPUser *U) {
161+
auto *VEPR = cast<VPVectorEndPointerRecipe>(U);
162+
return match(VEPR->getOffset(),
163+
m_c_Mul(m_VPValue(), m_Sub(m_Specific(&EVL), m_One())));
164+
}))
165+
return true;
166+
errs() << "Expected VectorEndPointer with EVL operand\n";
167+
return false;
168+
};
169+
return all_of(EVL.users(), [&](VPUser *U) {
160170
return TypeSwitch<const VPUser *, bool>(U)
161171
.Case<VPWidenIntrinsicRecipe>([&](const VPWidenIntrinsicRecipe *S) {
162172
return VerifyEVLUse(*S, S->getNumOperands() - 1);
@@ -179,8 +189,17 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
179189
if (I->getOpcode() == Instruction::PHI ||
180190
I->getOpcode() == Instruction::ICmp)
181191
return VerifyEVLUse(*I, 1);
182-
if (I->getOpcode() == Instruction::Sub)
183-
return true;
192+
if (I->getOpcode() == Instruction::Sub) {
193+
auto *VPI =
194+
dyn_cast_if_present<VPSingleDefRecipe>(I->getSingleUser());
195+
if (VPI) {
196+
auto VEPRs = make_filter_range(VPI->users(),
197+
IsaPred<VPVectorEndPointerRecipe>);
198+
if (!VEPRs.empty())
199+
return VerifyEVLUseInVecEndPtr(VEPRs);
200+
}
201+
return VerifyEVLUse(*I, 1);
202+
}
184203
switch (I->getOpcode()) {
185204
case Instruction::Add:
186205
break;

0 commit comments

Comments
 (0)