[Mlir-commits] [mlir] [mlir][xegpu] Lower lane_data repack convert_layout to bitcast_shuffle (PR #210837)
Jianhui Li
llvmlistbot at llvm.org
Sat Aug 1 14:01:46 PDT 2026
================
@@ -1665,6 +1665,115 @@ shuffleDataAsLaneLayoutChange(ConversionPatternRewriter &rewriter, Location loc,
return res;
}
+/// Redistributes `src` for a `convert_layout` that repacks the `lane_data`
+/// along dimension `repackDim` between round-robin and contiguous, keeping
+/// `lane_layout` and `order` unchanged. Each lane keeps the same `k` elements
+/// and total bits along `repackDim`, but their assignment to lanes changes, so
+/// a `xegpu.bitcast_shuffle` moves the data across lanes: it converts each run
+/// of `k` elements between the round-robin form `vector<k x iElem>` (each lane
+/// owns `k` strided elements) and the contiguous form `vector<1 x iWide>` (each
+/// lane owns one packed `k * elemBits` value), with a `vector.bitcast` to and
+/// from the original element type on either side.
+///
+/// `inputData`/`targetData` are the `repackDim` `lane_data` of the input and
+/// target layouts; exactly one must be 1 (round-robin) and the other `k`
+/// (contiguous). Returns failure if that does not hold or the packed run would
+/// exceed the widest representable integer (64 bits).
+static FailureOr<Value>
+repackLaneData(ConversionPatternRewriter &rewriter, Location loc, Value src,
+ int64_t repackDim, int64_t inputData, int64_t targetData) {
+ auto srcTy = dyn_cast<VectorType>(src.getType());
+ if (!srcTy)
+ return failure();
+ int64_t rank = srcTy.getRank();
+ Type elemTy = srcTy.getElementType();
+ int64_t elemBits = elemTy.getIntOrFloatBitWidth();
+ int64_t k = srcTy.getShape()[repackDim];
+
+ bool roundRobinToContig = inputData == 1 && targetData == k;
+ bool contigToRoundRobin = inputData == k && targetData == 1;
+ if (!roundRobinToContig && !contigToRoundRobin)
+ return failure();
+
+ int64_t wideBits = k * elemBits;
+ if (wideBits > 64)
+ return failure();
+
+ MLIRContext *ctx = rewriter.getContext();
+ VectorType roundRobinIntTy = VectorType::get({k}, IntegerType::get(ctx, elemBits));
+ VectorType contigIntTy = VectorType::get({1}, IntegerType::get(ctx, wideBits));
+ VectorType runTy = VectorType::get({k}, elemTy);
+
+ // Repacks one run (vector<k x elemTy>) into the target form, returning a
+ // vector<k x elemTy>.
+ auto repackRun = [&](Value run) -> Value {
+ if (roundRobinToContig) {
+ Value asInt =
+ vector::BitCastOp::create(rewriter, loc, roundRobinIntTy, run);
+ Value shuffled =
+ xegpu::BitcastShuffleOp::create(rewriter, loc, contigIntTy, asInt);
+ return vector::BitCastOp::create(rewriter, loc, runTy, shuffled);
+ }
+ Value asWide = vector::BitCastOp::create(rewriter, loc, contigIntTy, run);
----------------
Jianhui-Li wrote:
simplified the code after switching to lane_shuffle
https://github.com/llvm/llvm-project/pull/210837
More information about the Mlir-commits
mailing list