@@ -952,6 +952,7 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const {
952
952
case VPInstruction::CanonicalIVIncrementForPart:
953
953
case VPInstruction::BranchOnCount:
954
954
case VPInstruction::BranchOnCond:
955
+ case VPInstruction::Broadcast:
955
956
case VPInstruction::ReductionStartVector:
956
957
return true ;
957
958
case VPInstruction::PtrAdd:
@@ -1077,15 +1078,14 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
1077
1078
1078
1079
void VPInstructionWithType::execute (VPTransformState &State) {
1079
1080
State.setDebugLocFrom (getDebugLoc ());
1080
- switch (getOpcode ()) {
1081
- case Instruction::ZExt:
1082
- case Instruction::Trunc: {
1081
+ if (isScalarCast ()) {
1083
1082
Value *Op = State.get (getOperand (0 ), VPLane (0 ));
1084
1083
Value *Cast = State.Builder .CreateCast (Instruction::CastOps (getOpcode ()),
1085
1084
Op, ResultTy);
1086
1085
State.set (this , Cast, VPLane (0 ));
1087
- break ;
1086
+ return ;
1088
1087
}
1088
+ switch (getOpcode ()) {
1089
1089
case VPInstruction::StepVector: {
1090
1090
Value *StepVector =
1091
1091
State.Builder .CreateStepVector (VectorType::get (ResultTy, State.VF ));
@@ -1965,149 +1965,13 @@ InstructionCost VPHeaderPHIRecipe::computeCost(ElementCount VF,
1965
1965
return Ctx.TTI .getCFInstrCost (Instruction::PHI, Ctx.CostKind );
1966
1966
}
1967
1967
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
-
2006
1968
// / A helper function that returns an integer or floating-point constant with
2007
1969
// / value C.
2008
1970
static Constant *getSignedIntOrFpConstant (Type *Ty, int64_t C) {
2009
1971
return Ty->isIntegerTy () ? ConstantInt::getSigned (Ty, C)
2010
1972
: ConstantFP::get (Ty, C);
2011
1973
}
2012
1974
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
-
2111
1975
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2112
1976
void VPWidenIntOrFpInductionRecipe::print (raw_ostream &O, const Twine &Indent,
2113
1977
VPSlotTracker &SlotTracker) const {
@@ -3871,12 +3735,14 @@ void VPReductionPHIRecipe::print(raw_ostream &O, const Twine &Indent,
3871
3735
#endif
3872
3736
3873
3737
void VPWidenPHIRecipe::execute (VPTransformState &State) {
3874
- assert (EnableVPlanNativePath &&
3875
- " Non-native vplans are not expected to have VPWidenPHIRecipes." );
3876
-
3877
3738
Value *Op0 = State.get (getOperand (0 ));
3878
3739
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 ());
3880
3746
State.set (this , VecPhi);
3881
3747
}
3882
3748
0 commit comments