@@ -1571,13 +1571,7 @@ class LoopVectorizationCostModel {
1571
1571
// / Returns true if VP intrinsics with explicit vector length support should
1572
1572
// / be generated in the tail folded loop.
1573
1573
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;
1581
1575
}
1582
1576
1583
1577
// / Returns true if the Phi is part of an inloop reduction.
@@ -9388,12 +9382,18 @@ void VPWidenLoadRecipe::execute(VPTransformState &State) {
9388
9382
}
9389
9383
}
9390
9384
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
+
9391
9394
void VPWidenLoadEVLRecipe::execute (VPTransformState &State) {
9392
9395
assert (State.UF == 1 && " Expected only UF == 1 when vectorizing with "
9393
9396
" explicit vector length." );
9394
- // FIXME: Support reverse loading after vp_reverse is added.
9395
- assert (!isReverse () && " Reverse loads are not implemented yet." );
9396
-
9397
9397
auto *LI = cast<LoadInst>(&Ingredient);
9398
9398
9399
9399
Type *ScalarDataTy = getLoadStoreType (&Ingredient);
@@ -9406,9 +9406,15 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
9406
9406
CallInst *NewLI;
9407
9407
Value *EVL = State.get (getEVL (), VPIteration (0 , 0 ));
9408
9408
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
+
9412
9418
if (CreateGather) {
9413
9419
NewLI =
9414
9420
Builder.CreateIntrinsic (DataTy, Intrinsic::vp_gather, {Addr, Mask, EVL},
@@ -9422,7 +9428,13 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) {
9422
9428
NewLI->addParamAttr (
9423
9429
0 , Attribute::getWithAlignment (NewLI->getContext (), Alignment));
9424
9430
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 );
9426
9438
}
9427
9439
9428
9440
void VPWidenStoreRecipe::execute (VPTransformState &State) {
@@ -9468,9 +9480,6 @@ void VPWidenStoreRecipe::execute(VPTransformState &State) {
9468
9480
void VPWidenStoreEVLRecipe::execute (VPTransformState &State) {
9469
9481
assert (State.UF == 1 && " Expected only UF == 1 when vectorizing with "
9470
9482
" explicit vector length." );
9471
- // FIXME: Support reverse loading after vp_reverse is added.
9472
- assert (!isReverse () && " Reverse store are not implemented yet." );
9473
-
9474
9483
auto *SI = cast<StoreInst>(&Ingredient);
9475
9484
9476
9485
VPValue *StoredValue = getStoredValue ();
@@ -9483,10 +9492,19 @@ void VPWidenStoreEVLRecipe::execute(VPTransformState &State) {
9483
9492
CallInst *NewSI = nullptr ;
9484
9493
Value *StoredVal = State.get (StoredValue, 0 );
9485
9494
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
+ }
9490
9508
Value *Addr = State.get (getAddr (), 0 , !CreateScatter);
9491
9509
if (CreateScatter) {
9492
9510
NewSI = Builder.CreateIntrinsic (Type::getVoidTy (EVL->getContext ()),
0 commit comments