@@ -952,6 +952,7 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const {
952952 case VPInstruction::CanonicalIVIncrementForPart:
953953 case VPInstruction::BranchOnCount:
954954 case VPInstruction::BranchOnCond:
955+ case VPInstruction::Broadcast:
955956 case VPInstruction::ReductionStartVector:
956957 return true ;
957958 case VPInstruction::PtrAdd:
@@ -1077,15 +1078,14 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
10771078
10781079void VPInstructionWithType::execute (VPTransformState &State) {
10791080 State.setDebugLocFrom (getDebugLoc ());
1080- switch (getOpcode ()) {
1081- case Instruction::ZExt:
1082- case Instruction::Trunc: {
1081+ if (isScalarCast ()) {
10831082 Value *Op = State.get (getOperand (0 ), VPLane (0 ));
10841083 Value *Cast = State.Builder .CreateCast (Instruction::CastOps (getOpcode ()),
10851084 Op, ResultTy);
10861085 State.set (this , Cast, VPLane (0 ));
1087- break ;
1086+ return ;
10881087 }
1088+ switch (getOpcode ()) {
10891089 case VPInstruction::StepVector: {
10901090 Value *StepVector =
10911091 State.Builder .CreateStepVector (VectorType::get (ResultTy, State.VF ));
@@ -1965,149 +1965,13 @@ InstructionCost VPHeaderPHIRecipe::computeCost(ElementCount VF,
19651965 return Ctx.TTI .getCFInstrCost (Instruction::PHI, Ctx.CostKind );
19661966}
19671967
1968- // / This function adds
1969- // / (0 * Step, 1 * Step, 2 * Step, ...)
1970- // / to each vector element of Val.
1971- // / \p Opcode is relevant for FP induction variable.
1972- // / \p InitVec is an integer step vector from 0 with a step of 1.
1973- static Value *getStepVector (Value *Val, Value *Step, Value *InitVec,
1974- Instruction::BinaryOps BinOp, ElementCount VF,
1975- IRBuilderBase &Builder) {
1976- assert (VF.isVector () && " only vector VFs are supported" );
1977-
1978- // Create and check the types.
1979- auto *ValVTy = cast<VectorType>(Val->getType ());
1980- ElementCount VLen = ValVTy->getElementCount ();
1981-
1982- Type *STy = Val->getType ()->getScalarType ();
1983- assert ((STy->isIntegerTy () || STy->isFloatingPointTy ()) &&
1984- " Induction Step must be an integer or FP" );
1985- assert (Step->getType () == STy && " Step has wrong type" );
1986-
1987- if (STy->isIntegerTy ()) {
1988- Step = Builder.CreateVectorSplat (VLen, Step);
1989- assert (Step->getType () == Val->getType () && " Invalid step vec" );
1990- // FIXME: The newly created binary instructions should contain nsw/nuw
1991- // flags, which can be found from the original scalar operations.
1992- Step = Builder.CreateMul (InitVec, Step);
1993- return Builder.CreateAdd (Val, Step, " induction" );
1994- }
1995-
1996- // Floating point induction.
1997- assert ((BinOp == Instruction::FAdd || BinOp == Instruction::FSub) &&
1998- " Binary Opcode should be specified for FP induction" );
1999- InitVec = Builder.CreateUIToFP (InitVec, ValVTy);
2000-
2001- Step = Builder.CreateVectorSplat (VLen, Step);
2002- Value *MulOp = Builder.CreateFMul (InitVec, Step);
2003- return Builder.CreateBinOp (BinOp, Val, MulOp, " induction" );
2004- }
2005-
20061968// / A helper function that returns an integer or floating-point constant with
20071969// / value C.
20081970static Constant *getSignedIntOrFpConstant (Type *Ty, int64_t C) {
20091971 return Ty->isIntegerTy () ? ConstantInt::getSigned (Ty, C)
20101972 : ConstantFP::get (Ty, C);
20111973}
20121974
2013- void VPWidenIntOrFpInductionRecipe::execute (VPTransformState &State) {
2014- assert (!State.Lane && " Int or FP induction being replicated." );
2015-
2016- Value *Start = getStartValue ()->getLiveInIRValue ();
2017- const InductionDescriptor &ID = getInductionDescriptor ();
2018- TruncInst *Trunc = getTruncInst ();
2019- IRBuilderBase &Builder = State.Builder ;
2020- assert (getPHINode ()->getType () == ID.getStartValue ()->getType () &&
2021- " Types must match" );
2022- assert (State.VF .isVector () && " must have vector VF" );
2023-
2024- // The value from the original loop to which we are mapping the new induction
2025- // variable.
2026- Instruction *EntryVal = Trunc ? cast<Instruction>(Trunc) : getPHINode ();
2027-
2028- // Fast-math-flags propagate from the original induction instruction.
2029- IRBuilder<>::FastMathFlagGuard FMFG (Builder);
2030- if (isa_and_present<FPMathOperator>(ID.getInductionBinOp ()))
2031- Builder.setFastMathFlags (ID.getInductionBinOp ()->getFastMathFlags ());
2032-
2033- // Now do the actual transformations, and start with fetching the step value.
2034- Value *Step = State.get (getStepValue (), VPLane (0 ));
2035-
2036- assert ((isa<PHINode, TruncInst>(EntryVal)) &&
2037- " Expected either an induction phi-node or a truncate of it!" );
2038-
2039- // Construct the initial value of the vector IV in the vector loop preheader
2040- auto CurrIP = Builder.saveIP ();
2041- BasicBlock *VectorPH =
2042- State.CFG .VPBB2IRBB .at (getParent ()->getCFGPredecessor (0 ));
2043- Builder.SetInsertPoint (VectorPH->getTerminator ());
2044- if (isa<TruncInst>(EntryVal)) {
2045- assert (Start->getType ()->isIntegerTy () &&
2046- " Truncation requires an integer type" );
2047- auto *TruncType = cast<IntegerType>(EntryVal->getType ());
2048- Step = Builder.CreateTrunc (Step, TruncType);
2049- Start = Builder.CreateCast (Instruction::Trunc, Start, TruncType);
2050- }
2051-
2052- Value *SplatStart = Builder.CreateVectorSplat (State.VF , Start);
2053- Value *SteppedStart =
2054- ::getStepVector (SplatStart, Step, State.get(getStepVector()),
2055- ID.getInductionOpcode(), State.VF, State.Builder);
2056-
2057- // We create vector phi nodes for both integer and floating-point induction
2058- // variables. Here, we determine the kind of arithmetic we will perform.
2059- Instruction::BinaryOps AddOp;
2060- Instruction::BinaryOps MulOp;
2061- if (Step->getType ()->isIntegerTy ()) {
2062- AddOp = Instruction::Add;
2063- MulOp = Instruction::Mul;
2064- } else {
2065- AddOp = ID.getInductionOpcode ();
2066- MulOp = Instruction::FMul;
2067- }
2068-
2069- Value *SplatVF;
2070- if (VPValue *SplatVFOperand = getSplatVFValue ()) {
2071- // The recipe has been unrolled. In that case, fetch the splat value for the
2072- // induction increment.
2073- SplatVF = State.get (SplatVFOperand);
2074- } else {
2075- // Multiply the vectorization factor by the step using integer or
2076- // floating-point arithmetic as appropriate.
2077- Type *StepType = Step->getType ();
2078- Value *RuntimeVF = State.get (getVFValue (), VPLane (0 ));
2079- if (Step->getType ()->isFloatingPointTy ())
2080- RuntimeVF = Builder.CreateUIToFP (RuntimeVF, StepType);
2081- else
2082- RuntimeVF = Builder.CreateZExtOrTrunc (RuntimeVF, StepType);
2083- Value *Mul = Builder.CreateBinOp (MulOp, Step, RuntimeVF);
2084-
2085- // Create a vector splat to use in the induction update.
2086- SplatVF = Builder.CreateVectorSplat (State.VF , Mul);
2087- }
2088-
2089- Builder.restoreIP (CurrIP);
2090-
2091- // We may need to add the step a number of times, depending on the unroll
2092- // factor. The last of those goes into the PHI.
2093- PHINode *VecInd = PHINode::Create (SteppedStart->getType (), 2 , " vec.ind" );
2094- VecInd->insertBefore (State.CFG .PrevBB ->getFirstInsertionPt ());
2095- VecInd->setDebugLoc (getDebugLoc ());
2096- State.set (this , VecInd);
2097-
2098- Instruction *LastInduction = cast<Instruction>(
2099- Builder.CreateBinOp (AddOp, VecInd, SplatVF, " vec.ind.next" ));
2100- LastInduction->setDebugLoc (getDebugLoc ());
2101-
2102- VecInd->addIncoming (SteppedStart, VectorPH);
2103- // Add induction update using an incorrect block temporarily. The phi node
2104- // will be fixed after VPlan execution. Note that at this point the latch
2105- // block cannot be used, as it does not exist yet.
2106- // TODO: Model increment value in VPlan, by turning the recipe into a
2107- // multi-def and a subclass of VPHeaderPHIRecipe.
2108- VecInd->addIncoming (LastInduction, VectorPH);
2109- }
2110-
21111975#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
21121976void VPWidenIntOrFpInductionRecipe::print (raw_ostream &O, const Twine &Indent,
21131977 VPSlotTracker &SlotTracker) const {
@@ -3871,12 +3735,14 @@ void VPReductionPHIRecipe::print(raw_ostream &O, const Twine &Indent,
38713735#endif
38723736
38733737void VPWidenPHIRecipe::execute (VPTransformState &State) {
3874- assert (EnableVPlanNativePath &&
3875- " Non-native vplans are not expected to have VPWidenPHIRecipes." );
3876-
38773738 Value *Op0 = State.get (getOperand (0 ));
38783739 Type *VecTy = Op0->getType ();
3879- Value *VecPhi = State.Builder .CreatePHI (VecTy, 2 , Name);
3740+ Instruction *VecPhi = State.Builder .CreatePHI (VecTy, 2 , Name);
3741+ // Manually move it with the other PHIs in case PHI recipes above this one
3742+ // also inserted non-phi instructions.
3743+ // TODO: Remove once VPWidenPointerInductionRecipe is also expanded in
3744+ // convertToConcreteRecipes.
3745+ VecPhi->moveBefore (State.Builder .GetInsertBlock ()->getFirstNonPHIIt ());
38803746 State.set (this , VecPhi);
38813747}
38823748
0 commit comments