Skip to content

Commit 5feb4cc

Browse files
committed
[VPlan] Add new VPPhi subclass for VPInstruction with PHI opcodes.
Similarly to VPInstructionWithType and VPIRPhi, add VPPhi as a subclass for VPInstruction. This allows implementing the VPPhiAccessors trait, making available helpers for generic printing of incoming values / blocks and accessors for incoming blocks and values. It will also allow properly verifying def-uses for values used by VPInstructions with PHI opcodes via #124838.
1 parent c82e2f5 commit 5feb4cc

File tree

8 files changed

+55
-18
lines changed

8 files changed

+55
-18
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ class VPBuilder {
252252
VPInstruction *createScalarPhi(ArrayRef<VPValue *> IncomingValues,
253253
DebugLoc DL, const Twine &Name = "") {
254254
return tryInsertInstruction(
255-
new VPInstruction(Instruction::PHI, IncomingValues, DL, Name));
255+
new VPPhi(Instruction::PHI, IncomingValues, DL, Name));
256256
}
257257

258258
/// Convert the input value \p Current to the corresponding value of an

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,28 @@ class VPPhiAccessors {
11421142
#endif
11431143
};
11441144

1145+
struct VPPhi : public VPInstruction, public VPPhiAccessors {
1146+
VPPhi(unsigned Opcode, ArrayRef<VPValue *> Operands, DebugLoc DL,
1147+
const Twine &Name = "")
1148+
: VPInstruction(Opcode, Operands, DL, Name) {}
1149+
1150+
static inline bool classof(const VPRecipeBase *U) {
1151+
auto *R = dyn_cast<VPInstruction>(U);
1152+
return R && R->getOpcode() == Instruction::PHI;
1153+
}
1154+
1155+
void execute(VPTransformState &State) override;
1156+
1157+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1158+
/// Print the recipe.
1159+
void print(raw_ostream &O, const Twine &Indent,
1160+
VPSlotTracker &SlotTracker) const override;
1161+
#endif
1162+
1163+
protected:
1164+
const VPRecipeBase *getAsRecipe() const override { return this; }
1165+
};
1166+
11451167
/// A recipe to wrap on original IR instruction not to be modified during
11461168
/// execution, except for PHIs. PHIs are modeled via the VPIRPhi subclass.
11471169
/// Expect PHIs, VPIRInstructions cannot have any operands.

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -491,16 +491,7 @@ Value *VPInstruction::generate(VPTransformState &State) {
491491
return Builder.CreateCmp(getPredicate(), A, B, Name);
492492
}
493493
case Instruction::PHI: {
494-
assert(getParent() ==
495-
getParent()->getPlan()->getVectorLoopRegion()->getEntry() &&
496-
"VPInstructions with PHI opcodes must be used for header phis only "
497-
"at the moment");
498-
BasicBlock *VectorPH =
499-
State.CFG.VPBB2IRBB.at(getParent()->getCFGPredecessor(0));
500-
Value *Start = State.get(getOperand(0), VPLane(0));
501-
PHINode *Phi = State.Builder.CreatePHI(Start->getType(), 2, Name);
502-
Phi->addIncoming(Start, VectorPH);
503-
return Phi;
494+
llvm_unreachable("should be handled by VPPhi::execute");
504495
}
505496
case Instruction::Select: {
506497
bool OnlyFirstLaneUsed = vputils::onlyFirstLaneUsed(this);
@@ -1130,6 +1121,30 @@ void VPInstructionWithType::print(raw_ostream &O, const Twine &Indent,
11301121
}
11311122
#endif
11321123

1124+
void VPPhi::execute(VPTransformState &State) {
1125+
State.setDebugLocFrom(getDebugLoc());
1126+
assert(getParent() ==
1127+
getParent()->getPlan()->getVectorLoopRegion()->getEntry() &&
1128+
"VPInstructions with PHI opcodes must be used for header phis only "
1129+
"at the moment");
1130+
BasicBlock *VectorPH = State.CFG.VPBB2IRBB.at(getIncomingBlock(0));
1131+
Value *Start = State.get(getIncomingValue(0), VPLane(0));
1132+
PHINode *Phi = State.Builder.CreatePHI(Start->getType(), 2, getName());
1133+
Phi->addIncoming(Start, VectorPH);
1134+
State.set(this, Phi, VPLane(0));
1135+
}
1136+
1137+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1138+
void VPPhi::print(raw_ostream &O, const Twine &Indent,
1139+
VPSlotTracker &SlotTracker) const {
1140+
O << Indent << "EMIT ";
1141+
printAsOperand(O, SlotTracker);
1142+
O << " = phi ";
1143+
1144+
printPhiOperands(O, SlotTracker);
1145+
}
1146+
#endif
1147+
11331148
VPIRInstruction *VPIRInstruction ::create(Instruction &I) {
11341149
if (auto *Phi = dyn_cast<PHINode>(&I))
11351150
return new VPIRPhi(*Phi);

llvm/test/Transforms/LoopVectorize/AArch64/vplan-printing.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ define i32 @print_partial_reduction(ptr %a, ptr %b) {
8787
; CHECK-EMPTY:
8888
; CHECK-NEXT: <x1> vector loop: {
8989
; CHECK-NEXT: vector.body:
90-
; CHECK-NEXT: EMIT vp<[[EP_IV:%.+]]> = phi ir<0>, vp<%index.next>
90+
; CHECK-NEXT: EMIT vp<[[EP_IV:%.+]]> = phi [ ir<0>, ir-bb<vector.ph> ], [ vp<%index.next>, vector.body ]
9191
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%accum> = phi ir<0>, ir<%add> (VF scaled by 1/4)
9292
; CHECK-NEXT: CLONE ir<%gep.a> = getelementptr ir<%a>, vp<[[EP_IV]]>
9393
; CHECK-NEXT: vp<[[PTR_A:%.+]]> = vector-pointer ir<%gep.a>

llvm/test/Transforms/LoopVectorize/RISCV/riscv-vector-reverse.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ define void @vector_reverse_i64(ptr nocapture noundef writeonly %A, ptr nocaptur
197197
; CHECK-EMPTY:
198198
; CHECK-NEXT: <x1> vector loop: {
199199
; CHECK-NEXT: vector.body:
200-
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = phi ir<0>, vp<[[CAN_IV_NEXT:%.+]]>
200+
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = phi [ ir<0>, ir-bb<vector.ph> ], [ vp<[[CAN_IV_NEXT:%.+]]>, vector.body ]
201201
; CHECK-NEXT: vp<[[DEV_IV:%.+]]> = DERIVED-IV ir<%n> + vp<[[CAN_IV]]> * ir<-1>
202202
; CHECK-NEXT: CLONE ir<%i.0> = add nsw vp<[[DEV_IV]]>, ir<-1>
203203
; CHECK-NEXT: CLONE ir<%idxprom> = zext ir<%i.0>
@@ -448,7 +448,7 @@ define void @vector_reverse_f32(ptr nocapture noundef writeonly %A, ptr nocaptur
448448
; CHECK-EMPTY:
449449
; CHECK-NEXT: <x1> vector loop: {
450450
; CHECK-NEXT: vector.body:
451-
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = phi ir<0>, vp<[[CAN_IV_NEXT:%.+]]>
451+
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = phi [ ir<0>, ir-bb<vector.ph> ], [ vp<[[CAN_IV_NEXT:%.+]]>, vector.body ]
452452
; CHECK-NEXT: vp<[[DEV_IV:%.+]]> = DERIVED-IV ir<%n> + vp<[[CAN_IV]]> * ir<-1>
453453
; CHECK-NEXT: CLONE ir<%i.0> = add nsw vp<[[DEV_IV]]>, ir<-1>
454454
; CHECK-NEXT: CLONE ir<%idxprom> = zext ir<%i.0>

llvm/test/Transforms/LoopVectorize/RISCV/vplan-vp-intrinsics-fixed-order-recurrence.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ define void @first_order_recurrence(ptr noalias %A, ptr noalias %B, i64 %TC) {
2727
; IF-EVL-NEXT: EMIT vp<[[IV:%[0-9]+]]> = CANONICAL-INDUCTION
2828
; IF-EVL-NEXT: EXPLICIT-VECTOR-LENGTH-BASED-IV-PHI vp<[[EVL_PHI:%[0-9]+]]> = phi ir<0>, vp<[[IV_NEXT:%.+]]>
2929
; IF-EVL-NEXT: FIRST-ORDER-RECURRENCE-PHI ir<[[FOR_PHI:%.+]]> = phi ir<33>, ir<[[LD:%.+]]>
30-
; IF-EVL-NEXT: EMIT vp<[[PREV_EVL:%.+]]> = phi vp<[[VF32]]>, vp<[[EVL:%.+]]>
30+
; IF-EVL-NEXT: EMIT vp<[[PREV_EVL:%.+]]> = phi [ vp<[[VF32]]>, vector.ph ], [ vp<[[EVL:%.+]]>, vector.body ]
3131
; IF-EVL-NEXT: EMIT vp<[[AVL:%.+]]> = sub ir<%TC>, vp<[[EVL_PHI]]>
3232
; IF-EVL-NEXT: EMIT vp<[[EVL]]> = EXPLICIT-VECTOR-LENGTH vp<[[AVL]]>
3333
; IF-EVL-NEXT: vp<[[ST:%[0-9]+]]> = SCALAR-STEPS vp<[[EVL_PHI]]>, ir<1>

llvm/test/Transforms/LoopVectorize/RISCV/vplan-vp-select-intrinsics.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232

3333
; IF-EVL: <x1> vector loop: {
3434
; IF-EVL-NEXT: vector.body:
35-
; IF-EVL-NEXT: EMIT vp<[[IV:%.+]]> = phi ir<0>, vp<[[IV_NEXT_EXIT:%.+]]>
36-
; IF-EVL-NEXT: EMIT vp<[[EVL_PHI:%.+]]> = phi ir<0>, vp<[[IV_NEX:%.+]]>
35+
; IF-EVL-NEXT: EMIT vp<[[IV:%.+]]> = phi [ ir<0>, ir-bb<vector.ph> ], [ vp<[[IV_NEXT_EXIT:%.+]]>, vector.body ]
36+
; IF-EVL-NEXT: EMIT vp<[[EVL_PHI:%.+]]> = phi [ ir<0>, ir-bb<vector.ph> ], [ vp<[[IV_NEX:%.+]]>, vector.body ]
3737
; IF-EVL-NEXT: EMIT vp<[[AVL:%.+]]> = sub ir<%N>, vp<[[EVL_PHI]]>
3838
; IF-EVL-NEXT: EMIT vp<[[EVL:%.+]]> = EXPLICIT-VECTOR-LENGTH vp<[[AVL]]>
3939
; IF-EVL-NEXT: CLONE ir<[[GEP1:%.+]]> = getelementptr inbounds ir<%b>, vp<[[EVL_PHI]]>

llvm/test/Transforms/LoopVectorize/vplan-predicate-switch.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ define void @switch4_default_common_dest_with_case(ptr %start, ptr %end) {
1919
; CHECK-EMPTY:
2020
; CHECK-NEXT: <x1> vector loop: {
2121
; CHECK-NEXT: vector.body:
22-
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = phi ir<0>, vp<[[CAN_IV_NEXT:%.+]]>
22+
; CHECK-NEXT: EMIT vp<[[CAN_IV:%.+]]> = phi [ ir<0>, ir-bb<vector.ph> ], [ vp<[[CAN_IV_NEXT:%.+]]>, default.2 ]
2323
; CHECK-NEXT: vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>, ir<2>
2424
; CHECK-NEXT: EMIT vp<[[PTR:%.+]]> = ptradd ir<%start>, vp<[[STEPS]]>
2525
; CHECK-NEXT: vp<[[WIDE_PTR:%.+]]> = vector-pointer vp<[[PTR]]>

0 commit comments

Comments
 (0)