@@ -2127,7 +2127,63 @@ void VPWidenLoadRecipe::print(raw_ostream &O, const Twine &Indent,
21272127 O << " = load " ;
21282128 printOperands (O, SlotTracker);
21292129}
2130+ #endif
2131+
2132+ // / Use all-true mask for reverse rather than actual mask, as it avoids a
2133+ // / dependence w/o affecting the result.
2134+ static Instruction *createReverseEVL (IRBuilderBase &Builder, Value *Operand,
2135+ Value *EVL, const Twine &Name) {
2136+ VectorType *ValTy = cast<VectorType>(Operand->getType ());
2137+ Value *AllTrueMask =
2138+ Builder.CreateVectorSplat (ValTy->getElementCount (), Builder.getTrue ());
2139+ return Builder.CreateIntrinsic (ValTy, Intrinsic::experimental_vp_reverse,
2140+ {Operand, AllTrueMask, EVL}, nullptr , Name);
2141+ }
2142+
2143+ void VPWidenLoadEVLRecipe::execute (VPTransformState &State) {
2144+ assert (State.UF == 1 && " Expected only UF == 1 when vectorizing with "
2145+ " explicit vector length." );
2146+ auto *LI = cast<LoadInst>(&Ingredient);
2147+
2148+ Type *ScalarDataTy = getLoadStoreType (&Ingredient);
2149+ auto *DataTy = VectorType::get (ScalarDataTy, State.VF );
2150+ const Align Alignment = getLoadStoreAlignment (&Ingredient);
2151+ bool CreateGather = !isConsecutive ();
2152+
2153+ auto &Builder = State.Builder ;
2154+ State.setDebugLocFrom (getDebugLoc ());
2155+ CallInst *NewLI;
2156+ Value *EVL = State.get (getEVL (), VPIteration (0 , 0 ));
2157+ Value *Addr = State.get (getAddr (), 0 , !CreateGather);
2158+ Value *Mask = nullptr ;
2159+ if (VPValue *VPMask = getMask ()) {
2160+ Mask = State.get (VPMask, 0 );
2161+ if (isReverse ())
2162+ Mask = createReverseEVL (Builder, Mask, EVL, " vp.reverse.mask" );
2163+ } else {
2164+ Mask = Builder.CreateVectorSplat (State.VF , Builder.getTrue ());
2165+ }
2166+
2167+ if (CreateGather) {
2168+ NewLI =
2169+ Builder.CreateIntrinsic (DataTy, Intrinsic::vp_gather, {Addr, Mask, EVL},
2170+ nullptr , " wide.masked.gather" );
2171+ } else {
2172+ VectorBuilder VBuilder (Builder);
2173+ VBuilder.setEVL (EVL).setMask (Mask);
2174+ NewLI = cast<CallInst>(VBuilder.createVectorInstruction (
2175+ Instruction::Load, DataTy, Addr, " vp.op.load" ));
2176+ }
2177+ NewLI->addParamAttr (
2178+ 0 , Attribute::getWithAlignment (NewLI->getContext (), Alignment));
2179+ State.addMetadata (NewLI, LI);
2180+ Instruction *Res = NewLI;
2181+ if (isReverse ())
2182+ Res = createReverseEVL (Builder, Res, EVL, " vp.reverse" );
2183+ State.set (this , Res, 0 );
2184+ }
21302185
2186+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
21312187void VPWidenLoadEVLRecipe::print (raw_ostream &O, const Twine &Indent,
21322188 VPSlotTracker &SlotTracker) const {
21332189 O << Indent << " WIDEN " ;
@@ -2183,7 +2239,51 @@ void VPWidenStoreRecipe::print(raw_ostream &O, const Twine &Indent,
21832239 O << Indent << " WIDEN store " ;
21842240 printOperands (O, SlotTracker);
21852241}
2242+ #endif
2243+
2244+ void VPWidenStoreEVLRecipe::execute (VPTransformState &State) {
2245+ assert (State.UF == 1 && " Expected only UF == 1 when vectorizing with "
2246+ " explicit vector length." );
2247+ auto *SI = cast<StoreInst>(&Ingredient);
2248+
2249+ VPValue *StoredValue = getStoredValue ();
2250+ bool CreateScatter = !isConsecutive ();
2251+ const Align Alignment = getLoadStoreAlignment (&Ingredient);
2252+
2253+ auto &Builder = State.Builder ;
2254+ State.setDebugLocFrom (getDebugLoc ());
2255+
2256+ CallInst *NewSI = nullptr ;
2257+ Value *StoredVal = State.get (StoredValue, 0 );
2258+ Value *EVL = State.get (getEVL (), VPIteration (0 , 0 ));
2259+ if (isReverse ())
2260+ StoredVal = createReverseEVL (Builder, StoredVal, EVL, " vp.reverse" );
2261+ Value *Mask = nullptr ;
2262+ if (VPValue *VPMask = getMask ()) {
2263+ Mask = State.get (VPMask, 0 );
2264+ if (isReverse ())
2265+ Mask = createReverseEVL (Builder, Mask, EVL, " vp.reverse.mask" );
2266+ } else {
2267+ Mask = Builder.CreateVectorSplat (State.VF , Builder.getTrue ());
2268+ }
2269+ Value *Addr = State.get (getAddr (), 0 , !CreateScatter);
2270+ if (CreateScatter) {
2271+ NewSI = Builder.CreateIntrinsic (Type::getVoidTy (EVL->getContext ()),
2272+ Intrinsic::vp_scatter,
2273+ {StoredVal, Addr, Mask, EVL});
2274+ } else {
2275+ VectorBuilder VBuilder (Builder);
2276+ VBuilder.setEVL (EVL).setMask (Mask);
2277+ NewSI = cast<CallInst>(VBuilder.createVectorInstruction (
2278+ Instruction::Store, Type::getVoidTy (EVL->getContext ()),
2279+ {StoredVal, Addr}));
2280+ }
2281+ NewSI->addParamAttr (
2282+ 1 , Attribute::getWithAlignment (NewSI->getContext (), Alignment));
2283+ State.addMetadata (NewSI, SI);
2284+ }
21862285
2286+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
21872287void VPWidenStoreEVLRecipe::print (raw_ostream &O, const Twine &Indent,
21882288 VPSlotTracker &SlotTracker) const {
21892289 O << Indent << " WIDEN vp.store " ;
0 commit comments