@@ -478,6 +478,7 @@ unsigned VPInstruction::getNumOperandsForOpcode(unsigned Opcode) {
478
478
case VPInstruction::FirstOrderRecurrenceSplice:
479
479
case VPInstruction::LogicalAnd:
480
480
case VPInstruction::PtrAdd:
481
+ case VPInstruction::WidePtrAdd:
481
482
case VPInstruction::WideIVStep:
482
483
return 2 ;
483
484
case Instruction::Select:
@@ -858,6 +859,12 @@ Value *VPInstruction::generate(VPTransformState &State) {
858
859
Value *Addend = State.get (getOperand (1 ), VPLane (0 ));
859
860
return Builder.CreatePtrAdd (Ptr, Addend, Name, getGEPNoWrapFlags ());
860
861
}
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
+ }
861
868
case VPInstruction::AnyOf: {
862
869
Value *Res = State.get (getOperand (0 ));
863
870
for (VPValue *Op : drop_begin (operands ()))
@@ -1085,6 +1092,7 @@ bool VPInstruction::opcodeMayReadOrWriteFromMemory() const {
1085
1092
case VPInstruction::Not:
1086
1093
case VPInstruction::PtrAdd:
1087
1094
case VPInstruction::WideIVStep:
1095
+ case VPInstruction::WidePtrAdd:
1088
1096
case VPInstruction::StepVector:
1089
1097
case VPInstruction::ReductionStartVector:
1090
1098
return false ;
@@ -1123,6 +1131,8 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const {
1123
1131
return true ;
1124
1132
case VPInstruction::PtrAdd:
1125
1133
return Op == getOperand (0 ) || vputils::onlyFirstLaneUsed (this );
1134
+ case VPInstruction::WidePtrAdd:
1135
+ return Op == getOperand (0 );
1126
1136
case VPInstruction::ComputeAnyOfResult:
1127
1137
case VPInstruction::ComputeFindIVResult:
1128
1138
return Op == getOperand (1 );
@@ -1231,6 +1241,9 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
1231
1241
case VPInstruction::PtrAdd:
1232
1242
O << " ptradd" ;
1233
1243
break ;
1244
+ case VPInstruction::WidePtrAdd:
1245
+ O << " wide-ptradd" ;
1246
+ break ;
1234
1247
case VPInstruction::AnyOf:
1235
1248
O << " any-of" ;
1236
1249
break ;
@@ -1817,7 +1830,8 @@ bool VPIRFlags::flagsValidForOpcode(unsigned Opcode) const {
1817
1830
return Opcode == Instruction::AShr;
1818
1831
case OperationType::GEPOp:
1819
1832
return Opcode == Instruction::GetElementPtr ||
1820
- Opcode == VPInstruction::PtrAdd;
1833
+ Opcode == VPInstruction::PtrAdd ||
1834
+ Opcode == VPInstruction::WidePtrAdd;
1821
1835
case OperationType::FPMathOp:
1822
1836
return Opcode == Instruction::FAdd || Opcode == Instruction::FMul ||
1823
1837
Opcode == Instruction::FSub || Opcode == Instruction::FNeg ||
@@ -3682,87 +3696,6 @@ bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(bool IsScalable) {
3682
3696
(!IsScalable || vputils::onlyFirstLaneUsed (this ));
3683
3697
}
3684
3698
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
-
3766
3699
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3767
3700
void VPWidenPointerInductionRecipe::print (raw_ostream &O, const Twine &Indent,
3768
3701
VPSlotTracker &SlotTracker) const {
@@ -3921,11 +3854,6 @@ void VPWidenPHIRecipe::execute(VPTransformState &State) {
3921
3854
Value *Op0 = State.get (getOperand (0 ));
3922
3855
Type *VecTy = Op0->getType ();
3923
3856
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 ());
3929
3857
State.set (this , VecPhi);
3930
3858
}
3931
3859
0 commit comments