[TransformInterpreter] Avoid modifying a region while walking it (#11788)

The current code results in a use-after-free. Fixes
https://github.com/iree-org/iree/pull/11788
diff --git a/llvm-external-projects/iree-dialects/lib/Dialect/LinalgTransform/Passes/TransformInterpreter.cpp b/llvm-external-projects/iree-dialects/lib/Dialect/LinalgTransform/Passes/TransformInterpreter.cpp
index ee8075c..476e914 100644
--- a/llvm-external-projects/iree-dialects/lib/Dialect/LinalgTransform/Passes/TransformInterpreter.cpp
+++ b/llvm-external-projects/iree-dialects/lib/Dialect/LinalgTransform/Passes/TransformInterpreter.cpp
@@ -242,23 +242,31 @@
   }
 
   void runOnOperation() override {
+    SmallVector<Operation *> toDelete;
     getOperation()->walk<WalkOrder::PreOrder>([&](Operation *nestedOp) {
-      if (isa<iree_compiler::IREE::LinalgExt::DoNotDCEOperandsOp>(nestedOp))
-        nestedOp->erase();
-      if (isa<::mlir::transform::TransformOpInterface>(nestedOp)) {
-        nestedOp->erase();
+      if (isa<iree_compiler::IREE::LinalgExt::DoNotDCEOperandsOp>(nestedOp)) {
+        toDelete.push_back(nestedOp);
+      } else if (isa<::mlir::transform::TransformOpInterface>(nestedOp)) {
+        toDelete.push_back(nestedOp);
         return WalkResult::skip();
       }
       return WalkResult::advance();
     });
+    for (auto op : toDelete) {
+      op->erase();
+    }
+    SmallVector<ModuleOp> modulesToDelete;
     // Remove potential empty module after cleanup.
     getOperation()->walk([&](ModuleOp module) {
       if (module.getBodyRegion().hasOneBlock() && module.getBody()->empty()) {
-        module->erase();
+        modulesToDelete.push_back(module);
         return WalkResult::skip();
       }
       return WalkResult::advance();
     });
+    for (auto module : modulesToDelete) {
+      module->erase();
+    }
   }
 };
 } // namespace