Skip to content

Commit 3dae97c

Browse files
[mlir][bufferization] Fix op dominance bug in rewrite pattern (#74159)
Fixes a bug in `SplitDeallocWhenNotAliasingAnyOther`. This pattern used to generate invalid IR (op dominance error). We never noticed this bug in existing test cases because other patterns and/or foldings were applied afterwards and those rewrites "fixed up" the IR again. (The bug is visible when running `mlir-opt -debug`.) Also add additional comments to the implementation and simplify the code a bit. Apart from the fixed dominance error, this change is NFC. Without this change, buffer deallocation tests will fail when running with #74270.
1 parent 4288fb8 commit 3dae97c

File tree

1 file changed

+31
-24
lines changed

1 file changed

+31
-24
lines changed

mlir/lib/Dialect/Bufferization/Transforms/BufferDeallocationSimplification.cpp

+31-24
Original file line numberDiff line numberDiff line change
@@ -314,44 +314,51 @@ struct SplitDeallocWhenNotAliasingAnyOther
314314

315315
LogicalResult matchAndRewrite(DeallocOp deallocOp,
316316
PatternRewriter &rewriter) const override {
317+
Location loc = deallocOp.getLoc();
317318
if (deallocOp.getMemrefs().size() <= 1)
318319
return failure();
319320

320-
SmallVector<Value> newMemrefs, newConditions, replacements;
321-
DenseSet<Operation *> exceptedUsers;
322-
replacements = deallocOp.getUpdatedConditions();
321+
SmallVector<Value> remainingMemrefs, remainingConditions;
322+
SmallVector<SmallVector<Value>> updatedConditions;
323323
for (auto [memref, cond] :
324324
llvm::zip(deallocOp.getMemrefs(), deallocOp.getConditions())) {
325+
// Check if `memref` can split off into a separate bufferization.dealloc.
325326
if (potentiallyAliasesMemref(aliasAnalysis, deallocOp.getMemrefs(),
326327
memref, true)) {
327-
newMemrefs.push_back(memref);
328-
newConditions.push_back(cond);
328+
// `memref` alias with other memrefs, do not split off.
329+
remainingMemrefs.push_back(memref);
330+
remainingConditions.push_back(cond);
329331
continue;
330332
}
331333

332-
auto newDeallocOp = rewriter.create<DeallocOp>(
333-
deallocOp.getLoc(), memref, cond, deallocOp.getRetained());
334-
replacements = SmallVector<Value>(llvm::map_range(
335-
llvm::zip(replacements, newDeallocOp.getUpdatedConditions()),
336-
[&](auto replAndNew) -> Value {
337-
auto orOp = rewriter.create<arith::OrIOp>(deallocOp.getLoc(),
338-
std::get<0>(replAndNew),
339-
std::get<1>(replAndNew));
340-
exceptedUsers.insert(orOp);
341-
return orOp.getResult();
342-
}));
334+
// Create new bufferization.dealloc op for `memref`.
335+
auto newDeallocOp = rewriter.create<DeallocOp>(loc, memref, cond,
336+
deallocOp.getRetained());
337+
updatedConditions.push_back(
338+
llvm::to_vector(ValueRange(newDeallocOp.getUpdatedConditions())));
343339
}
344340

345-
if (newMemrefs.size() == deallocOp.getMemrefs().size())
341+
// Fail if no memref was split off.
342+
if (remainingMemrefs.size() == deallocOp.getMemrefs().size())
346343
return failure();
347344

348-
rewriter.replaceUsesWithIf(deallocOp.getUpdatedConditions(), replacements,
349-
[&](OpOperand &operand) {
350-
return !exceptedUsers.contains(
351-
operand.getOwner());
352-
});
353-
return updateDeallocIfChanged(deallocOp, newMemrefs, newConditions,
354-
rewriter);
345+
// Create bufferization.dealloc op for all remaining memrefs.
346+
auto newDeallocOp = rewriter.create<DeallocOp>(
347+
loc, remainingMemrefs, remainingConditions, deallocOp.getRetained());
348+
349+
// Bit-or all conditions.
350+
SmallVector<Value> replacements =
351+
llvm::to_vector(ValueRange(newDeallocOp.getUpdatedConditions()));
352+
for (auto additionalConditions : updatedConditions) {
353+
assert(replacements.size() == additionalConditions.size() &&
354+
"expected same number of updated conditions");
355+
for (int64_t i = 0, e = replacements.size(); i < e; ++i) {
356+
replacements[i] = rewriter.create<arith::OrIOp>(
357+
loc, replacements[i], additionalConditions[i]);
358+
}
359+
}
360+
rewriter.replaceOp(deallocOp, replacements);
361+
return success();
355362
}
356363

357364
private:

0 commit comments

Comments
 (0)