Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[VPlan] Verify dominance for incoming values of phi-like recipes. #124838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

fhahn
Copy link
Contributor

@fhahn fhahn commented Jan 28, 2025

Update the verifier to verify dominance for incoming values for phi-like recipes. The defining recipe must dominate the incoming block for the incoming value.

There are 4 different cases to consider when retrieving the incoming block:

  • VPIRInstructions wrapping phis: the incoming block from the blocks predecessors has the same index as the incoming value operand.
  • VPHeaderPhiRecipes, VPWidenPhi used in header: there's no predecessors; if the incoming value is the start value use the predecessor of the containing region, otherwise the exiting block of the region
  • 1 predecessor: Must be a VPWidenPHI used as LCSSA phi; use the predecessor
  • 2 predecessors: must be a VPPredInstPhiRecipe, use the second predecessor.

@llvmbot
Copy link
Member

llvmbot commented Jan 28, 2025

@llvm/pr-subscribers-vectorizers

Author: Florian Hahn (fhahn)

Changes

Update the verifier to verify dominance for incoming values for phi-like recipes. The defining recipe must dominate the incoming block for the incoming value.

There are 4 different cases to consider when retrieving the incoming block:

  • VPIRInstructions wrapping phis: the incoming block from the blocks predecessors has the same index as the incoming value operand.
  • VPHeaderPhiRecipes, VPWidenPhi used in header: there's no predecessors; if the incoming value is the start value use the predecessor of the containing region, otherwise the exiting block of the region
  • 1 predecessor: Must be a VPWidenPHI used as LCSSA phi; use the predecessor
  • 2 predecessors: must be a VPPredInstPhiRecipe, use the second predecessor.

Full diff: https://github.com/llvm/llvm-project/pull/124838.diff

1 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp (+53-5)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
index 0f151c897d938e..0948452e8d19cf 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
@@ -175,6 +175,11 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
   });
 }
 
+/// Return true if \p R is a VPIRInstruction wrapping a phi.
+static bool isVPIRInstructionPhi(const VPRecipeBase &R) {
+  auto *VPIRI = dyn_cast<VPIRInstruction>(&R);
+  return VPIRI && isa<PHINode>(VPIRI->getInstruction());
+}
 bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
   if (!verifyPhiRecipes(VPBB))
     return false;
@@ -207,14 +212,57 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
 
       for (const VPUser *U : V->users()) {
         auto *UI = cast<VPRecipeBase>(U);
-        // TODO: check dominance of incoming values for phis properly.
-        if (!UI ||
-            isa<VPHeaderPHIRecipe, VPWidenPHIRecipe, VPPredInstPHIRecipe>(UI))
+        const VPBlockBase *UserVPBB = UI->getParent();
+
+        // Verify incoming values of VPIRInstructions wrapping phis. V most
+        // dominate the end of the incoming block. The operand index of the
+        // incoming value matches the predecessor block index of the
+        // corresponding incoming block.
+        if (isVPIRInstructionPhi(*UI)) {
+          for (const auto &[Idx, Op] : enumerate(UI->operands())) {
+            if (V != Op)
+              continue;
+            const VPBlockBase *Incoming = UserVPBB->getPredecessors()[Idx];
+            if (Incoming != VPBB && !VPDT.dominates(VPBB, Incoming)) {
+              errs() << "Use before def!\n";
+              return false;
+            }
+          }
           continue;
+        }
+        // Verify incoming value of various phi-like recipes.
+        if (isa<VPWidenPHIRecipe, VPHeaderPHIRecipe, VPPredInstPHIRecipe>(UI)) {
+          const VPBlockBase *Incoming = nullptr;
+          // Get the incoming block based on the number of predecessors.
+          if (UserVPBB->getNumPredecessors() == 0) {
+            assert((isa<VPWidenPHIRecipe>(UI) || isa<VPHeaderPHIRecipe>(UI)) &&
+                   "Unexpected recipe with 0 predecessors");
+            const VPRegionBlock *UserRegion = UserVPBB->getParent();
+            Incoming = V == UI->getOperand(0)
+                           ? UserRegion->getSinglePredecessor()
+                           : UserRegion->getExiting();
+          } else if (UserVPBB->getNumPredecessors() == 1) {
+            assert(isa<VPWidenPHIRecipe>(UI) &&
+                   "Unexpected recipe with 1 predecessors");
+            Incoming = UserVPBB->getSinglePredecessor();
+          } else {
+            assert(UserVPBB->getNumPredecessors() == 2 &&
+                   isa<VPPredInstPHIRecipe>(UI) &&
+                   "Unexpected recipe with 2 or more predecessors");
+            Incoming = UserVPBB->getPredecessors()[1];
+          }
+          if (auto *R = dyn_cast<VPRegionBlock>(Incoming))
+            Incoming = R->getExiting();
+          if (Incoming != VPBB && !VPDT.dominates(VPBB, Incoming)) {
+            errs() << "Use before def!\n";
+            return false;
+          }
+          continue;
+        }
 
         // If the user is in the same block, check it comes after R in the
         // block.
-        if (UI->getParent() == VPBB) {
+        if (UserVPBB == VPBB) {
           if (RecipeNumbering[UI] < RecipeNumbering[&R]) {
             errs() << "Use before def!\n";
             return false;
@@ -222,7 +270,7 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
           continue;
         }
 
-        if (!VPDT.dominates(VPBB, UI->getParent())) {
+        if (!VPDT.dominates(VPBB, UserVPBB)) {
           errs() << "Use before def!\n";
           return false;
         }

@llvmbot
Copy link
Member

llvmbot commented Jan 28, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Florian Hahn (fhahn)

Changes

Update the verifier to verify dominance for incoming values for phi-like recipes. The defining recipe must dominate the incoming block for the incoming value.

There are 4 different cases to consider when retrieving the incoming block:

  • VPIRInstructions wrapping phis: the incoming block from the blocks predecessors has the same index as the incoming value operand.
  • VPHeaderPhiRecipes, VPWidenPhi used in header: there's no predecessors; if the incoming value is the start value use the predecessor of the containing region, otherwise the exiting block of the region
  • 1 predecessor: Must be a VPWidenPHI used as LCSSA phi; use the predecessor
  • 2 predecessors: must be a VPPredInstPhiRecipe, use the second predecessor.

Full diff: https://github.com/llvm/llvm-project/pull/124838.diff

1 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp (+53-5)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
index 0f151c897d938e..0948452e8d19cf 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
@@ -175,6 +175,11 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
   });
 }
 
+/// Return true if \p R is a VPIRInstruction wrapping a phi.
+static bool isVPIRInstructionPhi(const VPRecipeBase &R) {
+  auto *VPIRI = dyn_cast<VPIRInstruction>(&R);
+  return VPIRI && isa<PHINode>(VPIRI->getInstruction());
+}
 bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
   if (!verifyPhiRecipes(VPBB))
     return false;
@@ -207,14 +212,57 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
 
       for (const VPUser *U : V->users()) {
         auto *UI = cast<VPRecipeBase>(U);
-        // TODO: check dominance of incoming values for phis properly.
-        if (!UI ||
-            isa<VPHeaderPHIRecipe, VPWidenPHIRecipe, VPPredInstPHIRecipe>(UI))
+        const VPBlockBase *UserVPBB = UI->getParent();
+
+        // Verify incoming values of VPIRInstructions wrapping phis. V most
+        // dominate the end of the incoming block. The operand index of the
+        // incoming value matches the predecessor block index of the
+        // corresponding incoming block.
+        if (isVPIRInstructionPhi(*UI)) {
+          for (const auto &[Idx, Op] : enumerate(UI->operands())) {
+            if (V != Op)
+              continue;
+            const VPBlockBase *Incoming = UserVPBB->getPredecessors()[Idx];
+            if (Incoming != VPBB && !VPDT.dominates(VPBB, Incoming)) {
+              errs() << "Use before def!\n";
+              return false;
+            }
+          }
           continue;
+        }
+        // Verify incoming value of various phi-like recipes.
+        if (isa<VPWidenPHIRecipe, VPHeaderPHIRecipe, VPPredInstPHIRecipe>(UI)) {
+          const VPBlockBase *Incoming = nullptr;
+          // Get the incoming block based on the number of predecessors.
+          if (UserVPBB->getNumPredecessors() == 0) {
+            assert((isa<VPWidenPHIRecipe>(UI) || isa<VPHeaderPHIRecipe>(UI)) &&
+                   "Unexpected recipe with 0 predecessors");
+            const VPRegionBlock *UserRegion = UserVPBB->getParent();
+            Incoming = V == UI->getOperand(0)
+                           ? UserRegion->getSinglePredecessor()
+                           : UserRegion->getExiting();
+          } else if (UserVPBB->getNumPredecessors() == 1) {
+            assert(isa<VPWidenPHIRecipe>(UI) &&
+                   "Unexpected recipe with 1 predecessors");
+            Incoming = UserVPBB->getSinglePredecessor();
+          } else {
+            assert(UserVPBB->getNumPredecessors() == 2 &&
+                   isa<VPPredInstPHIRecipe>(UI) &&
+                   "Unexpected recipe with 2 or more predecessors");
+            Incoming = UserVPBB->getPredecessors()[1];
+          }
+          if (auto *R = dyn_cast<VPRegionBlock>(Incoming))
+            Incoming = R->getExiting();
+          if (Incoming != VPBB && !VPDT.dominates(VPBB, Incoming)) {
+            errs() << "Use before def!\n";
+            return false;
+          }
+          continue;
+        }
 
         // If the user is in the same block, check it comes after R in the
         // block.
-        if (UI->getParent() == VPBB) {
+        if (UserVPBB == VPBB) {
           if (RecipeNumbering[UI] < RecipeNumbering[&R]) {
             errs() << "Use before def!\n";
             return false;
@@ -222,7 +270,7 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
           continue;
         }
 
-        if (!VPDT.dominates(VPBB, UI->getParent())) {
+        if (!VPDT.dominates(VPBB, UserVPBB)) {
           errs() << "Use before def!\n";
           return false;
         }

Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

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

Thanks for this - looks sensible to me. I just had a couple of comments.

static bool isVPIRInstructionPhi(const VPRecipeBase &R) {
auto *VPIRI = dyn_cast<VPIRInstruction>(&R);
return VPIRI && isa<PHINode>(VPIRI->getInstruction());
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Add new line after function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adde a newline, thanks

"Unexpected recipe with 2 or more predecessors");
Incoming = UserVPBB->getPredecessors()[1];
}
if (auto *R = dyn_cast<VPRegionBlock>(Incoming))
Copy link
Contributor

Choose a reason for hiding this comment

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

Just out of curiosity, what's the scenario where the incoming block for a VPWidenPHIRecipe, VPHeaderPHIRecipe or VPPredInstPHIRecipe recipe would be the region? Is it the recipes we create in the middle block? If so, could this check potentially fail with uncountable early exits, i.e. the incoming block is effectively the middle.split block? I assume it's fine, but just wondering if there are missing tests for all the scenarios.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only case at the moment is in VPWidenPHIRecipes added in the VPlan-native path. I added an assert; it cannot happen in the inner-loop vectorizer path.

@fhahn fhahn force-pushed the vplan-verify-def-use-phi branch from 29aa9b0 to 695ef3c Compare January 29, 2025 20:47
@fhahn fhahn force-pushed the vplan-verify-def-use-phi branch from 695ef3c to 129e8ad Compare February 15, 2025 21:16
Copy link
Contributor Author

@fhahn fhahn left a comment

Choose a reason for hiding this comment

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

ping :)

Copy link
Collaborator

@ayalz ayalz left a comment

Choose a reason for hiding this comment

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

Good to see this TODO being addressed, adding various comments.

@@ -207,24 +213,69 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {

for (const VPUser *U : V->users()) {
auto *UI = cast<VPRecipeBase>(U);
Copy link
Collaborator

Choose a reason for hiding this comment

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

unrelated nit:

Suggested change
auto *UI = cast<VPRecipeBase>(U);
auto *UR = cast<VPRecipeBase>(U);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix independently.

isa<PHINode>(cast<VPIRInstruction>(UI)->getInstruction())))
const VPBlockBase *UserVPBB = UI->getParent();

// Verify incoming values of VPIRInstructions wrapping phis. V most
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// Verify incoming values of VPIRInstructions wrapping phis. V most
// Verify incoming values of VPIRInstructions wrapping phis. V must

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed, thanks


// Verify incoming values of VPIRInstructions wrapping phis. V most
// dominate the end of the incoming block. The operand index of the
// incoming value matches the predecessor block index of the
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// incoming value matches the predecessor block index of the
// incoming value must match the predecessor block index of the

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done thanks!

// incoming value matches the predecessor block index of the
// corresponding incoming block.
if (isVPIRInstructionPhi(*UI)) {
for (const auto &[Idx, Op] : enumerate(UI->operands())) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
for (const auto &[Idx, Op] : enumerate(UI->operands())) {
for (const auto &[Index, OpAtIndex] : enumerate(UI->operands())) {

for (const auto &[Idx, Op] : enumerate(UI->operands())) {
if (V != Op)
continue;
const VPBlockBase *Incoming = UserVPBB->getPredecessors()[Idx];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const VPBlockBase *Incoming = UserVPBB->getPredecessors()[Idx];
const VPBlockBase *PredAtIndex = UserVPBB->getPredecessors()[Idx];

Comment on lines 235 to 237
if (isa<VPWidenPHIRecipe, VPHeaderPHIRecipe, VPPredInstPHIRecipe>(UI)) {
const VPBlockBase *Incoming = nullptr;
// Get the incoming block based on the number of predecessors.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: better switch over the types of recipes involved, asserting the number of predecessors, than vice-versa? Nearly every recipe seems to be doing its own thing anyhow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Code has been replaced by type-switch and using incoming values/blocks iterator.

"Unexpected recipe with 2 or more predecessors");
Incoming = UserVPBB->getPredecessors()[1];
}
if (auto *R = dyn_cast<VPRegionBlock>(Incoming)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if (auto *R = dyn_cast<VPRegionBlock>(Incoming)) {
if (auto *IncomingRegion = dyn_cast<VPRegionBlock>(Incoming)) {

to avoid confusion with R which is also being used for the current Recipe.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Code is gone in latest version

"VPWidenPHIRecipe");
Incoming = R->getExiting();
}
if (Incoming != VPBB && !VPDT.dominates(VPBB, Incoming)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same comment as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Code is gone in latest version

// dominate the end of the incoming block. The operand index of the
// incoming value matches the predecessor block index of the
// corresponding incoming block.
if (isVPIRInstructionPhi(*UI)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can the case of VPIRInstruction be handled along with all other phi recipes below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are cases where the block containing a VPIR Phi has multiple predecessors (some cases with early exits), for those we need the proper phi-handling

return false;
}
continue;
}

// If the user is in the same block, check it comes after R in the
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// If the user is in the same block, check it comes after R in the
// If the user is in the same block, check that it comes after R in the

fhahn added a commit to fhahn/llvm-project that referenced this pull request Mar 1, 2025
Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks, with corresponding iterators.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying llvm#124838.
Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks, with corresponding iterators.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying llvm#124838.
Copy link
Contributor Author

@fhahn fhahn left a comment

Choose a reason for hiding this comment

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

I reworked the PR quite a bit and it is now building on a few additional patches:

auto *VPIRI = dyn_cast<VPIRInstruction>(&R);
return VPIRI && isa<PHINode>(VPIRI->getInstruction());
}

bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
if (!verifyPhiRecipes(VPBB))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure how we could move the new code to verifyPhiRecipes, as here we verify def before use property looking at the uses of a defined VPValue and when looking at the uses we need to handle phi-like recipes.

@@ -175,6 +175,12 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
});
}

/// Return true if \p R is a VPIRInstruction wrapping a phi.
static bool isVPIRInstructionPhi(const VPRecipeBase &R) {
auto *VPIRI = dyn_cast<VPIRInstruction>(&R);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will check separately, thanks!

auto *VPIRI = dyn_cast<VPIRInstruction>(&R);
return VPIRI && isa<PHINode>(VPIRI->getInstruction());
}

bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
if (!verifyPhiRecipes(VPBB))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should be complete now, updated, thanks!

@@ -207,24 +213,69 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {

for (const VPUser *U : V->users()) {
auto *UI = cast<VPRecipeBase>(U);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix independently.

isa<PHINode>(cast<VPIRInstruction>(UI)->getInstruction())))
const VPBlockBase *UserVPBB = UI->getParent();

// Verify incoming values of VPIRInstructions wrapping phis. V most
Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed, thanks


// Verify incoming values of VPIRInstructions wrapping phis. V most
// dominate the end of the incoming block. The operand index of the
// incoming value matches the predecessor block index of the
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done thanks!

// dominate the end of the incoming block. The operand index of the
// incoming value matches the predecessor block index of the
// corresponding incoming block.
if (isVPIRInstructionPhi(*UI)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are cases where the block containing a VPIR Phi has multiple predecessors (some cases with early exits), for those we need the proper phi-handling

Copy link

github-actions bot commented Mar 1, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

fhahn added a commit to fhahn/llvm-project that referenced this pull request Mar 12, 2025
Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks, with corresponding iterators.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying llvm#124838.
fhahn added 2 commits May 3, 2025 10:52
@fhahn fhahn force-pushed the vplan-verify-def-use-phi branch from bbd3712 to 5fee077 Compare May 3, 2025 09:58
fhahn added a commit that referenced this pull request May 4, 2025
…#129388)

Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying #124838.

PR: #129388
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…llvm#129388)

Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying llvm#124838.

PR: llvm#129388
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…llvm#129388)

Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying llvm#124838.

PR: llvm#129388
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…llvm#129388)

Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying llvm#124838.

PR: llvm#129388
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request May 6, 2025
…cipes (NFC) (#129388)

Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying llvm/llvm-project#124838.

PR: llvm/llvm-project#129388
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
…llvm#129388)

Add a VPPhiAccessors class to provide interfaces to access incoming
values and blocks.

The first user is VPWidenPhiRecipe, with the other phi-like recipes
following soon.

This will also be used to verify def-use chains where users are phi-like
recipes, simplifying llvm#124838.

PR: llvm#129388
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants