Skip to content
Open
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
26 changes: 5 additions & 21 deletions llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,19 +189,7 @@ static bool sinkScalarOperands(VPlan &Plan) {
if (NeedsDuplicating) {
if (ScalarVFOnly)
continue;
VPSingleDefRecipe *Clone;
if (auto *SinkCandidateRepR =
dyn_cast<VPReplicateRecipe>(SinkCandidate)) {
// TODO: Handle converting to uniform recipes as separate transform,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to keep the TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps not? I think we wanted to address it sometime in the past, but I don't think it's the case any longer?

// then cloning should be sufficient here.
Instruction *I = SinkCandidate->getUnderlyingInstr();
Clone = new VPReplicateRecipe(I, SinkCandidate->operands(), true,
nullptr /*Mask*/, *SinkCandidateRepR);
// TODO: add ".cloned" suffix to name of Clone's VPValue.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding the TODO to getSingleScalarClone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth noting that the constructor doesn't accept a Name field, so I'm not sure if we're going to resolve this: kept it for now.

} else {
Clone = SinkCandidate->clone();
}

VPSingleDefRecipe *Clone = vputils::getSingleScalarClone(SinkCandidate);
Clone->insertBefore(SinkCandidate);
SinkCandidate->replaceUsesWithIf(Clone, [SinkTo](VPUser &U, unsigned) {
return cast<VPRecipeBase>(&U)->getParent() != SinkTo;
Expand Down Expand Up @@ -667,8 +655,7 @@ static void legalizeAndOptimizeInductions(VPlan &Plan) {
if (!vputils::isSingleScalar(Def) && !vputils::onlyFirstLaneUsed(Def))
continue;

auto *Clone = new VPReplicateRecipe(Def->getUnderlyingInstr(),
Def->operands(), /*IsUniform*/ true);
VPSingleDefRecipe *Clone = vputils::getSingleScalarClone(Def);
Clone->insertAfter(Def);
Def->replaceAllUsesWith(Clone);
}
Expand Down Expand Up @@ -1335,9 +1322,8 @@ static void narrowToSingleScalarRecipes(VPlan &Plan) {
auto *RepOrWidenR = cast<VPSingleDefRecipe>(&R);
if (RepR && isa<StoreInst>(RepR->getUnderlyingInstr()) &&
vputils::isSingleScalar(RepR->getOperand(1))) {
auto *Clone = new VPReplicateRecipe(
RepOrWidenR->getUnderlyingInstr(), RepOrWidenR->operands(),
true /*IsSingleScalar*/, nullptr /*Mask*/, *RepR /*Metadata*/);
auto *Clone =
cast<VPReplicateRecipe>(vputils::getSingleScalarClone(RepOrWidenR));
Clone->insertBefore(RepOrWidenR);
unsigned ExtractOpc =
vputils::isUniformAcrossVFsAndUFs(RepR->getOperand(1))
Expand All @@ -1362,9 +1348,7 @@ static void narrowToSingleScalarRecipes(VPlan &Plan) {
}))
continue;

auto *Clone = new VPReplicateRecipe(RepOrWidenR->getUnderlyingInstr(),
RepOrWidenR->operands(),
true /*IsSingleScalar*/);
VPSingleDefRecipe *Clone = vputils::getSingleScalarClone(RepOrWidenR);
Clone->insertBefore(RepOrWidenR);
RepOrWidenR->replaceAllUsesWith(Clone);
}
Expand Down
22 changes: 22 additions & 0 deletions llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,25 @@ vputils::getRecipesForUncountableExit(VPlan &Plan,

return UncountableCondition;
}

VPSingleDefRecipe *vputils::getSingleScalarClone(VPSingleDefRecipe *R) {
// TODO: add ".cloned" suffix to name of Clone's VPValue.
return TypeSwitch<VPSingleDefRecipe *, VPSingleDefRecipe *>(R)
.Case<VPInstruction, VPWidenRecipe, VPWidenSelectRecipe,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about all the other VPSingleDefRecipe types, i.e. VPWidenPHIRecipe, VPBlendRecipe, VPExpressionRecipe, VPWidenCanonicalIVRecipe, etc? I'm a bit nervous that we might be missing some cases here. Have you tried running the LLVM test suite to catch any missing cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fine for the moment, as all the uses in the use-sites are covered: when we add more recipes to handle in the use-sites, we should update this (follow-ups planned).

VPWidenCallRecipe, VPReplicateRecipe>([](auto *I) {
return new VPReplicateRecipe(I->getUnderlyingInstr(), I->operands(),
/*IsSingleScalar*/ true,
/*Mask*/ nullptr,
/*Metadata*/ *I);
})
.Case<VPWidenGEPRecipe>([](auto *I) {
// WidenGEP does not have metadata.
return new VPReplicateRecipe(I->getUnderlyingInstr(), I->operands(),
/*IsSingleScalar*/ true, /*Mask*/ nullptr);
})
.Case<VPScalarIVStepsRecipe>([](auto *I) { return I->clone(); })
.Default([](auto *I) {
llvm_unreachable("Don't know how to convert to single-scalar");
return nullptr;
});
}
4 changes: 4 additions & 0 deletions llvm/lib/Transforms/Vectorize/VPlanUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ std::optional<VPValue *>
getRecipesForUncountableExit(VPlan &Plan,
SmallVectorImpl<VPRecipeBase *> &Recipes,
SmallVectorImpl<VPRecipeBase *> &GEPs);

/// Returns a single-scalar version of \p R, creating a fresh single-scalar
/// VPReplicateRecipe or just cloning the recipe.
VPSingleDefRecipe *getSingleScalarClone(VPSingleDefRecipe *R);
} // namespace vputils

//===----------------------------------------------------------------------===//
Expand Down