@@ -478,6 +478,7 @@ unsigned VPInstruction::getNumOperandsForOpcode(unsigned Opcode) {
478478 case VPInstruction::FirstOrderRecurrenceSplice:
479479 case VPInstruction::LogicalAnd:
480480 case VPInstruction::PtrAdd:
481+ case VPInstruction::WidePtrAdd:
481482 case VPInstruction::WideIVStep:
482483 return 2 ;
483484 case Instruction::Select:
@@ -858,6 +859,12 @@ Value *VPInstruction::generate(VPTransformState &State) {
858859 Value *Addend = State.get (getOperand (1 ), VPLane (0 ));
859860 return Builder.CreatePtrAdd (Ptr, Addend, Name, getGEPNoWrapFlags ());
860861 }
862+ case VPInstruction::WidePtrAdd: {
863+ Value *Ptr =
864+ State.get (getOperand (0 ), vputils::isSingleScalar (getOperand (0 )));
865+ Value *Addend = State.get (getOperand (1 ));
866+ return Builder.CreatePtrAdd (Ptr, Addend, Name, getGEPNoWrapFlags ());
867+ }
861868 case VPInstruction::AnyOf: {
862869 Value *Res = State.get (getOperand (0 ));
863870 for (VPValue *Op : drop_begin (operands ()))
@@ -1085,6 +1092,7 @@ bool VPInstruction::opcodeMayReadOrWriteFromMemory() const {
10851092 case VPInstruction::Not:
10861093 case VPInstruction::PtrAdd:
10871094 case VPInstruction::WideIVStep:
1095+ case VPInstruction::WidePtrAdd:
10881096 case VPInstruction::StepVector:
10891097 case VPInstruction::ReductionStartVector:
10901098 return false ;
@@ -1123,6 +1131,8 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const {
11231131 return true ;
11241132 case VPInstruction::PtrAdd:
11251133 return Op == getOperand (0 ) || vputils::onlyFirstLaneUsed (this );
1134+ case VPInstruction::WidePtrAdd:
1135+ return Op == getOperand (0 );
11261136 case VPInstruction::ComputeAnyOfResult:
11271137 case VPInstruction::ComputeFindIVResult:
11281138 return Op == getOperand (1 );
@@ -1231,6 +1241,9 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
12311241 case VPInstruction::PtrAdd:
12321242 O << " ptradd" ;
12331243 break ;
1244+ case VPInstruction::WidePtrAdd:
1245+ O << " wide-ptradd" ;
1246+ break ;
12341247 case VPInstruction::AnyOf:
12351248 O << " any-of" ;
12361249 break ;
@@ -1817,7 +1830,8 @@ bool VPIRFlags::flagsValidForOpcode(unsigned Opcode) const {
18171830 return Opcode == Instruction::AShr;
18181831 case OperationType::GEPOp:
18191832 return Opcode == Instruction::GetElementPtr ||
1820- Opcode == VPInstruction::PtrAdd;
1833+ Opcode == VPInstruction::PtrAdd ||
1834+ Opcode == VPInstruction::WidePtrAdd;
18211835 case OperationType::FPMathOp:
18221836 return Opcode == Instruction::FAdd || Opcode == Instruction::FMul ||
18231837 Opcode == Instruction::FSub || Opcode == Instruction::FNeg ||
@@ -3682,87 +3696,6 @@ bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(bool IsScalable) {
36823696 (!IsScalable || vputils::onlyFirstLaneUsed (this ));
36833697}
36843698
3685- void VPWidenPointerInductionRecipe::execute (VPTransformState &State) {
3686- assert (getInductionDescriptor ().getKind () ==
3687- InductionDescriptor::IK_PtrInduction &&
3688- " Not a pointer induction according to InductionDescriptor!" );
3689- assert (State.TypeAnalysis .inferScalarType (this )->isPointerTy () &&
3690- " Unexpected type." );
3691- assert (!onlyScalarsGenerated (State.VF .isScalable ()) &&
3692- " Recipe should have been replaced" );
3693-
3694- unsigned CurrentPart = getUnrollPart (*this );
3695-
3696- // Build a pointer phi
3697- Value *ScalarStartValue = getStartValue ()->getLiveInIRValue ();
3698- Type *ScStValueType = ScalarStartValue->getType ();
3699-
3700- BasicBlock *VectorPH =
3701- State.CFG .VPBB2IRBB .at (getParent ()->getCFGPredecessor (0 ));
3702- PHINode *NewPointerPhi = nullptr ;
3703- if (CurrentPart == 0 ) {
3704- IRBuilder<>::InsertPointGuard Guard (State.Builder );
3705- if (State.Builder .GetInsertPoint () !=
3706- State.Builder .GetInsertBlock ()->getFirstNonPHIIt ())
3707- State.Builder .SetInsertPoint (
3708- State.Builder .GetInsertBlock ()->getFirstNonPHIIt ());
3709- NewPointerPhi = State.Builder .CreatePHI (ScStValueType, 2 , " pointer.phi" );
3710- NewPointerPhi->addIncoming (ScalarStartValue, VectorPH);
3711- NewPointerPhi->setDebugLoc (getDebugLoc ());
3712- } else {
3713- // The recipe has been unrolled. In that case, fetch the single pointer phi
3714- // shared among all unrolled parts of the recipe.
3715- auto *GEP =
3716- cast<GetElementPtrInst>(State.get (getFirstUnrolledPartOperand ()));
3717- NewPointerPhi = cast<PHINode>(GEP->getPointerOperand ());
3718- }
3719-
3720- // A pointer induction, performed by using a gep
3721- BasicBlock::iterator InductionLoc = State.Builder .GetInsertPoint ();
3722- Value *ScalarStepValue = State.get (getStepValue (), VPLane (0 ));
3723- Type *PhiType = State.TypeAnalysis .inferScalarType (getStepValue ());
3724- Value *RuntimeVF = getRuntimeVF (State.Builder , PhiType, State.VF );
3725- // Add induction update using an incorrect block temporarily. The phi node
3726- // will be fixed after VPlan execution. Note that at this point the latch
3727- // block cannot be used, as it does not exist yet.
3728- // TODO: Model increment value in VPlan, by turning the recipe into a
3729- // multi-def and a subclass of VPHeaderPHIRecipe.
3730- if (CurrentPart == 0 ) {
3731- // The recipe represents the first part of the pointer induction. Create the
3732- // GEP to increment the phi across all unrolled parts.
3733- Value *NumUnrolledElems = State.get (getOperand (2 ), true );
3734-
3735- Value *InductionGEP = GetElementPtrInst::Create (
3736- State.Builder .getInt8Ty (), NewPointerPhi,
3737- State.Builder .CreateMul (
3738- ScalarStepValue,
3739- State.Builder .CreateTrunc (NumUnrolledElems, PhiType)),
3740- " ptr.ind" , InductionLoc);
3741-
3742- NewPointerPhi->addIncoming (InductionGEP, VectorPH);
3743- }
3744-
3745- // Create actual address geps that use the pointer phi as base and a
3746- // vectorized version of the step value (<step*0, ..., step*N>) as offset.
3747- Type *VecPhiType = VectorType::get (PhiType, State.VF );
3748- Value *StartOffsetScalar = State.Builder .CreateMul (
3749- RuntimeVF, ConstantInt::get (PhiType, CurrentPart));
3750- Value *StartOffset =
3751- State.Builder .CreateVectorSplat (State.VF , StartOffsetScalar);
3752- // Create a vector of consecutive numbers from zero to VF.
3753- StartOffset = State.Builder .CreateAdd (
3754- StartOffset, State.Builder .CreateStepVector (VecPhiType));
3755-
3756- assert (ScalarStepValue == State.get (getOperand (1 ), VPLane (0 )) &&
3757- " scalar step must be the same across all parts" );
3758- Value *GEP = State.Builder .CreateGEP (
3759- State.Builder .getInt8Ty (), NewPointerPhi,
3760- State.Builder .CreateMul (StartOffset, State.Builder .CreateVectorSplat (
3761- State.VF , ScalarStepValue)),
3762- " vector.gep" );
3763- State.set (this , GEP);
3764- }
3765-
37663699#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
37673700void VPWidenPointerInductionRecipe::print (raw_ostream &O, const Twine &Indent,
37683701 VPSlotTracker &SlotTracker) const {
@@ -3921,11 +3854,6 @@ void VPWidenPHIRecipe::execute(VPTransformState &State) {
39213854 Value *Op0 = State.get (getOperand (0 ));
39223855 Type *VecTy = Op0->getType ();
39233856 Instruction *VecPhi = State.Builder .CreatePHI (VecTy, 2 , Name);
3924- // Manually move it with the other PHIs in case PHI recipes above this one
3925- // also inserted non-phi instructions.
3926- // TODO: Remove once VPWidenPointerInductionRecipe is also expanded in
3927- // convertToConcreteRecipes.
3928- VecPhi->moveBefore (State.Builder .GetInsertBlock ()->getFirstNonPHIIt ());
39293857 State.set (this , VecPhi);
39303858}
39313859
0 commit comments