@@ -2127,7 +2127,63 @@ void VPWidenLoadRecipe::print(raw_ostream &O, const Twine &Indent,
2127
2127
O << " = load " ;
2128
2128
printOperands (O, SlotTracker);
2129
2129
}
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
+ }
2130
2185
2186
+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2131
2187
void VPWidenLoadEVLRecipe::print (raw_ostream &O, const Twine &Indent,
2132
2188
VPSlotTracker &SlotTracker) const {
2133
2189
O << Indent << " WIDEN " ;
@@ -2183,7 +2239,51 @@ void VPWidenStoreRecipe::print(raw_ostream &O, const Twine &Indent,
2183
2239
O << Indent << " WIDEN store " ;
2184
2240
printOperands (O, SlotTracker);
2185
2241
}
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
+ }
2186
2285
2286
+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2187
2287
void VPWidenStoreEVLRecipe::print (raw_ostream &O, const Twine &Indent,
2188
2288
VPSlotTracker &SlotTracker) const {
2189
2289
O << Indent << " WIDEN vp.store " ;
0 commit comments