[Mlir-commits] [mlir] [MLIR][XeGPU] Add distribution pattern for xegpu.load & store for sg to wi pass (PR #181917)
Charitha Saumya
llvmlistbot at llvm.org
Fri Feb 20 13:25:11 PST 2026
================
@@ -522,6 +594,80 @@ struct LowerVectorMultiReductionPattern
}
};
+/// Distributes a subgroup-level StoreScatter (xegpu.store) op to
+/// workitem-level.
+struct SgToWiStoreScatter : public OpConversionPattern<xegpu::StoreScatterOp> {
+ using OpConversionPattern<xegpu::StoreScatterOp>::OpConversionPattern;
+
+ LogicalResult
+ matchAndRewrite(xegpu::StoreScatterOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ xegpu::DistributeLayoutAttr layout = op.getAnchorLayout();
+ if (!layout)
+ return failure();
+
+ VectorType valueTy = op.getValueType();
+ if (!valueTy)
+ return failure();
+
+ // Check that all leading dimensions are unit dimensions.
+ int chunkSize = op.getChunkSize().value_or(1);
+ int effectiveVecRank = (chunkSize == 1) ? 1 : 2;
+ for (int i = 0; i < valueTy.getRank() - effectiveVecRank; i++) {
+ if (valueTy.getShape()[i] != 1)
+ return rewriter.notifyMatchFailure(
+ op, "Only unit dimensions allowed for the leading "
+ "dimensions of the store vector!");
+ }
+
+ auto expectedWiValueTyOrFailure =
+ xegpu::getDistVecTypeBasedOnLaneLayout(layout, valueTy);
+ if (failed(expectedWiValueTyOrFailure))
+ return rewriter.notifyMatchFailure(
+ op,
+ "unable to compute expected workitem vector type from lane layout");
+
+ VectorType expectedWiValueTy = expectedWiValueTyOrFailure.value();
+ VectorType supportedWiValueTy =
+ VectorType::get({expectedWiValueTy.getNumElements()},
+ expectedWiValueTy.getElementType());
+
+ Value adaptedValue = adaptor.getValue();
+ if (adaptedValue.getType() != supportedWiValueTy)
+ adaptedValue =
+ vector::ShapeCastOp::create(rewriter, op.getLoc(), supportedWiValueTy,
+ adaptedValue)
+ .getResult();
+
+ // Flatten offsets and mask to 1D to match the 1D value type.
+ Value offsets = adaptor.getOffsets();
+ if (auto offsetsTy = dyn_cast<VectorType>(offsets.getType())) {
+ VectorType offsetsTy1D = VectorType::get({offsetsTy.getNumElements()},
+ offsetsTy.getElementType());
+ if (offsetsTy != offsetsTy1D)
+ offsets = vector::ShapeCastOp::create(rewriter, op.getLoc(),
+ offsetsTy1D, offsets)
+ .getResult();
+ }
+ Value mask = adaptor.getMask();
+ if (auto maskTy = dyn_cast<VectorType>(mask.getType())) {
+ VectorType maskTy1D =
+ VectorType::get({maskTy.getNumElements()}, maskTy.getElementType());
+ if (maskTy != maskTy1D)
+ mask =
+ vector::ShapeCastOp::create(rewriter, op.getLoc(), maskTy1D, mask)
+ .getResult();
+ }
----------------
charithaintc wrote:
same as above
https://github.com/llvm/llvm-project/pull/181917
More information about the Mlir-commits
mailing list