[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