Skip to content

Commit 7c4262f

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 20d6def commit 7c4262f

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
@@ -253,7 +253,7 @@ class VPBuilder {
253253
VPInstruction *createScalarPhi(ArrayRef<VPValue *> IncomingValues,
254254
DebugLoc DL, const Twine &Name = "") {
255255
return tryInsertInstruction(
256-
new VPInstruction(Instruction::PHI, IncomingValues, DL, Name));
256+
new VPPhi(Instruction::PHI, IncomingValues, DL, Name));
257257
}
258258

259259
/// 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
@@ -1143,6 +1143,28 @@ class VPPhiAccessors {
11431143
#endif
11441144
};
11451145

1146+
struct VPPhi : public VPInstruction, public VPPhiAccessors {
1147+
VPPhi(unsigned Opcode, ArrayRef<VPValue *> Operands, DebugLoc DL,
1148+
const Twine &Name = "")
1149+
: VPInstruction(Opcode, Operands, DL, Name) {}
1150+
1151+
static inline bool classof(const VPRecipeBase *U) {
1152+
auto *R = dyn_cast<VPInstruction>(U);
1153+
return R && R->getOpcode() == Instruction::PHI;
1154+
}
1155+
1156+
void execute(VPTransformState &State) override;
1157+
1158+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1159+
/// Print the recipe.
1160+
void print(raw_ostream &O, const Twine &Indent,
1161+
VPSlotTracker &SlotTracker) const override;
1162+
#endif
1163+
1164+
protected:
1165+
const VPRecipeBase *getAsRecipe() const override { return this; }
1166+
};
1167+
11461168
/// A recipe to wrap on original IR instruction not to be modified during
11471169
/// execution, except for PHIs. PHIs are modeled via the VPIRPhi subclass.
11481170
/// 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
@@ -492,16 +492,7 @@ Value *VPInstruction::generate(VPTransformState &State) {
492492
return Builder.CreateCmp(getPredicate(), A, B, Name);
493493
}
494494
case Instruction::PHI: {
495-
assert(getParent() ==
496-
getParent()->getPlan()->getVectorLoopRegion()->getEntry() &&
497-
"VPInstructions with PHI opcodes must be used for header phis only "
498-
"at the moment");
499-
BasicBlock *VectorPH =
500-
State.CFG.VPBB2IRBB.at(getParent()->getCFGPredecessor(0));
501-
Value *Start = State.get(getOperand(0), VPLane(0));
502-
PHINode *Phi = State.Builder.CreatePHI(Start->getType(), 2, Name);
503-
Phi->addIncoming(Start, VectorPH);
504-
return Phi;
495+
llvm_unreachable("should be handled by VPPhi::execute");
505496
}
506497
case Instruction::Select: {
507498
bool OnlyFirstLaneUsed = vputils::onlyFirstLaneUsed(this);
@@ -1131,6 +1122,30 @@ void VPInstructionWithType::print(raw_ostream &O, const Twine &Indent,
11311122
}
11321123
#endif
11331124

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