@@ -2566,10 +2566,15 @@ InstructionCost VPWidenMemoryRecipe::computeCost(ElementCount VF,
25662566 const Value *Ptr = getLoadStorePointerOperand (&Ingredient);
25672567 assert (!Reverse &&
25682568 " Inconsecutive memory access should not have the order." );
2569- return Ctx.TTI .getAddressComputationCost (Ty) +
2570- Ctx.TTI .getGatherScatterOpCost (Ingredient.getOpcode (), Ty, Ptr,
2571- IsMasked, Alignment, Ctx.CostKind ,
2572- &Ingredient);
2569+ if (Strided)
2570+ return Ctx.TTI .getStridedMemoryOpCost (Ingredient.getOpcode (), Ty, Ptr,
2571+ IsMasked, Alignment, Ctx.CostKind ,
2572+ &Ingredient);
2573+ else
2574+ return Ctx.TTI .getAddressComputationCost (Ty) +
2575+ Ctx.TTI .getGatherScatterOpCost (Ingredient.getOpcode (), Ty, Ptr,
2576+ IsMasked, Alignment, Ctx.CostKind ,
2577+ &Ingredient);
25732578 }
25742579
25752580 InstructionCost Cost = 0 ;
@@ -2596,11 +2601,13 @@ void VPWidenLoadRecipe::execute(VPTransformState &State) {
25962601 Type *ScalarDataTy = getLoadStoreType (&Ingredient);
25972602 auto *DataTy = VectorType::get (ScalarDataTy, State.VF );
25982603 const Align Alignment = getLoadStoreAlignment (&Ingredient);
2599- bool CreateGather = !isConsecutive ();
2604+ bool CreateGather = !isConsecutive () && ! isStrided () ;
26002605
26012606 auto &Builder = State.Builder ;
26022607 State.setDebugLocFrom (getDebugLoc ());
2603- Value *Mask = nullptr ;
2608+ Value *Mask = isStrided ()
2609+ ? Builder.CreateVectorSplat (State.VF , Builder.getTrue ())
2610+ : nullptr ;
26042611 if (auto *VPMask = getMask ()) {
26052612 // Mask reversal is only needed for non-all-one (null) masks, as reverse
26062613 // of a null all-one mask is a null mask.
@@ -2615,9 +2622,25 @@ void VPWidenLoadRecipe::execute(VPTransformState &State) {
26152622 NewLI = Builder.CreateMaskedGather (DataTy, Addr, Alignment, Mask, nullptr ,
26162623 " wide.masked.gather" );
26172624 } else if (Mask) {
2618- NewLI =
2619- Builder.CreateMaskedLoad (DataTy, Addr, Alignment, Mask,
2620- PoisonValue::get (DataTy), " wide.masked.load" );
2625+ if (isStrided ()) {
2626+ const DataLayout &DL = LI->getDataLayout ();
2627+ auto *PtrTy = Addr->getType ();
2628+ auto *StrideTy = DL.getIndexType (PtrTy);
2629+ // TODO: Support non-unit-reverse strided accesses.
2630+ auto *StrideVal =
2631+ ConstantInt::get (StrideTy, -1 * DL.getTypeAllocSize (ScalarDataTy));
2632+ Value *RuntimeVF =
2633+ getRuntimeVF (State.Builder , State.Builder .getInt32Ty (), State.VF );
2634+ NewLI = Builder.CreateIntrinsic (
2635+ Intrinsic::experimental_vp_strided_load, {DataTy, PtrTy, StrideTy},
2636+ {Addr, StrideVal, Mask, RuntimeVF}, nullptr , " wide.strided.load" );
2637+ cast<CallInst>(NewLI)->addParamAttr (
2638+ 0 , Attribute::getWithAlignment (NewLI->getContext (), Alignment));
2639+ } else {
2640+ NewLI = Builder.CreateMaskedLoad (DataTy, Addr, Alignment, Mask,
2641+ PoisonValue::get (DataTy),
2642+ " wide.masked.load" );
2643+ }
26212644 } else {
26222645 NewLI = Builder.CreateAlignedLoad (DataTy, Addr, Alignment, " wide.load" );
26232646 }
@@ -2655,7 +2678,7 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
26552678 Type *ScalarDataTy = getLoadStoreType (&Ingredient);
26562679 auto *DataTy = VectorType::get (ScalarDataTy, State.VF );
26572680 const Align Alignment = getLoadStoreAlignment (&Ingredient);
2658- bool CreateGather = !isConsecutive ();
2681+ bool CreateGather = !isConsecutive () && ! isStrided () ;
26592682
26602683 auto &Builder = State.Builder ;
26612684 State.setDebugLocFrom (getDebugLoc ());
@@ -2675,6 +2698,16 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
26752698 NewLI =
26762699 Builder.CreateIntrinsic (DataTy, Intrinsic::vp_gather, {Addr, Mask, EVL},
26772700 nullptr , " wide.masked.gather" );
2701+ } else if (isStrided ()) {
2702+ const DataLayout &DL = LI->getDataLayout ();
2703+ auto *PtrTy = Addr->getType ();
2704+ auto *StrideTy = DL.getIndexType (PtrTy);
2705+ // TODO: Support non-unit-reverse strided accesses.
2706+ auto *StrideVal =
2707+ ConstantInt::get (StrideTy, -1 * DL.getTypeAllocSize (ScalarDataTy));
2708+ NewLI = Builder.CreateIntrinsic (
2709+ Intrinsic::experimental_vp_strided_load, {DataTy, PtrTy, StrideTy},
2710+ {Addr, StrideVal, Mask, EVL}, nullptr , " wide.strided.load" );
26782711 } else {
26792712 VectorBuilder VBuilder (Builder);
26802713 VBuilder.setEVL (EVL).setMask (Mask);
@@ -2729,13 +2762,15 @@ void VPWidenStoreRecipe::execute(VPTransformState &State) {
27292762 auto *SI = cast<StoreInst>(&Ingredient);
27302763
27312764 VPValue *StoredVPValue = getStoredValue ();
2732- bool CreateScatter = !isConsecutive ();
2765+ bool CreateScatter = !isConsecutive () && ! isStrided () ;
27332766 const Align Alignment = getLoadStoreAlignment (&Ingredient);
27342767
27352768 auto &Builder = State.Builder ;
27362769 State.setDebugLocFrom (getDebugLoc ());
27372770
2738- Value *Mask = nullptr ;
2771+ Value *Mask = isStrided ()
2772+ ? Builder.CreateVectorSplat (State.VF , Builder.getTrue ())
2773+ : nullptr ;
27392774 if (auto *VPMask = getMask ()) {
27402775 // Mask reversal is only needed for non-all-one (null) masks, as reverse
27412776 // of a null all-one mask is a null mask.
@@ -2754,12 +2789,32 @@ void VPWidenStoreRecipe::execute(VPTransformState &State) {
27542789 }
27552790 Value *Addr = State.get (getAddr (), /* IsScalar*/ !CreateScatter);
27562791 Instruction *NewSI = nullptr ;
2757- if (CreateScatter)
2792+ if (CreateScatter) {
27582793 NewSI = Builder.CreateMaskedScatter (StoredVal, Addr, Alignment, Mask);
2759- else if (Mask)
2760- NewSI = Builder.CreateMaskedStore (StoredVal, Addr, Alignment, Mask);
2761- else
2794+ } else if (Mask) {
2795+ if (isStrided ()) {
2796+ const DataLayout &DL = SI->getDataLayout ();
2797+ auto *StoredVecTy = cast<VectorType>(StoredVal->getType ());
2798+ Type *StoredEltTy = StoredVecTy->getElementType ();
2799+ auto *PtrTy = Addr->getType ();
2800+ auto *StrideTy = DL.getIndexType (PtrTy);
2801+ // TODO: Support non-unit-reverse strided accesses.
2802+ auto *StrideVal =
2803+ ConstantInt::get (StrideTy, -1 * DL.getTypeAllocSize (StoredEltTy));
2804+ Value *RuntimeVF =
2805+ getRuntimeVF (State.Builder , State.Builder .getInt32Ty (), State.VF );
2806+ NewSI = Builder.CreateIntrinsic (
2807+ Intrinsic::experimental_vp_strided_store,
2808+ {StoredVecTy, PtrTy, StrideTy},
2809+ {StoredVal, Addr, StrideVal, Mask, RuntimeVF});
2810+ cast<CallInst>(NewSI)->addParamAttr (
2811+ 1 , Attribute::getWithAlignment (NewSI->getContext (), Alignment));
2812+ } else {
2813+ NewSI = Builder.CreateMaskedStore (StoredVal, Addr, Alignment, Mask);
2814+ }
2815+ } else {
27622816 NewSI = Builder.CreateAlignedStore (StoredVal, Addr, Alignment);
2817+ }
27632818 State.addMetadata (NewSI, SI);
27642819}
27652820
@@ -2775,7 +2830,7 @@ void VPWidenStoreEVLRecipe::execute(VPTransformState &State) {
27752830 auto *SI = cast<StoreInst>(&Ingredient);
27762831
27772832 VPValue *StoredValue = getStoredValue ();
2778- bool CreateScatter = !isConsecutive ();
2833+ bool CreateScatter = !isConsecutive () && ! isStrided () ;
27792834 const Align Alignment = getLoadStoreAlignment (&Ingredient);
27802835
27812836 auto &Builder = State.Builder ;
@@ -2800,11 +2855,25 @@ void VPWidenStoreEVLRecipe::execute(VPTransformState &State) {
28002855 Intrinsic::vp_scatter,
28012856 {StoredVal, Addr, Mask, EVL});
28022857 } else {
2803- VectorBuilder VBuilder (Builder);
2804- VBuilder.setEVL (EVL).setMask (Mask);
2805- NewSI = cast<CallInst>(VBuilder.createVectorInstruction (
2806- Instruction::Store, Type::getVoidTy (EVL->getContext ()),
2807- {StoredVal, Addr}));
2858+ if (isStrided ()) {
2859+ const DataLayout &DL = SI->getDataLayout ();
2860+ auto *StoredVecTy = cast<VectorType>(StoredVal->getType ());
2861+ Type *StoredEltTy = StoredVecTy->getElementType ();
2862+ auto *PtrTy = Addr->getType ();
2863+ auto *StrideTy = DL.getIndexType (PtrTy);
2864+ // TODO: Support non-unit-reverse strided accesses.
2865+ auto *StrideVal =
2866+ ConstantInt::get (StrideTy, -1 * DL.getTypeAllocSize (StoredEltTy));
2867+ NewSI = Builder.CreateIntrinsic (Intrinsic::experimental_vp_strided_store,
2868+ {StoredVecTy, PtrTy, StrideTy},
2869+ {StoredVal, Addr, StrideVal, Mask, EVL});
2870+ } else {
2871+ VectorBuilder VBuilder (Builder);
2872+ VBuilder.setEVL (EVL).setMask (Mask);
2873+ NewSI = cast<CallInst>(VBuilder.createVectorInstruction (
2874+ Instruction::Store, Type::getVoidTy (EVL->getContext ()),
2875+ {StoredVal, Addr}));
2876+ }
28082877 }
28092878 NewSI->addParamAttr (
28102879 1 , Attribute::getWithAlignment (NewSI->getContext (), Alignment));
0 commit comments