diff --git a/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp b/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp --- a/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp +++ b/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp @@ -620,10 +620,35 @@ const BufferizationAliasInfo &aliasInfo, const AnalysisState &state) { aliasInfo.applyOnAliases(root, [&](Value alias) { - for (auto &use : alias.getUses()) - // Read to a value that aliases root. - if (state.bufferizesToMemoryRead(use)) + for (auto &use : alias.getUses()) { + // Read of a value that aliases root. + if (state.bufferizesToMemoryRead(use)) { res.insert(&use); + continue; + } + + // Read of a dependent value in the SSA use-def chain. E.g.: + // + // %0 = ... + // %1 = tensor.extract_slice %0 {not_analyzed_yet} + // "read"(%1) + // + // In the above example, getAliasingReads(%0) includes the first OpOperand + // of the tensor.extract_slice op. The extract_slice itself does not read + // but its aliasing result is eventually fed into an op that does. + // + // Note: This is considered a "read" only if the use does not bufferize to + // a memory write. (We already ruled out memory reads. In case of a memory + // write, the buffer would be entirely overwritten; in the above example + // there would then be no flow of data from the extract_slice operand to + // its result's uses.) + if (!state.bufferizesToMemoryWrite(use)) { + SmallVector opResults = state.getAliasingOpResult(use); + if (llvm::any_of(opResults, + [&](OpResult r) { return state.isValueRead(r); })) + res.insert(&use); + } + } }); }