-
Notifications
You must be signed in to change notification settings - Fork 13k
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
[VPlan] Use VPlan predecessors in VPWidenPHIRecipe (NFC). #126388
Conversation
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-vectorizers Author: Florian Hahn (fhahn) ChangesUpdate VPWidenPHIRecipe to use the predecessors in VPlan to determine the incoming blocks instead of tracking them separately. This brings VPWidenPHIrecipe in line with the other phi recipes. Full diff: https://github.com/llvm/llvm-project/pull/126388.diff 6 Files Affected:
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 3816e1b61576a3d..f2f118f5d2980c1 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -1958,13 +1958,12 @@ class VPScalarPHIRecipe : public VPHeaderPHIRecipe {
#endif
};
-/// A recipe for handling phis that are widened in the vector loop.
-/// In the VPlan native path, all incoming VPValues & VPBasicBlock pairs are
-/// managed in the recipe directly.
+/// A recipe for widened phis. Incoming values are operands of the recipe and
+/// their operand index corresponds to the incoming predeocessor block. If the
+/// recipe is placed in an entry block to a (non-replicate) region, it must have
+/// exactly 2 incoming values, from from the predecessors of the region and one
+/// from the exiting block of the region.
class VPWidenPHIRecipe : public VPSingleDefRecipe {
- /// List of incoming blocks. Only used in the VPlan native path.
- SmallVector<VPBasicBlock *, 2> IncomingBlocks;
-
public:
/// Create a new VPWidenPHIRecipe for \p Phi with start value \p Start and
/// debug location \p DL.
@@ -1991,19 +1990,8 @@ class VPWidenPHIRecipe : public VPSingleDefRecipe {
VPSlotTracker &SlotTracker) const override;
#endif
- /// Adds a pair (\p IncomingV, \p IncomingBlock) to the phi.
- void addIncoming(VPValue *IncomingV, VPBasicBlock *IncomingBlock) {
- addOperand(IncomingV);
- IncomingBlocks.push_back(IncomingBlock);
- }
-
/// Returns the \p I th incoming VPBasicBlock.
- VPBasicBlock *getIncomingBlock(unsigned I) { return IncomingBlocks[I]; }
-
- /// Set the \p I th incoming VPBasicBlock to \p IncomingBlock.
- void setIncomingBlock(unsigned I, VPBasicBlock *IncomingBlock) {
- IncomingBlocks[I] = IncomingBlock;
- }
+ VPBasicBlock *getIncomingBlock(unsigned I);
/// Returns the \p I th incoming VPValue.
VPValue *getIncomingValue(unsigned I) { return getOperand(I); }
diff --git a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
index 5a2e5d7cfee48d0..c94ea35e8112e25 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
@@ -136,19 +136,22 @@ void PlainCFGBuilder::fixPhiNodes() {
// predecessor is the first operand of the recipe.
assert(Phi->getNumOperands() == 2);
BasicBlock *LoopPred = L->getLoopPredecessor();
- VPPhi->addIncoming(
- getOrCreateVPOperand(Phi->getIncomingValueForBlock(LoopPred)),
- BB2VPBB[LoopPred]);
+ VPPhi->addOperand(
+ getOrCreateVPOperand(Phi->getIncomingValueForBlock(LoopPred)));
BasicBlock *LoopLatch = L->getLoopLatch();
- VPPhi->addIncoming(
- getOrCreateVPOperand(Phi->getIncomingValueForBlock(LoopLatch)),
- BB2VPBB[LoopLatch]);
+ VPPhi->addOperand(
+ getOrCreateVPOperand(Phi->getIncomingValueForBlock(LoopLatch)));
continue;
}
- for (unsigned I = 0; I != Phi->getNumOperands(); ++I)
- VPPhi->addIncoming(getOrCreateVPOperand(Phi->getIncomingValue(I)),
- BB2VPBB[Phi->getIncomingBlock(I)]);
+ // Add operands for VPPhi in the order matching its predecessors in VPlan.
+ DenseMap<const VPBasicBlock *, VPValue *> IncomingValues;
+ for (unsigned I = 0; I != Phi->getNumOperands(); ++I) {
+ IncomingValues[BB2VPBB[Phi->getIncomingBlock(I)]] =
+ getOrCreateVPOperand(Phi->getIncomingValue(I));
+ }
+ for (VPBlockBase *Pred : VPPhi->getParent()->getPredecessors())
+ VPPhi->addOperand(IncomingValues.lookup(Pred->getExitingBasicBlock()));
}
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index bc80c5ea0b1b2af..b86b6285fc50183 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -3577,6 +3577,21 @@ void VPReductionPHIRecipe::print(raw_ostream &O, const Twine &Indent,
}
#endif
+VPBasicBlock *VPWidenPHIRecipe::getIncomingBlock(unsigned I) {
+ VPBasicBlock *Parent = getParent();
+ VPBlockBase *Pred = nullptr;
+ if (Parent->getNumPredecessors() == 0) {
+ auto *R = Parent->getParent();
+ assert(R && R->getEntry() == Parent);
+ assert(I < 2);
+ Pred = I == 0 ? R->getSinglePredecessor() : R;
+ } else {
+ Pred = Parent->getPredecessors()[I];
+ }
+
+ return Pred->getExitingBasicBlock();
+}
+
void VPWidenPHIRecipe::execute(VPTransformState &State) {
assert(EnableVPlanNativePath &&
"Non-native vplans are not expected to have VPWidenPHIRecipes.");
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.h b/llvm/lib/Transforms/Vectorize/VPlanUtils.h
index ac5e1978fcfbe00..6ddb88308955f1a 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.h
@@ -169,16 +169,8 @@ class VPBlockUtils {
static void reassociateBlocks(VPBlockBase *Old, VPBlockBase *New) {
for (auto *Pred : to_vector(Old->getPredecessors()))
Pred->replaceSuccessor(Old, New);
- for (auto *Succ : to_vector(Old->getSuccessors())) {
+ for (auto *Succ : to_vector(Old->getSuccessors()))
Succ->replacePredecessor(Old, New);
-
- // Replace any references to Old in widened phi incoming blocks.
- for (auto &R : Succ->getEntryBasicBlock()->phis())
- if (auto *WidenPhiR = dyn_cast<VPWidenPHIRecipe>(&R))
- for (unsigned I = 0; I < WidenPhiR->getNumOperands(); I++)
- if (WidenPhiR->getIncomingBlock(I) == Old)
- WidenPhiR->setIncomingBlock(I, cast<VPBasicBlock>(New));
- }
New->setPredecessors(Old->getPredecessors());
New->setSuccessors(Old->getSuccessors());
Old->clearPredecessors();
diff --git a/llvm/test/Transforms/LoopVectorize/outer-loop-wide-phis.ll b/llvm/test/Transforms/LoopVectorize/outer-loop-wide-phis.ll
index 3f81c0f5c822a2e..c5d2f6acf85b380 100644
--- a/llvm/test/Transforms/LoopVectorize/outer-loop-wide-phis.ll
+++ b/llvm/test/Transforms/LoopVectorize/outer-loop-wide-phis.ll
@@ -134,7 +134,7 @@ define void @wide_phi_2_predecessors_phi_ops_swapped(ptr noalias %A, ptr noalias
; CHECK-NEXT: [[WIDE_MASKED_GATHER:%.*]] = call <4 x i64> @llvm.masked.gather.v4i64.v4p0(<4 x ptr> [[TMP1]], i32 8, <4 x i1> splat (i1 true), <4 x i64> poison)
; CHECK-NEXT: br label %[[INNER_LATCH4]]
; CHECK: [[INNER_LATCH4]]:
-; CHECK-NEXT: [[VEC_PHI5:%.*]] = phi <4 x i64> [ zeroinitializer, %[[INNER_HEADER1]] ], [ [[WIDE_MASKED_GATHER]], %[[THEN3]] ]
+; CHECK-NEXT: [[VEC_PHI5:%.*]] = phi <4 x i64> [ [[WIDE_MASKED_GATHER]], %[[THEN3]] ], [ zeroinitializer, %[[INNER_HEADER1]] ]
; CHECK-NEXT: [[TMP2:%.*]] = add nsw <4 x i64> [[VEC_PHI5]], [[VEC_IND]]
; CHECK-NEXT: [[TMP3]] = add nsw <4 x i64> [[TMP2]], [[VEC_PHI2]]
; CHECK-NEXT: [[TMP4]] = add nuw nsw <4 x i64> [[VEC_PHI]], splat (i64 1)
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index 2f37c08bd9f117d..b17725382e33c56 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -672,7 +672,7 @@ TEST_F(VPBasicBlockTest, reassociateBlocks) {
auto *WidenPhi = new VPWidenPHIRecipe(nullptr);
IntegerType *Int32 = IntegerType::get(C, 32);
VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
- WidenPhi->addIncoming(Val, VPBB1);
+ WidenPhi->addOperand(Val);
VPBB2->appendRecipe(WidenPhi);
VPBasicBlock *VPBBNew = Plan.createVPBasicBlock("VPBBNew");
@@ -693,7 +693,7 @@ TEST_F(VPBasicBlockTest, reassociateBlocks) {
auto *WidenPhi = new VPWidenPHIRecipe(nullptr);
IntegerType *Int32 = IntegerType::get(C, 32);
VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
- WidenPhi->addIncoming(Val, VPBB1);
+ WidenPhi->addOperand(Val);
VPBB2->appendRecipe(WidenPhi);
VPBasicBlock *VPBBNew = Plan.createVPBasicBlock("VPBBNew");
|
#125481 made me think if tracking the incoming blocks separately is actually needed and it appears we can use the same approach as all other phi recipes I think |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, makes sense to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some post-approval comments and thoughts.
/// exactly 2 incoming values, from from the predecessors of the region and one | ||
/// from the exiting block of the region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// exactly 2 incoming values, from from the predecessors of the region and one | |
/// from the exiting block of the region. | |
/// exactly 2 incoming values, the first from the predecessors of the region and the second | |
/// from the exiting block of the region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks!
VPBasicBlock *Parent = getParent(); | ||
VPBlockBase *Pred = nullptr; | ||
if (Parent->getNumPredecessors() == 0) { | ||
auto *R = Parent->getParent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
auto *R = Parent->getParent(); | |
auto *Region = Parent->getParent(); |
R is often used for Recipe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks
assert(R && R->getEntry() == Parent); | ||
assert(I < 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error messages.
VPlans holding VPWidenPHIRecipes have only loop regions, which have a single predecessor - the preheader, even when nested?
Worth asserting R is not a replicating region.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added error messages and updated assert thanks.
VPlans holding VPWidenPHIRecipes have only loop regions, which have a single predecessor - the preheader, even when nested?
Yes at the moment (getSinglePredecessor will assert that)
auto *R = Parent->getParent(); | ||
assert(R && R->getEntry() == Parent); | ||
assert(I < 2); | ||
Pred = I == 0 ? R->getSinglePredecessor() : R; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I == 1 then the enclosing region is returned, whose exiting block feeds the VPWidenPHIRecipe across the backedge? Worth a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment, thanks!
@@ -136,19 +136,22 @@ void PlainCFGBuilder::fixPhiNodes() { | |||
// predecessor is the first operand of the recipe. | |||
assert(Phi->getNumOperands() == 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(independent) Error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 620a515
getOrCreateVPOperand(Phi->getIncomingValueForBlock(LoopPred)), | ||
BB2VPBB[LoopPred]); | ||
VPPhi->addOperand( | ||
getOrCreateVPOperand(Phi->getIncomingValueForBlock(LoopPred))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(independent) This first operand can be set when creating the VPWidenPHIRecipe, only the second operand requires backpatching.
for (unsigned I = 0; I != Phi->getNumOperands(); ++I) | ||
VPPhi->addIncoming(getOrCreateVPOperand(Phi->getIncomingValue(I)), | ||
BB2VPBB[Phi->getIncomingBlock(I)]); | ||
// Add operands for VPPhi in the order matching its predecessors in VPlan. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(independent) The operands of non-header VPWidenPHIRecipes can be set when creating it, rather than here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 30f44c9
VPPhi->addIncoming(getOrCreateVPOperand(Phi->getIncomingValue(I)), | ||
BB2VPBB[Phi->getIncomingBlock(I)]); | ||
// Add operands for VPPhi in the order matching its predecessors in VPlan. | ||
DenseMap<const VPBasicBlock *, VPValue *> IncomingValues; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DenseMap<const VPBasicBlock *, VPValue *> IncomingValues; | |
DenseMap<const VPBasicBlock *, VPValue *> VPPredToIncomingValue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks!
getOrCreateVPOperand(Phi->getIncomingValue(I)); | ||
} | ||
for (VPBlockBase *Pred : VPPhi->getParent()->getPredecessors()) | ||
VPPhi->addOperand(IncomingValues.lookup(Pred->getExitingBasicBlock())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: if/when the reverse mapping VPBB2BB is available, this could be done by
VPPhi->addOperand(Phi->getIncomingValueForBlock(VPBB2BB[Pred->getExitingBasicBlock()]));
void setIncomingBlock(unsigned I, VPBasicBlock *IncomingBlock) { | ||
IncomingBlocks[I] = IncomingBlock; | ||
} | ||
VPBasicBlock *getIncomingBlock(unsigned I); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow-up: make VPWidenPHIRecipe a VPInstruction by inlining both getIncomingValue() and getIncomingBlock() (in VPlan the latter fits a VPBB rather than a phi recipe) into their only user - fixNonInductionPHIs().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if VPInstruction
is the best place, as it may be beneficial to have an easier/more direct way to check if the node is phi-like. But it can probably share most of the logic with VPScalarPhiRecipe eventually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making VPWidenPHIRecipe be a VPInstruction would simplify "buildLoop" VPlan produced by HCFGBuilder, making it more consistent ("Widen"? All recipes are scalar at this point) and aligned with "wrapInput" VPlan/Region/Blocks which consist of VPIRInstructions - for phi's and non-phi's alike (with the option of introducing other recipes between them).
6047df3
to
ecf91bc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll take care of the independent suggestions separately.
/// exactly 2 incoming values, from from the predecessors of the region and one | ||
/// from the exiting block of the region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks!
void setIncomingBlock(unsigned I, VPBasicBlock *IncomingBlock) { | ||
IncomingBlocks[I] = IncomingBlock; | ||
} | ||
VPBasicBlock *getIncomingBlock(unsigned I); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if VPInstruction
is the best place, as it may be beneficial to have an easier/more direct way to check if the node is phi-like. But it can probably share most of the logic with VPScalarPhiRecipe eventually.
VPPhi->addIncoming(getOrCreateVPOperand(Phi->getIncomingValue(I)), | ||
BB2VPBB[Phi->getIncomingBlock(I)]); | ||
// Add operands for VPPhi in the order matching its predecessors in VPlan. | ||
DenseMap<const VPBasicBlock *, VPValue *> IncomingValues; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks!
VPBasicBlock *Parent = getParent(); | ||
VPBlockBase *Pred = nullptr; | ||
if (Parent->getNumPredecessors() == 0) { | ||
auto *R = Parent->getParent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks
assert(R && R->getEntry() == Parent); | ||
assert(I < 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added error messages and updated assert thanks.
VPlans holding VPWidenPHIRecipes have only loop regions, which have a single predecessor - the preheader, even when nested?
Yes at the moment (getSinglePredecessor will assert that)
auto *R = Parent->getParent(); | ||
assert(R && R->getEntry() == Parent); | ||
assert(I < 2); | ||
Pred = I == 0 ? R->getSinglePredecessor() : R; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last minor nits, LGTM too.
/// In the VPlan native path, all incoming VPValues & VPBasicBlock pairs are | ||
/// managed in the recipe directly. | ||
/// A recipe for widened phis. Incoming values are operands of the recipe and | ||
/// their operand index corresponds to the incoming predeocessor block. If the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// their operand index corresponds to the incoming predeocessor block. If the | |
/// their operand index corresponds to the incoming predecessor block. If the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks
/// A recipe for widened phis. Incoming values are operands of the recipe and | ||
/// their operand index corresponds to the incoming predeocessor block. If the | ||
/// recipe is placed in an entry block to a (non-replicate) region, it must have | ||
/// exactly 2 incoming values, the first from the predecessors of the region and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// exactly 2 incoming values, the first from the predecessors of the region and | |
/// exactly 2 incoming values, the first from the predecessor of the region and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks
void setIncomingBlock(unsigned I, VPBasicBlock *IncomingBlock) { | ||
IncomingBlocks[I] = IncomingBlock; | ||
} | ||
VPBasicBlock *getIncomingBlock(unsigned I); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making VPWidenPHIRecipe be a VPInstruction would simplify "buildLoop" VPlan produced by HCFGBuilder, making it more consistent ("Widen"? All recipes are scalar at this point) and aligned with "wrapInput" VPlan/Region/Blocks which consist of VPIRInstructions - for phi's and non-phi's alike (with the option of introducing other recipes between them).
if (Parent->getNumPredecessors() == 0) { | ||
auto *Region = Parent->getParent(); | ||
assert(Region && !Region->isReplicator() && Region->getEntry() == Parent && | ||
"must be in the entry block of a non-replicate region"); | ||
assert( | ||
I < 2 && getNumOperands() == 2 && | ||
"when placed in an entry block, only 2 incoming blocks are available"); | ||
|
||
// I == 0 selects the predecessor of the region, I == 1 selects the region | ||
// itself whose exiting block feeds the phi across the backedge. | ||
Pred = I == 0 ? Region->getSinglePredecessor() : Region; | ||
} else { | ||
Pred = Parent->getPredecessors()[I]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: better start with the 1-liner case first
if (Parent->getNumPredecessors() == 0) { | |
auto *Region = Parent->getParent(); | |
assert(Region && !Region->isReplicator() && Region->getEntry() == Parent && | |
"must be in the entry block of a non-replicate region"); | |
assert( | |
I < 2 && getNumOperands() == 2 && | |
"when placed in an entry block, only 2 incoming blocks are available"); | |
// I == 0 selects the predecessor of the region, I == 1 selects the region | |
// itself whose exiting block feeds the phi across the backedge. | |
Pred = I == 0 ? Region->getSinglePredecessor() : Region; | |
} else { | |
Pred = Parent->getPredecessors()[I]; | |
} | |
if (Parent->getNumPredecessors() > 0) { | |
Pred = Parent->getPredecessors()[I]; | |
} else { | |
auto *Region = Parent->getParent(); | |
assert(Region && !Region->isReplicator() && Region->getEntry() == Parent && | |
"must be in the entry block of a non-replicate region"); | |
assert( | |
I < 2 && getNumOperands() == 2 && | |
"when placed in an entry block, only 2 incoming blocks are available"); | |
// I == 0 selects the predecessor of the region, I == 1 selects the region | |
// itself whose exiting block feeds the phi across the backedge. | |
Pred = I == 0 ? Region->getSinglePredecessor() : Region; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks
Update VPWidenPHIRecipe to use the predecessors in VPlan to determine the incoming blocks instead of tracking them separately. This brings VPWidenPHIrecipe in line with the other phi recipes.
ecf91bc
to
25b218c
Compare
…(#126388) Update VPWidenPHIRecipe to use the predecessors in VPlan to determine the incoming blocks instead of tracking them separately. This brings VPWidenPHIRecipe in line with the other phi recipes. PR: llvm/llvm-project#126388
Update HCFG builder to set the incoming values directly at construction for non-header phis. Simplification/clarification as suggested independently in #126388.
Update HCFG builder to set the incoming values directly at construction for non-header phis. Simplification/clarification as suggested independently in llvm/llvm-project#126388.
Update HCFG builder to set the incoming values directly at construction for non-header phis. Simplification/clarification as suggested independently in llvm#126388.
Update VPWidenPHIRecipe to use the predecessors in VPlan to determine the incoming blocks instead of tracking them separately. This brings VPWidenPHIRecipe in line with the other phi recipes. PR: llvm#126388
Update HCFG builder to set the incoming values directly at construction for non-header phis. Simplification/clarification as suggested independently in llvm#126388.
Update VPWidenPHIRecipe to use the predecessors in VPlan to determine the incoming blocks instead of tracking them separately. This brings VPWidenPHIRecipe in line with the other phi recipes. PR: llvm#126388
Update HCFG builder to set the incoming values directly at construction for non-header phis. Simplification/clarification as suggested independently in llvm#126388.
Update VPWidenPHIRecipe to use the predecessors in VPlan to determine the incoming blocks instead of tracking them separately. This brings VPWidenPHIrecipe in line with the other phi recipes.