@@ -1571,13 +1571,7 @@ class LoopVectorizationCostModel {
15711571 // / Returns true if VP intrinsics with explicit vector length support should
15721572 // / be generated in the tail folded loop.
15731573 bool foldTailWithEVL () const {
1574- return getTailFoldingStyle () == TailFoldingStyle::DataWithEVL &&
1575- // FIXME: remove this once vp_reverse is supported.
1576- none_of (
1577- WideningDecisions,
1578- [](const std::pair<std::pair<Instruction *, ElementCount>,
1579- std::pair<InstWidening, InstructionCost>>
1580- &Data) { return Data.second .first == CM_Widen_Reverse; });
1574+ return getTailFoldingStyle () == TailFoldingStyle::DataWithEVL;
15811575 }
15821576
15831577 // / Returns true if the Phi is part of an inloop reduction.
@@ -9388,12 +9382,18 @@ void VPWidenLoadRecipe::execute(VPTransformState &State) {
93889382 }
93899383}
93909384
9385+ static Instruction *createReverseEVL (IRBuilderBase &Builder, Value *Operand,
9386+ Value *EVL, const Twine &Name) {
9387+ VectorType *ValTy = cast<VectorType>(Operand->getType ());
9388+ Value *AllTrueMask =
9389+ Builder.CreateVectorSplat (ValTy->getElementCount (), Builder.getTrue ());
9390+ return Builder.CreateIntrinsic (ValTy, Intrinsic::experimental_vp_reverse,
9391+ {Operand, AllTrueMask, EVL}, nullptr , Name);
9392+ }
9393+
93919394void VPWidenLoadEVLRecipe::execute (VPTransformState &State) {
93929395 assert (State.UF == 1 && " Expected only UF == 1 when vectorizing with "
93939396 " explicit vector length." );
9394- // FIXME: Support reverse loading after vp_reverse is added.
9395- assert (!isReverse () && " Reverse loads are not implemented yet." );
9396-
93979397 auto *LI = cast<LoadInst>(&Ingredient);
93989398
93999399 Type *ScalarDataTy = getLoadStoreType (&Ingredient);
@@ -9406,9 +9406,15 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
94069406 CallInst *NewLI;
94079407 Value *EVL = State.get (getEVL (), VPIteration (0 , 0 ));
94089408 Value *Addr = State.get (getAddr (), 0 , !CreateGather);
9409- Value *Mask = getMask ()
9410- ? State.get (getMask (), 0 )
9411- : Builder.CreateVectorSplat (State.VF , Builder.getTrue ());
9409+ Value *Mask = nullptr ;
9410+ if (VPValue *VPMask = getMask ()) {
9411+ Mask = State.get (VPMask, 0 );
9412+ if (isReverse ())
9413+ Mask = createReverseEVL (Builder, Mask, EVL, " vp.reverse.mask" );
9414+ } else {
9415+ Mask = Builder.CreateVectorSplat (State.VF , Builder.getTrue ());
9416+ }
9417+
94129418 if (CreateGather) {
94139419 NewLI =
94149420 Builder.CreateIntrinsic (DataTy, Intrinsic::vp_gather, {Addr, Mask, EVL},
@@ -9422,7 +9428,13 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
94229428 NewLI->addParamAttr (
94239429 0 , Attribute::getWithAlignment (NewLI->getContext (), Alignment));
94249430 State.addMetadata (NewLI, LI);
9425- State.set (this , NewLI, 0 );
9431+ Instruction *Res = NewLI;
9432+ if (isReverse ()) {
9433+ // Use cheap all-true mask for reverse rather than actual mask, it does not
9434+ // affect the result.
9435+ Res = createReverseEVL (Builder, Res, EVL, " vp.reverse" );
9436+ }
9437+ State.set (this , Res, 0 );
94269438}
94279439
94289440void VPWidenStoreRecipe::execute (VPTransformState &State) {
@@ -9468,9 +9480,6 @@ void VPWidenStoreRecipe::execute(VPTransformState &State) {
94689480void VPWidenStoreEVLRecipe::execute (VPTransformState &State) {
94699481 assert (State.UF == 1 && " Expected only UF == 1 when vectorizing with "
94709482 " explicit vector length." );
9471- // FIXME: Support reverse loading after vp_reverse is added.
9472- assert (!isReverse () && " Reverse store are not implemented yet." );
9473-
94749483 auto *SI = cast<StoreInst>(&Ingredient);
94759484
94769485 VPValue *StoredValue = getStoredValue ();
@@ -9483,10 +9492,19 @@ void VPWidenStoreEVLRecipe::execute(VPTransformState &State) {
94839492 CallInst *NewSI = nullptr ;
94849493 Value *StoredVal = State.get (StoredValue, 0 );
94859494 Value *EVL = State.get (getEVL (), VPIteration (0 , 0 ));
9486- // FIXME: Support reverse store after vp_reverse is added.
9487- Value *Mask = getMask ()
9488- ? State.get (getMask (), 0 )
9489- : Builder.CreateVectorSplat (State.VF , Builder.getTrue ());
9495+ if (isReverse ()) {
9496+ // Use cheap all-true mask for reverse rather than actual mask, it does not
9497+ // affect the result.
9498+ StoredVal = createReverseEVL (Builder, StoredVal, EVL, " vp.reverse" );
9499+ }
9500+ Value *Mask = nullptr ;
9501+ if (VPValue *VPMask = getMask ()) {
9502+ Mask = State.get (VPMask, 0 );
9503+ if (isReverse ())
9504+ Mask = createReverseEVL (Builder, Mask, EVL, " vp.reverse.mask" );
9505+ } else {
9506+ Mask = Builder.CreateVectorSplat (State.VF , Builder.getTrue ());
9507+ }
94909508 Value *Addr = State.get (getAddr (), 0 , !CreateScatter);
94919509 if (CreateScatter) {
94929510 NewSI = Builder.CreateIntrinsic (Type::getVoidTy (EVL->getContext ()),
0 commit comments