[Mlir-commits] [mlir] [mlir][CSE] fix use-after-free (PR #203849)
Stefan Schuermans
llvmlistbot at llvm.org
Mon Jun 15 01:54:49 PDT 2026
https://github.com/schuermans-roofline created https://github.com/llvm/llvm-project/pull/203849
There was a use-after free introduced accidentally by e79e056ee982 [mlir][CSE] Remove the opsToErase container and immediately delete dead ops. (#203702) This change fixes it.
Locating the use-after-free has been assisted by Claude Code. The implementation of the fix has been done without it.
>From e2fa29a2f499aa2e5af30c0634b0daa14aabe13b Mon Sep 17 00:00:00 2001
From: Stefan Schuermans <schuermans at roofline.ai>
Date: Mon, 15 Jun 2026 10:45:51 +0200
Subject: [PATCH] [mlir][CSE] fix use-after-free
There was a use-after free introduced accidentally by
e79e056ee982 [mlir][CSE] Remove the opsToErase container and immediately delete dead ops. (#203702)
This change fixes it.
Locating the use-after-free has been assisted by Claude Code. The implementation of the fix has been done without it.
Signed-off-by: Stefan Schuermans <schuermans at roofline.ai>
---
mlir/lib/Transforms/Utils/CSE.cpp | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/mlir/lib/Transforms/Utils/CSE.cpp b/mlir/lib/Transforms/Utils/CSE.cpp
index eed77f20dd2da..a5cc2376f4ba8 100644
--- a/mlir/lib/Transforms/Utils/CSE.cpp
+++ b/mlir/lib/Transforms/Utils/CSE.cpp
@@ -126,14 +126,15 @@ void CSEDriver::replaceUsesAndDelete(ScopedMapTy &knownValues, Operation *op,
Operation *existing,
bool hasSSADominance) {
// If we find one then replace all uses of the current operation with the
- // existing one and mark it for deletion. We can only replace an operand in
- // an operation if it has not been visited yet.
+ // existing one and mark it for deletion at the bottom of the function. We
+ // can only replace an operand in an operation if it has not been visited yet.
+ bool opIsDead = false;
if (hasSSADominance) {
// If the region has SSA dominance, then we are guaranteed to have not
// visited any use of the current operation.
// Replace all uses, but do not remove the operation yet.
rewriter.replaceAllOpUsesWith(op, existing->getResults());
- eraseDeadOp(op);
+ opIsDead = true;
} else {
// When the region does not have SSA dominance, we need to check if we
// have visited a use before replacing any use.
@@ -152,8 +153,7 @@ void CSEDriver::replaceUsesAndDelete(ScopedMapTy &knownValues, Operation *op,
wasVisited);
// There may be some remaining uses of the operation.
- if (op->use_empty())
- eraseDeadOp(op);
+ opIsDead = op->use_empty();
}
// If the existing operation has an unknown location and the current
@@ -162,6 +162,11 @@ void CSEDriver::replaceUsesAndDelete(ScopedMapTy &knownValues, Operation *op,
if (isa<UnknownLoc>(existing->getLoc()) && !isa<UnknownLoc>(op->getLoc()))
existing->setLoc(op->getLoc());
+ // Deletion of the dead current op can only be done here, and not before,
+ // because the its location is still read above.
+ if (opIsDead)
+ eraseDeadOp(op);
+
++numCSE;
}
More information about the Mlir-commits
mailing list