[Mlir-commits] [mlir] [mlir][x86] Adds extra pattern for AMX lowering (PR #213228)
Arun Thangamani
llvmlistbot at llvm.org
Fri Jul 31 02:04:14 PDT 2026
https://github.com/arun-thmn created https://github.com/llvm/llvm-project/pull/213228
None
>From f889774c3e00fffef7c00c4a30a6c248c2cf3c6a Mon Sep 17 00:00:00 2001
From: Arun Thangamani <arun.thangamani at intel.com>
Date: Fri, 31 Jul 2026 02:02:53 -0700
Subject: [PATCH] adds extra pattern for AMX lowering
---
.../VectorContractToAMXDotProduct.cpp | 35 ++++++++++++-------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/mlir/lib/Dialect/X86/Transforms/VectorContractToAMXDotProduct.cpp b/mlir/lib/Dialect/X86/Transforms/VectorContractToAMXDotProduct.cpp
index 238d03ce4f6af..28b8542d79cfb 100644
--- a/mlir/lib/Dialect/X86/Transforms/VectorContractToAMXDotProduct.cpp
+++ b/mlir/lib/Dialect/X86/Transforms/VectorContractToAMXDotProduct.cpp
@@ -495,14 +495,16 @@ static SmallVector<Value> createTileZeros(OpBuilder &rewriter, Location loc,
static Value getIndxToLoadStoreFromPckBuffer(
OpBuilder &rewriter, Location loc, Value ivInnerLoop, Value ivOuterLoop,
bool isInnerLoopUBHasOddQuot, bool isInnerLoopUBLarger, bool pack,
- unsigned int blockingFactor) {
+ Value blockStride) {
Value c2 = arith::ConstantIndexOp::create(rewriter, loc, 2);
- Value packOffset =
- arith::ConstantIndexOp::create(rewriter, loc, (16 * blockingFactor));
+ // `blockStride` is the reduction (K) loop step, i.e. the amount by which the
+ // induction variable advances for one K-block. Dividing the induction value
+ // by it yields the K-block index regardless of whether the loop counts
+ // K-elements (step == 16*blockingFactor) or pre-blocked K-tiles (step == 1).
Value quotientInnerLoop =
- arith::DivUIOp::create(rewriter, loc, ivInnerLoop, packOffset);
+ arith::DivUIOp::create(rewriter, loc, ivInnerLoop, blockStride);
Value remInnerLoop = arith::RemUIOp::create(
rewriter, loc, rewriter.getIndexType(), quotientInnerLoop, c2);
@@ -587,8 +589,7 @@ createLoops(OpBuilder &rewriter, Location loc, Value lowerBound,
nLoadIndx, ivNewInnerLoop);
indxToStoreInBuffer = getIndxToLoadStoreFromPckBuffer(
rewriter, loc, ivNewInnerLoop, ivOuterLoop,
- isInnerLoopUBHasOddQuot, isInnerLoopUBLarger, pack,
- blockingFactor);
+ isInnerLoopUBHasOddQuot, isInnerLoopUBLarger, pack, step);
Value indxToLoadFromMatB =
arith::AddIOp::create(rewriter, loc, indxToStoreInBuffer, c1);
indxToLoadFromBuffer =
@@ -653,14 +654,16 @@ createLoops(OpBuilder &rewriter, Location loc, Value lowerBound,
if (!isVnni) {
if (outerLoop) {
if (!pack) {
- Value nLoadIndx = arith::ConstantIndexOp::create(
- rewriter, locNewInnerLoop, offset);
matB = Value();
indxToLoadFromBuffer = c0;
+ // Use the real spill-block induction value (== spillInnerLoop)
+ // together with the loop step so the computed ping-pong slot
+ // matches the prefetch store side for any number of register
+ // blocks, including odd counts (e.g. 96 = 3 blocks). Passing a
+ // constant here mis-parities the slot for odd block counts.
indxToLoadFromBuffer = getIndxToLoadStoreFromPckBuffer(
- rewriter, loc, nLoadIndx, ivOuterLoop,
- isInnerLoopUBHasOddQuot, isInnerLoopUBLarger, pack,
- blockingFactor);
+ rewriter, loc, ivNewInnerLoop, ivOuterLoop,
+ isInnerLoopUBHasOddQuot, isInnerLoopUBLarger, pack, step);
}
} else {
if (!pack) {
@@ -1045,10 +1048,18 @@ struct VectorContractToAMXDotProduct
while (true) {
Operation *parent = current->getParentOfType<scf::ForOp>();
- if (!parent)
+ if (!parent) {
+ // The accumulator initialization can be hoisted above an enclosing
+ // parallel region (scf.parallel/scf.forall) when the register tile
+ // matches the problem size and the M/N register loops fold away. In
+ // that case the reduction loop(s) collected so far are still valid to
+ // rewrite, so stop climbing instead of bailing out.
+ if (!loopLists.empty())
+ break;
return rewriter.notifyMatchFailure(
contractOp,
"Accumulator read and contract op not within scf.for op");
+ }
loopLists.push_back(dyn_cast<scf::ForOp>(parent));
More information about the Mlir-commits
mailing list