[Mlir-commits] [mlir] [mlir][linalg] Prevent hoisting of transfer pairs in the presence of aliases (PR #145235)
Han-Chung Wang
llvmlistbot at llvm.org
Wed Jun 25 10:57:27 PDT 2025
================
@@ -303,23 +303,50 @@ void mlir::linalg::hoistRedundantVectorTransfers(Operation *root,
// 1. indices, vector type and permutation map are the same (i.e., the
// transfer_read/transfer_write ops are matching),
// 2. source operands for transfer.{read|write} do not originate from
- // Ops implementing ViewLikeOpInterface.
+ // nor have users that are Ops implementing ViewLikeOpInterface.
// 3. no other operations in the loop access the same memref except
// for transfer_read/transfer_write accessing statically disjoint
// slices.
+
+ // Check 1.
if (transferRead.getIndices() != transferWrite.getIndices() ||
transferRead.getVectorType() != transferWrite.getVectorType() ||
transferRead.getPermutationMap() != transferWrite.getPermutationMap())
return WalkResult::advance();
- auto *source = transferRead.getBase().getDefiningOp();
- if (source && isa_and_nonnull<ViewLikeOpInterface>(source))
- return WalkResult::advance();
+ // Check 2. Note, since both xfer Ops share the source, we only need to
+ // look at one of them.
+ auto base = transferRead.getBase();
+ auto *source = base.getDefiningOp();
+ if (source) {
+ // NOTE: We treat `memref.assume_alignment` as a special case:
+ // 1. If it has exactly two uses then these have to be the xfer Ops
+ // being looked at.
+ // 2. Otherwise, there are other users that we should take into
+ // account
+ // In the case of 1., it is safe to look past AssumeAlignmentOp,
+ // i.e. at the defining Op of the input MemRef, provided that:
+ // * the original MemRef has only one use (i.e.
+ // `memref.assume_alignment`)
+ if (auto assume = dyn_cast<memref::AssumeAlignmentOp>(source)) {
+ Value memPreAlignment = assume.getMemref();
+ auto numInLoopUses =
+ llvm::count_if(base.getUses(), [&loop](OpOperand &use) {
+ return loop->isAncestor(use.getOwner());
+ });
+
+ if (numInLoopUses && memPreAlignment.hasOneUse())
+ source = memPreAlignment.getDefiningOp();
+ }
+ if (isa_and_nonnull<ViewLikeOpInterface>(source))
+ return WalkResult::advance();
+ }
- source = transferWrite.getBase().getDefiningOp();
- if (source && isa_and_nonnull<ViewLikeOpInterface>(source))
- return WalkResult::advance();
+ for (auto *user : base.getUsers())
+ if (isa_and_nonnull<ViewLikeOpInterface>(user))
+ return WalkResult::advance();
----------------
hanhanW wrote:
optional nit: I'd use any_of and `llvm::IsaPred<>` in this case. (I think the user won't be NULL, so dropping nonnull should be okay.) E.g.,
```cpp
if (llvm::any_of(base.getUsers(), llvm::IsaPred<ViewLikeOpInterface>))
return WalkResult::advance();
```
https://github.com/llvm/llvm-project/pull/145235
More information about the Mlir-commits
mailing list