[clang] [flang] [clang-tools-extra] [compiler-rt] [llvm] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 26 03:34:27 PST 2024


================
@@ -8292,13 +8271,13 @@ VPRecipeOrVPValueTy VPRecipeBuilder::tryToBlend(PHINode *Phi,
   for (unsigned In = 0; In < NumIncoming; In++) {
     VPValue *EdgeMask =
         createEdgeMask(Phi->getIncomingBlock(In), Phi->getParent(), *Plan);
-    assert((EdgeMask || NumIncoming == 1) &&
+    assert((EdgeMask || NumIncoming == 1 || Operands[In] == Operands[0]) &&
----------------
ayalz wrote:

Ah, right. This empty edge-mask case is a bit subtle.

Blend recipe expects an even number of operands, referring to them as {incoming-value, non-null edge-mask} pairs, or else a single operand, referring to it as an incoming-value.

An empty edge-mask is formed when its predecessor has an empty block-mask and a single successor or two identical successors, as in the above degenerate example. In the latter case, however, OperandsWithMask will contain two entries, both being (the same) incoming-values, as their edge-masks are both null. Note that three or more incoming-values must (all) have non-null edge-masks, otherwise they must post/dominate each other.

So maybe clearer to have something like:
```
  for (unsigned In = 0; In < NumIncoming; In++) {
    OperandsWithMask.push_back(Operands[In]);
    VPValue *EdgeMask =
        createEdgeMask(Phi->getIncomingBlock(In), Phi->getParent(), *Plan);
    if (!EdgeMask) {
      assert(In == 0 && "Both null and non-null edge masks found");
      assert(llvm::all_equal(Operands) && "Distinct incoming values with one having a full mask");
      break;
    }
    OperandsWithMask.push_back(EdgeMask);
  }
```

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


More information about the cfe-commits mailing list