[llvm] [VPlan] Implement interleaving as VPlan-to-VPlan transform. (PR #95842)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 19 04:53:50 PDT 2024
================
@@ -60,3 +61,36 @@ bool vputils::isHeaderMask(const VPValue *V, VPlan &Plan) {
return match(V, m_Binary<Instruction::ICmp>(m_VPValue(A), m_VPValue(B))) &&
IsWideCanonicalIV(A) && B == Plan.getOrCreateBackedgeTakenCount();
}
+
+bool vputils::isUniformAcrossVFsAndUFs(VPValue *V) {
+ // Loop invariants are uniform.
+ if (V->isDefinedOutsideVectorRegions())
+ return true;
+
+ VPRecipeBase *R = V->getDefiningRecipe();
+ auto *CanonicalIV = R->getParent()->getPlan()->getCanonicalIV();
+ // Canonical IV chain is uniform.
+ if (V == CanonicalIV || V == CanonicalIV->getBackedgeValue())
+ return true;
+
+ return TypeSwitch<const VPRecipeBase *, bool>(R)
+ .Case<VPDerivedIVRecipe>([](const auto *R) { return true; })
+ .Case<VPReplicateRecipe>([](const auto *R) {
+ // Loads and stores that are uniform across VF lanes are handled by
+ // VPReplicateRecipe.IsUniform. They are also uniform across UF parts if
+ // all their operands are invariant.
+ // TODO: Further relax the restrictions.
+ return R->isUniform() &&
+ (isa<LoadInst, StoreInst>(R->getUnderlyingValue())) &&
+ all_of(R->operands(),
+ [](VPValue *Op) { return isUniformAcrossVFsAndUFs(Op); });
+ })
+ .Case<VPScalarCastRecipe, VPWidenCastRecipe>([](const auto *R) {
+ // A cast is uniform according to its operand.
+ return isUniformAcrossVFsAndUFs(R->getOperand(0));
+ })
+ .Default([](const VPRecipeBase *) { // A values is considered non-uniform
----------------
fhahn wrote:
Fixed, thanks!
https://github.com/llvm/llvm-project/pull/95842
More information about the llvm-commits
mailing list