[llvm] [VPlan] Compute blend masks from minimum set of edge masks (PR #201783)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 20 00:11:57 PDT 2026


================
@@ -233,6 +246,103 @@ void VPPredicator::createSwitchEdgeMasks(const VPInstruction *SI) {
   setEdgeMask(Src, DefaultDst, DefaultMask);
 }
 
+// Start by keeping track of what edges lead to which value. Then see if any
+// node has the same value for all outgoing edges. If so then propagate that
+// value up to every node it postdominates. E.g:
+//
+//    Entry      Edges =  {C->ɸ : %x, D->ɸ : %x, F->ɸ : %y}
+//    /   \            [C,D,F all outgoing edges equal: go up postdom frontier]
+//   A     B           ~> {A->C : %x, A->D : %x, Entry->B : %y}
+//  / \    |\          [A all outgoing edges equal: go up postdom frontier]
+// C   D   | E         ~> {Entry->A : %x, Entry->B : %y}
+//  \   \  |/
+//   \  |  F
+//    \ | /
+//      ɸ = phi [%x, C], [%x, D], [%y, F]
+MapVector<VPPredicator::EdgeTy, VPValue *>
+VPPredicator::computeBlendEdges(VPPhi *Phi) {
+  MapVector<EdgeTy, VPValue *> Edges;
+
+  // Mark the given edge as providing the value \p V.
+  auto AddEdge = [&Edges](const VPBlockBase *From, const VPBlockBase *To,
+                          VPValue *V) {
+    EdgeTy Edge = {cast<VPBasicBlock>(From), cast<VPBasicBlock>(To)};
+    assert((!Edges.contains(Edge) || Edges.lookup(Edge) == V) &&
+           "Clobbering an edge?");
+    Edges[Edge] = V;
+  };
+
+  for (auto [InVal, InVPBB] : Phi->incoming_values_and_blocks())
+    AddEdge(InVPBB, Phi->getParent(), InVal);
+
+  SetVector<const VPBlockBase *> Worklist(from_range, Phi->incoming_blocks());
+  while (!Worklist.empty()) {
+    auto *VPBB = cast<VPBasicBlock>(Worklist.pop_back_val());
+
+    // Check that all outgoing edges from VPBB have the same value.
+    SmallVector<EdgeTy> OutEdges;
+    for (const VPBlockBase *Succ : VPBB->getSuccessors())
+      OutEdges.emplace_back(VPBB, cast<VPBasicBlock>(Succ));
+    auto OutVals =
+        map_range(OutEdges, [&Edges](EdgeTy E) { return Edges.lookup(E); });
+    VPValue *Common = *OutVals.begin();
+    if (!Common || !all_equal(OutVals))
+      continue;
+
+    // They have the same value: we can move the edges up.
+    for (EdgeTy Edge : OutEdges)
+      Edges.erase(Edge);
+
+    // Iterate up through the post dominance frontier.
+    for (const VPBlockBase *Frontier : VPPDF.find(VPBB)->second) {
----------------
lukel97 wrote:

Done in d8aa8301f5e37c11020b73751c5812d7923401b6, thanks

https://github.com/llvm/llvm-project/pull/201783


More information about the llvm-commits mailing list