Skip to content

Commit c3e25e7

Browse files
authored
[VPlan] Add VPInst::getNumOperandsForOpcode, use to verify in ctor (NFC) (#142284)
Add a new getNumOperandsForOpcode helper to determine the number of operands from the opcode. For now, it is used to verify the number operands at VPInstruction construction. It returns -1 for a few opcodes where the number of operands cannot be determined (GEP, Switch, PHI, Call). This can also be used in a follow-up to determine if a VPInstruction is masked based on the number of arguments. PR: #142284
1 parent b171ebb commit c3e25e7

File tree

3 files changed

+85
-17
lines changed

3 files changed

+85
-17
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,13 @@ class VPInstruction : public VPRecipeWithIRFlags,
10011001
/// value for lane \p Lane.
10021002
Value *generatePerLane(VPTransformState &State, const VPLane &Lane);
10031003

1004+
#if !defined(NDEBUG)
1005+
/// Return the number of operands determined by the opcode of the
1006+
/// VPInstruction. Returns -1u if the number of operands cannot be determined
1007+
/// directly by the opcode.
1008+
static unsigned getNumOperandsForOpcode(unsigned Opcode);
1009+
#endif
1010+
10041011
public:
10051012
VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands, DebugLoc DL = {},
10061013
const Twine &Name = "")

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,64 @@ VPInstruction::VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands,
415415
VPIRMetadata(), Opcode(Opcode), Name(Name.str()) {
416416
assert(flagsValidForOpcode(getOpcode()) &&
417417
"Set flags not supported for the provided opcode");
418+
assert((getNumOperandsForOpcode(Opcode) == -1u ||
419+
getNumOperandsForOpcode(Opcode) == getNumOperands()) &&
420+
"number of operands does not match opcode");
418421
}
419422

423+
#ifndef NDEBUG
424+
unsigned VPInstruction::getNumOperandsForOpcode(unsigned Opcode) {
425+
if (Instruction::isUnaryOp(Opcode) || Instruction::isCast(Opcode))
426+
return 1;
427+
428+
if (Instruction::isBinaryOp(Opcode))
429+
return 2;
430+
431+
switch (Opcode) {
432+
case VPInstruction::StepVector:
433+
return 0;
434+
case Instruction::Alloca:
435+
case Instruction::ExtractValue:
436+
case Instruction::Freeze:
437+
case Instruction::Load:
438+
case VPInstruction::AnyOf:
439+
case VPInstruction::BranchOnCond:
440+
case VPInstruction::CalculateTripCountMinusVF:
441+
case VPInstruction::CanonicalIVIncrementForPart:
442+
case VPInstruction::ExplicitVectorLength:
443+
case VPInstruction::ExtractLastElement:
444+
case VPInstruction::ExtractPenultimateElement:
445+
case VPInstruction::FirstActiveLane:
446+
case VPInstruction::Not:
447+
return 1;
448+
case Instruction::ICmp:
449+
case Instruction::FCmp:
450+
case Instruction::Store:
451+
case VPInstruction::ActiveLaneMask:
452+
case VPInstruction::BranchOnCount:
453+
case VPInstruction::ComputeReductionResult:
454+
case VPInstruction::FirstOrderRecurrenceSplice:
455+
case VPInstruction::LogicalAnd:
456+
case VPInstruction::PtrAdd:
457+
case VPInstruction::WideIVStep:
458+
return 2;
459+
case Instruction::Select:
460+
case VPInstruction::ComputeAnyOfResult:
461+
case VPInstruction::ReductionStartVector:
462+
return 3;
463+
case VPInstruction::ComputeFindLastIVResult:
464+
return 4;
465+
case Instruction::Call:
466+
case Instruction::GetElementPtr:
467+
case Instruction::PHI:
468+
case Instruction::Switch:
469+
// Cannot determine the number of operands from the opcode.
470+
return -1u;
471+
}
472+
llvm_unreachable("all cases should be handled above");
473+
}
474+
#endif
475+
420476
bool VPInstruction::doesGeneratePerAllLanes() const {
421477
return Opcode == VPInstruction::PtrAdd && !vputils::onlyFirstLaneUsed(this);
422478
}

llvm/unittests/Transforms/Vectorize/VPlanTest.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -706,13 +706,15 @@ TEST_F(VPBasicBlockTest, reassociateBlocks) {
706706

707707
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
708708
TEST_F(VPBasicBlockTest, print) {
709-
VPInstruction *TC = new VPInstruction(Instruction::Add, {});
709+
VPInstruction *TC = new VPInstruction(Instruction::PHI, {});
710710
VPlan &Plan = getPlan(TC);
711+
IntegerType *Int32 = IntegerType::get(C, 32);
712+
VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
711713
VPBasicBlock *VPBB0 = Plan.getEntry();
712714
VPBB0->appendRecipe(TC);
713715

714-
VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
715-
VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1});
716+
VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val});
717+
VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1, Val});
716718
VPInstruction *I3 = new VPInstruction(Instruction::Br, {I1, I2});
717719

718720
VPBasicBlock *VPBB1 = Plan.createVPBasicBlock("");
@@ -722,7 +724,7 @@ TEST_F(VPBasicBlockTest, print) {
722724
VPBB1->setName("bb1");
723725

724726
VPInstruction *I4 = new VPInstruction(Instruction::Mul, {I2, I1});
725-
VPInstruction *I5 = new VPInstruction(Instruction::Ret, {I4});
727+
VPInstruction *I5 = new VPInstruction(Instruction::Br, {I4});
726728
VPBasicBlock *VPBB2 = Plan.createVPBasicBlock("");
727729
VPBB2->appendRecipe(I4);
728730
VPBB2->appendRecipe(I5);
@@ -752,22 +754,22 @@ edge [fontname=Courier, fontsize=30]
752754
compound=true
753755
N0 [label =
754756
"preheader:\l" +
755-
" EMIT vp\<%1\> = add \l" +
757+
" EMIT-SCALAR vp\<%1\> = phi \l" +
756758
"Successor(s): bb1\l"
757759
]
758760
N0 -> N1 [ label=""]
759761
N1 [label =
760762
"bb1:\l" +
761-
" EMIT vp\<%2\> = add \l" +
762-
" EMIT vp\<%3\> = sub vp\<%2\>\l" +
763+
" EMIT vp\<%2\> = add ir\<1\>, ir\<1\>\l" +
764+
" EMIT vp\<%3\> = sub vp\<%2\>, ir\<1\>\l" +
763765
" EMIT br vp\<%2\>, vp\<%3\>\l" +
764766
"Successor(s): bb2\l"
765767
]
766768
N1 -> N2 [ label=""]
767769
N2 [label =
768770
"bb2:\l" +
769771
" EMIT vp\<%5\> = mul vp\<%3\>, vp\<%2\>\l" +
770-
" EMIT ret vp\<%5\>\l" +
772+
" EMIT br vp\<%5\>\l" +
771773
"Successor(s): ir-bb\<scalar.header\>\l"
772774
]
773775
N2 -> N3 [ label=""]
@@ -780,8 +782,8 @@ compound=true
780782
EXPECT_EQ(ExpectedStr, FullDump);
781783

782784
const char *ExpectedBlock1Str = R"(bb1:
783-
EMIT vp<%2> = add
784-
EMIT vp<%3> = sub vp<%2>
785+
EMIT vp<%2> = add ir<1>, ir<1>
786+
EMIT vp<%3> = sub vp<%2>, ir<1>
785787
EMIT br vp<%2>, vp<%3>
786788
Successor(s): bb2
787789
)";
@@ -793,7 +795,7 @@ Successor(s): bb2
793795
// Ensure that numbering is good when dumping the second block in isolation.
794796
const char *ExpectedBlock2Str = R"(bb2:
795797
EMIT vp<%5> = mul vp<%3>, vp<%2>
796-
EMIT ret vp<%5>
798+
EMIT br vp<%5>
797799
Successor(s): ir-bb<scalar.header>
798800
)";
799801
std::string Block2Dump;
@@ -909,9 +911,12 @@ TEST_F(VPBasicBlockTest, cloneAndPrint) {
909911
VPlan &Plan = getPlan(nullptr);
910912
VPBasicBlock *VPBB0 = Plan.getEntry();
911913

912-
VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
913-
VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1});
914-
VPInstruction *I3 = new VPInstruction(Instruction::Br, {I1, I2});
914+
IntegerType *Int32 = IntegerType::get(C, 32);
915+
VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
916+
917+
VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val});
918+
VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1, Val});
919+
VPInstruction *I3 = new VPInstruction(Instruction::Store, {I1, I2});
915920

916921
VPBasicBlock *VPBB1 = Plan.createVPBasicBlock("");
917922
VPBB1->appendRecipe(I1);
@@ -932,9 +937,9 @@ compound=true
932937
N0 -> N1 [ label=""]
933938
N1 [label =
934939
"bb1:\l" +
935-
" EMIT vp\<%1\> = add \l" +
936-
" EMIT vp\<%2\> = sub vp\<%1\>\l" +
937-
" EMIT br vp\<%1\>, vp\<%2\>\l" +
940+
" EMIT vp\<%1\> = add ir\<1\>, ir\<1\>\l" +
941+
" EMIT vp\<%2\> = sub vp\<%1\>, ir\<1\>\l" +
942+
" EMIT store vp\<%1\>, vp\<%2\>\l" +
938943
"No successors\l"
939944
]
940945
}

0 commit comments

Comments
 (0)