[Mlir-commits] [mlir] [MLIR][XeGPU] Rename Xe3 uArch to Xe3p and add 2D block memory restrictions (PR #229936)
Charitha Saumya
llvmlistbot at llvm.org
Wed Oct 7 16:51:03 PDT 2026
================
@@ -245,6 +245,116 @@ translateStoreXeGPUCacheHint(std::optional<xegpu::CachePolicy> L1hint,
class CreateNdDescToXeVMPattern
: public OpConversionPattern<xegpu::CreateNdDescOp> {
using OpConversionPattern::OpConversionPattern;
+
+ // A descriptor is lowered before its consumers are known, so a restriction
+ // may only be enforced here if it holds for every 2D block instruction the
+ // target supports. Fold the supported instructions' restrictions into the
+ // weakest common requirement -- the smallest of the minimum sizes and the GCD
+ // of the alignments -- so that a violation means the surface is unusable by
+ // any consumer. Returns std::nullopt if the target has no 2D block
+ // instruction at all.
+ static std::optional<xegpu::uArch::BlockIOMemoryRestrictions>
+ getWeakestBlockIORestrictions(const xegpu::uArch::uArch *uArch) {
+ std::optional<xegpu::uArch::BlockIOMemoryRestrictions> weakest;
+ for (xegpu::uArch::InstructionKind kind :
+ {xegpu::uArch::InstructionKind::Subgroup2DBlockLoad,
+ xegpu::uArch::InstructionKind::Subgroup2DBlockStore,
+ xegpu::uArch::InstructionKind::Subgroup2DBlockPrefetch}) {
+ if (!uArch->isSupportedInstruction(kind))
+ continue;
+ const auto *blockIo =
+ llvm::dyn_cast<xegpu::uArch::BlockIOInstructionInterface>(
+ uArch->getInstruction(kind));
+ if (!blockIo)
+ continue;
+ const xegpu::uArch::BlockIOMemoryRestrictions &r =
+ blockIo->getMemoryRestrictions();
+ if (!weakest) {
+ weakest = r;
+ continue;
+ }
+ weakest->baseAddressAlignmentBytes = std::gcd(
+ weakest->baseAddressAlignmentBytes, r.baseAddressAlignmentBytes);
+ weakest->minBaseWidthBytes =
+ std::min(weakest->minBaseWidthBytes, r.minBaseWidthBytes);
+ weakest->baseWidthAlignmentBytes =
+ std::gcd(weakest->baseWidthAlignmentBytes, r.baseWidthAlignmentBytes);
+ weakest->minBasePitchBytes =
+ std::min(weakest->minBasePitchBytes, r.minBasePitchBytes);
+ weakest->basePitchAlignmentBytes =
+ std::gcd(weakest->basePitchAlignmentBytes, r.basePitchAlignmentBytes);
+ }
+ return weakest;
+ }
+
+ // Checks the surface width and pitch against the target's 2D block memory
+ // restrictions. Only these two are enforced: both are derived from the
+ // source's static shape and strides, whereas the base address alignment is a
+ // property of the allocation that is not visible here. Dimensions that are
+ // only known at runtime are left unchecked -- guarding them inside the kernel
+ // would cost far more than it is worth.
+ LogicalResult
+ checkMemoryRestrictions(xegpu::CreateNdDescOp op, int64_t rank,
+ ConversionPatternRewriter &rewriter) const {
+ const auto *uArch =
+ xegpu::uArch::getUArch(xegpu::getChipStr(op).value_or(""));
+ // Without a known target chip there is no uArch to check against, so the
+ // descriptor must be accepted as-is.
+ if (!uArch)
+ return success();
+ std::optional<xegpu::uArch::BlockIOMemoryRestrictions> limits =
+ getWeakestBlockIORestrictions(uArch);
+ if (!limits)
+ return success();
+
+ // `getMixedSizes` / `getMixedStrides` may only be queried when the op
+ // itself carries the shape and strides, which is the same condition under
+ // which the lowering below trusts them; for a memref with dynamic shape or
+ // strides they are recovered from memref.extract_strided_metadata instead.
+ // Nothing is statically known in that case, so there is nothing to check.
+ auto memrefTy = dyn_cast<MemRefType>(op.getSource().getType());
+ if (memrefTy && !xegpu::hasStaticShapeAndStrides(memrefTy))
+ return success();
+
+ unsigned elemBitSize =
+ op.getType().getElementType().getIntOrFloatBitWidth();
+ // Converts a static number of elements into bytes. Returns std::nullopt if
+ // the count is dynamic, or if it does not land on a byte boundary (possible
+ // for sub-byte element types).
+ auto toBytes = [&](OpFoldResult ofr) -> std::optional<int64_t> {
----------------
charithaintc wrote:
how are sub byte types handled in this calculation. it seems `memref<8x67xi4>` lowers.
https://github.com/llvm/llvm-project/pull/229936
More information about the Mlir-commits
mailing list