diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index f4163b0743a9a..972eca1fe8376 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1001,6 +1001,13 @@ class VPInstruction : public VPRecipeWithIRFlags, /// value for lane \p Lane. Value *generatePerLane(VPTransformState &State, const VPLane &Lane); +#if !defined(NDEBUG) + /// Return the number of operands determined by the opcode of the + /// VPInstruction. Returns -1u if the number of operands cannot be determined + /// directly by the opcode. + static unsigned getNumOperandsForOpcode(unsigned Opcode); +#endif + public: VPInstruction(unsigned Opcode, ArrayRef Operands, DebugLoc DL = {}, const Twine &Name = "") diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 805cd04c5ce35..4b0b74c0ea7d8 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -415,8 +415,64 @@ VPInstruction::VPInstruction(unsigned Opcode, ArrayRef Operands, VPIRMetadata(), Opcode(Opcode), Name(Name.str()) { assert(flagsValidForOpcode(getOpcode()) && "Set flags not supported for the provided opcode"); + assert((getNumOperandsForOpcode(Opcode) == -1u || + getNumOperandsForOpcode(Opcode) == getNumOperands()) && + "number of operands does not match opcode"); } +#ifndef NDEBUG +unsigned VPInstruction::getNumOperandsForOpcode(unsigned Opcode) { + if (Instruction::isUnaryOp(Opcode) || Instruction::isCast(Opcode)) + return 1; + + if (Instruction::isBinaryOp(Opcode)) + return 2; + + switch (Opcode) { + case VPInstruction::StepVector: + return 0; + case Instruction::Alloca: + case Instruction::ExtractValue: + case Instruction::Freeze: + case Instruction::Load: + case VPInstruction::AnyOf: + case VPInstruction::BranchOnCond: + case VPInstruction::CalculateTripCountMinusVF: + case VPInstruction::CanonicalIVIncrementForPart: + case VPInstruction::ExplicitVectorLength: + case VPInstruction::ExtractLastElement: + case VPInstruction::ExtractPenultimateElement: + case VPInstruction::FirstActiveLane: + case VPInstruction::Not: + return 1; + case Instruction::ICmp: + case Instruction::FCmp: + case Instruction::Store: + case VPInstruction::ActiveLaneMask: + case VPInstruction::BranchOnCount: + case VPInstruction::ComputeReductionResult: + case VPInstruction::FirstOrderRecurrenceSplice: + case VPInstruction::LogicalAnd: + case VPInstruction::PtrAdd: + case VPInstruction::WideIVStep: + return 2; + case Instruction::Select: + case VPInstruction::ComputeAnyOfResult: + case VPInstruction::ReductionStartVector: + return 3; + case VPInstruction::ComputeFindLastIVResult: + return 4; + case Instruction::Call: + case Instruction::GetElementPtr: + case Instruction::PHI: + case Instruction::Switch: + // Cannot determine the number of operands from the opcode. + return -1u; + } + llvm_unreachable("all cases should be handled above"); +} +#endif + bool VPInstruction::doesGeneratePerAllLanes() const { return Opcode == VPInstruction::PtrAdd && !vputils::onlyFirstLaneUsed(this); } diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp index 8b4fd066aaa26..8012d9ed38706 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -706,13 +706,15 @@ TEST_F(VPBasicBlockTest, reassociateBlocks) { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) TEST_F(VPBasicBlockTest, print) { - VPInstruction *TC = new VPInstruction(Instruction::Add, {}); + VPInstruction *TC = new VPInstruction(Instruction::PHI, {}); VPlan &Plan = getPlan(TC); + IntegerType *Int32 = IntegerType::get(C, 32); + VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); VPBasicBlock *VPBB0 = Plan.getEntry(); VPBB0->appendRecipe(TC); - VPInstruction *I1 = new VPInstruction(Instruction::Add, {}); - VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1}); + VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val}); + VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1, Val}); VPInstruction *I3 = new VPInstruction(Instruction::Br, {I1, I2}); VPBasicBlock *VPBB1 = Plan.createVPBasicBlock(""); @@ -722,7 +724,7 @@ TEST_F(VPBasicBlockTest, print) { VPBB1->setName("bb1"); VPInstruction *I4 = new VPInstruction(Instruction::Mul, {I2, I1}); - VPInstruction *I5 = new VPInstruction(Instruction::Ret, {I4}); + VPInstruction *I5 = new VPInstruction(Instruction::Br, {I4}); VPBasicBlock *VPBB2 = Plan.createVPBasicBlock(""); VPBB2->appendRecipe(I4); VPBB2->appendRecipe(I5); @@ -752,14 +754,14 @@ edge [fontname=Courier, fontsize=30] compound=true N0 [label = "preheader:\l" + - " EMIT vp\<%1\> = add \l" + + " EMIT-SCALAR vp\<%1\> = phi \l" + "Successor(s): bb1\l" ] N0 -> N1 [ label=""] N1 [label = "bb1:\l" + - " EMIT vp\<%2\> = add \l" + - " EMIT vp\<%3\> = sub vp\<%2\>\l" + + " EMIT vp\<%2\> = add ir\<1\>, ir\<1\>\l" + + " EMIT vp\<%3\> = sub vp\<%2\>, ir\<1\>\l" + " EMIT br vp\<%2\>, vp\<%3\>\l" + "Successor(s): bb2\l" ] @@ -767,7 +769,7 @@ compound=true N2 [label = "bb2:\l" + " EMIT vp\<%5\> = mul vp\<%3\>, vp\<%2\>\l" + - " EMIT ret vp\<%5\>\l" + + " EMIT br vp\<%5\>\l" + "Successor(s): ir-bb\\l" ] N2 -> N3 [ label=""] @@ -780,8 +782,8 @@ compound=true EXPECT_EQ(ExpectedStr, FullDump); const char *ExpectedBlock1Str = R"(bb1: - EMIT vp<%2> = add - EMIT vp<%3> = sub vp<%2> + EMIT vp<%2> = add ir<1>, ir<1> + EMIT vp<%3> = sub vp<%2>, ir<1> EMIT br vp<%2>, vp<%3> Successor(s): bb2 )"; @@ -793,7 +795,7 @@ Successor(s): bb2 // Ensure that numbering is good when dumping the second block in isolation. const char *ExpectedBlock2Str = R"(bb2: EMIT vp<%5> = mul vp<%3>, vp<%2> - EMIT ret vp<%5> + EMIT br vp<%5> Successor(s): ir-bb )"; std::string Block2Dump; @@ -909,9 +911,12 @@ TEST_F(VPBasicBlockTest, cloneAndPrint) { VPlan &Plan = getPlan(nullptr); VPBasicBlock *VPBB0 = Plan.getEntry(); - VPInstruction *I1 = new VPInstruction(Instruction::Add, {}); - VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1}); - VPInstruction *I3 = new VPInstruction(Instruction::Br, {I1, I2}); + IntegerType *Int32 = IntegerType::get(C, 32); + VPValue *Val = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1)); + + VPInstruction *I1 = new VPInstruction(Instruction::Add, {Val, Val}); + VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1, Val}); + VPInstruction *I3 = new VPInstruction(Instruction::Store, {I1, I2}); VPBasicBlock *VPBB1 = Plan.createVPBasicBlock(""); VPBB1->appendRecipe(I1); @@ -932,9 +937,9 @@ compound=true N0 -> N1 [ label=""] N1 [label = "bb1:\l" + - " EMIT vp\<%1\> = add \l" + - " EMIT vp\<%2\> = sub vp\<%1\>\l" + - " EMIT br vp\<%1\>, vp\<%2\>\l" + + " EMIT vp\<%1\> = add ir\<1\>, ir\<1\>\l" + + " EMIT vp\<%2\> = sub vp\<%1\>, ir\<1\>\l" + + " EMIT store vp\<%1\>, vp\<%2\>\l" + "No successors\l" ] }