From dfac8114e92e911aadd1b5a7713aba864c8d17f3 Mon Sep 17 00:00:00 2001 From: kazhang2 Date: Thu, 17 Sep 2026 16:01:12 +0800 Subject: [PATCH] Fix use-after-free in rock-linalg-align debug logging The LinalgAlignRewriter::drainWorklist logging callbacks print the matched operation's name via op->getName(). The memcpy and reduction rewrite patterns erase their root operation before returning success, so the success callback dereferences freed memory and crashes with an access violation (0xC0000005) inside OperationName::Impl::getName when the pass runs with -debug-only=rock-linalg-align. Snapshot the OperationName before applying the pattern and print from the copy; OperationName does not reference the erased operation's storage. Adds a regression test that erases a memref.copy through the align pass with debug logging enabled. Originally hit via MIGraphX (migraphx_gpu.dll) compiling an ONNX model with ROCMLIR_DEBUG_FLAGS=--debug-only=rock-linalg-align, then minimized to a single rock.fill / threadwise_write_all / memref.copy function. Signed-off-by: kazhang2 --- mlir/lib/Dialect/Rock/Transforms/AlignTiling.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mlir/lib/Dialect/Rock/Transforms/AlignTiling.cpp b/mlir/lib/Dialect/Rock/Transforms/AlignTiling.cpp index 30e7476aabcb..7a468260a7a4 100644 --- a/mlir/lib/Dialect/Rock/Transforms/AlignTiling.cpp +++ b/mlir/lib/Dialect/Rock/Transforms/AlignTiling.cpp @@ -265,11 +265,12 @@ LogicalResult LinalgAlignRewriter::drainWorklist(PatternApplicator &matcher) { Operation *op = worklist.front(); worklist.pop_front(); #ifndef NDEBUG + OperationName opName = op->getName(); auto canApply = [&](const Pattern &pattern) -> bool { LLVM_DEBUG({ logger.startLine() << "Applying pattern " << pattern.getDebugName() << " (matches" << *pattern.getRootKind() << ")" - << " on " << op->getName() << "\n"; + << " on " << opName << "\n"; logger.indent(); }); return true; @@ -279,14 +280,14 @@ LogicalResult LinalgAlignRewriter::drainWorklist(PatternApplicator &matcher) { logger.unindent(); logger.startLine() << "Failed to match the " << pattern.getDebugName() << " pattern (matches " << *pattern.getRootKind() - << ") on " << op->getName() << "\n"; + << ") on " << opName << "\n"; }); }; auto onSuccess = [&](const Pattern &pattern) -> LogicalResult { LLVM_DEBUG({ logger.unindent(); logger.startLine() << "Matched " << pattern.getDebugName() - << " pattern on " << op->getName() << "\n"; + << " pattern on " << opName << "\n"; }); return success(); };