Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LV][EVL]Support reversed loads/stores. #88025

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 39 additions & 21 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1571,13 +1571,7 @@ class LoopVectorizationCostModel {
/// Returns true if VP intrinsics with explicit vector length support should
/// be generated in the tail folded loop.
bool foldTailWithEVL() const {
return getTailFoldingStyle() == TailFoldingStyle::DataWithEVL &&
// FIXME: remove this once vp_reverse is supported.
none_of(
WideningDecisions,
[](const std::pair<std::pair<Instruction *, ElementCount>,
std::pair<InstWidening, InstructionCost>>
&Data) { return Data.second.first == CM_Widen_Reverse; });
return getTailFoldingStyle() == TailFoldingStyle::DataWithEVL;
}

/// Returns true if the Phi is part of an inloop reduction.
Expand Down Expand Up @@ -9383,12 +9377,18 @@ void VPWidenLoadRecipe::execute(VPTransformState &State) {
}
}

static Instruction *createReverseEVL(IRBuilderBase &Builder, Value *Operand,
alexey-bataev marked this conversation as resolved.
Show resolved Hide resolved
Value *EVL, const Twine &Name) {
VectorType *ValTy = cast<VectorType>(Operand->getType());
Value *AllTrueMask =
Builder.CreateVectorSplat(ValTy->getElementCount(), Builder.getTrue());
return Builder.CreateIntrinsic(ValTy, Intrinsic::experimental_vp_reverse,
{Operand, AllTrueMask, EVL}, nullptr, Name);
}

void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
assert(State.UF == 1 && "Expected only UF == 1 when vectorizing with "
"explicit vector length.");
// FIXME: Support reverse loading after vp_reverse is added.
assert(!isReverse() && "Reverse loads are not implemented yet.");

auto *LI = cast<LoadInst>(&Ingredient);

Type *ScalarDataTy = getLoadStoreType(&Ingredient);
Expand All @@ -9401,9 +9401,15 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
CallInst *NewLI;
Value *EVL = State.get(getEVL(), VPIteration(0, 0));
Value *Addr = State.get(getAddr(), 0, !CreateGather);
Value *Mask = getMask()
? State.get(getMask(), 0)
: Builder.CreateVectorSplat(State.VF, Builder.getTrue());
Value *Mask = nullptr;
if (VPValue *VPMask = getMask()) {
Mask = State.get(VPMask, 0);
if (isReverse())
Mask = createReverseEVL(Builder, Mask, EVL, "vp.reverse.mask");
} else {
Mask = Builder.CreateVectorSplat(State.VF, Builder.getTrue());
}

if (CreateGather) {
NewLI =
Builder.CreateIntrinsic(DataTy, Intrinsic::vp_gather, {Addr, Mask, EVL},
Expand All @@ -9417,7 +9423,13 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
NewLI->addParamAttr(
0, Attribute::getWithAlignment(NewLI->getContext(), Alignment));
State.addMetadata(NewLI, LI);
State.set(this, NewLI, 0);
Instruction *Res = NewLI;
if (isReverse()) {
// Use cheap all-true mask for reverse rather than actual mask, it does not
// affect the result.
alexey-bataev marked this conversation as resolved.
Show resolved Hide resolved
Res = createReverseEVL(Builder, Res, EVL, "vp.reverse");
}
State.set(this, Res, 0);
}

void VPWidenStoreRecipe::execute(VPTransformState &State) {
Expand Down Expand Up @@ -9463,9 +9475,6 @@ void VPWidenStoreRecipe::execute(VPTransformState &State) {
void VPWidenStoreEVLRecipe::execute(VPTransformState &State) {
assert(State.UF == 1 && "Expected only UF == 1 when vectorizing with "
"explicit vector length.");
// FIXME: Support reverse loading after vp_reverse is added.
assert(!isReverse() && "Reverse store are not implemented yet.");

auto *SI = cast<StoreInst>(&Ingredient);

VPValue *StoredValue = getStoredValue();
Expand All @@ -9478,10 +9487,19 @@ void VPWidenStoreEVLRecipe::execute(VPTransformState &State) {
CallInst *NewSI = nullptr;
Value *StoredVal = State.get(StoredValue, 0);
Value *EVL = State.get(getEVL(), VPIteration(0, 0));
// FIXME: Support reverse store after vp_reverse is added.
Value *Mask = getMask()
? State.get(getMask(), 0)
: Builder.CreateVectorSplat(State.VF, Builder.getTrue());
if (isReverse()) {
// Use cheap all-true mask for reverse rather than actual mask, it does not
// affect the result.
alexey-bataev marked this conversation as resolved.
Show resolved Hide resolved
StoredVal = createReverseEVL(Builder, StoredVal, EVL, "vp.reverse");
}
Value *Mask = nullptr;
if (VPValue *VPMask = getMask()) {
Mask = State.get(VPMask, 0);
if (isReverse())
Mask = createReverseEVL(Builder, Mask, EVL, "vp.reverse.mask");
} else {
Mask = Builder.CreateVectorSplat(State.VF, Builder.getTrue());
}
Value *Addr = State.get(getAddr(), 0, !CreateScatter);
if (CreateScatter) {
NewSI = Builder.CreateIntrinsic(Type::getVoidTy(EVL->getContext()),
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Transforms/Vectorize/VPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -2399,8 +2399,8 @@ struct VPWidenLoadRecipe final : public VPWidenMemoryRecipe, public VPValue {
struct VPWidenLoadEVLRecipe final : public VPWidenMemoryRecipe, public VPValue {
VPWidenLoadEVLRecipe(VPWidenLoadRecipe *L, VPValue *EVL, VPValue *Mask)
: VPWidenMemoryRecipe(VPDef::VPWidenLoadEVLSC, L->getIngredient(),
{L->getAddr(), EVL}, L->isConsecutive(), false,
L->getDebugLoc()),
{L->getAddr(), EVL}, L->isConsecutive(),
L->isReverse(), L->getDebugLoc()),
VPValue(this, &getIngredient()) {
setMask(Mask);
}
Expand Down Expand Up @@ -2476,7 +2476,8 @@ struct VPWidenStoreEVLRecipe final : public VPWidenMemoryRecipe {
VPWidenStoreEVLRecipe(VPWidenStoreRecipe *S, VPValue *EVL, VPValue *Mask)
: VPWidenMemoryRecipe(VPDef::VPWidenStoreEVLSC, S->getIngredient(),
{S->getAddr(), S->getStoredValue(), EVL},
S->isConsecutive(), false, S->getDebugLoc()) {
S->isConsecutive(), S->isReverse(),
S->getDebugLoc()) {
setMask(Mask);
}

Expand Down
2 changes: 0 additions & 2 deletions llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1341,8 +1341,6 @@ void VPlanTransforms::addExplicitVectorLength(VPlan &Plan) {
auto *MemR = dyn_cast<VPWidenMemoryRecipe>(U);
if (!MemR)
continue;
assert(!MemR->isReverse() &&
"Reversed memory operations not supported yet.");
VPValue *OrigMask = MemR->getMask();
assert(OrigMask && "Unmasked widen memory recipe when folding tail");
VPValue *NewMask = HeaderMask == OrigMask ? nullptr : OrigMask;
Expand Down
Loading
Loading