From 17395b45b102b365e6fb19796223d190b5f2bebf Mon Sep 17 00:00:00 2001
From: Jakob Degen <jakob.e.degen@gmail.com>
Date: Sun, 30 Oct 2022 17:17:25 -0700
Subject: [PATCH] Detect unused files in `src/test/mir-opt` and error on them
 in tidy.

---
 Cargo.lock                                    |   9 ++
 Cargo.toml                                    |   1 +
 src/bootstrap/builder.rs                      |   1 +
 src/bootstrap/check.rs                        |   1 +
 ...c.try_identity.DestinationPropagation.diff |  72 ----------
 ...y.try_identity.DestinationPropagation.diff | 106 --------------
 ..._try.try_identity.SimplifyArmIdentity.diff |  85 ------------
 ....try_identity.SimplifyBranchSame.after.mir |  83 -----------
 ..._try.try_identity.SimplifyLocals.after.mir |  58 --------
 src/tools/compiletest/Cargo.toml              |   1 +
 src/tools/compiletest/src/runtest.rs          | 130 +++++-------------
 src/tools/miropt-test-tools/Cargo.toml        |   7 +
 src/tools/miropt-test-tools/src/lib.rs        |  70 ++++++++++
 src/tools/tidy/Cargo.toml                     |   1 +
 src/tools/tidy/src/lib.rs                     |   1 +
 src/tools/tidy/src/main.rs                    |   1 +
 src/tools/tidy/src/mir_opt_tests.rs           |  37 +++++
 17 files changed, 168 insertions(+), 496 deletions(-)
 delete mode 100644 src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
 delete mode 100644 src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
 delete mode 100644 src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
 delete mode 100644 src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
 delete mode 100644 src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
 create mode 100644 src/tools/miropt-test-tools/Cargo.toml
 create mode 100644 src/tools/miropt-test-tools/src/lib.rs
 create mode 100644 src/tools/tidy/src/mir_opt_tests.rs

diff --git a/Cargo.lock b/Cargo.lock
index dab693419a95d..301167e02cc5d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -816,6 +816,7 @@ dependencies = [
  "lazycell",
  "libc",
  "miow",
+ "miropt-test-tools",
  "regex",
  "rustfix",
  "serde",
@@ -2268,6 +2269,13 @@ dependencies = [
  "ui_test",
 ]
 
+[[package]]
+name = "miropt-test-tools"
+version = "0.1.0"
+dependencies = [
+ "regex",
+]
+
 [[package]]
 name = "new_debug_unreachable"
 version = "1.0.4"
@@ -4920,6 +4928,7 @@ version = "0.1.0"
 dependencies = [
  "cargo_metadata 0.14.0",
  "lazy_static",
+ "miropt-test-tools",
  "regex",
  "walkdir",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index e49fe5e2f6356..13a98eedde867 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,7 @@ members = [
   "src/tools/error_index_generator",
   "src/tools/linkchecker",
   "src/tools/lint-docs",
+  "src/tools/miropt-test-tools",
   "src/tools/rustbook",
   "src/tools/unstable-book-gen",
   "src/tools/tidy",
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index c8285c85d0358..6de3746363337 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -622,6 +622,7 @@ impl<'a> Builder<'a> {
                 check::Clippy,
                 check::Miri,
                 check::CargoMiri,
+                check::MiroptTestTools,
                 check::Rls,
                 check::RustAnalyzer,
                 check::Rustfmt,
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 4450dd7e80f95..2e1bd8d6d1f6d 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -460,6 +460,7 @@ tool_check_step!(Miri, "src/tools/miri", SourceType::InTree);
 tool_check_step!(CargoMiri, "src/tools/miri/cargo-miri", SourceType::InTree);
 tool_check_step!(Rls, "src/tools/rls", SourceType::InTree);
 tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree);
+tool_check_step!(MiroptTestTools, "src/tools/miropt-test-tools", SourceType::InTree);
 
 tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false);
 
diff --git a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
deleted file mode 100644
index c3e503bf2c686..0000000000000
--- a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
+++ /dev/null
@@ -1,72 +0,0 @@
-- // MIR for `try_identity` before DestinationPropagation
-+ // MIR for `try_identity` after DestinationPropagation
-  
-  fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
-      debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:6:17: 6:18
-      let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:6:41: 6:57
-      let _2: u32;                         // in scope 0 at $DIR/simplify_try.rs:7:9: 7:10
-      let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
-      let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-      let mut _5: isize;                   // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let _6: i32;                         // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let mut _7: !;                       // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let mut _8: i32;                     // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let mut _9: i32;                     // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      let _10: u32;                        // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
-      let mut _11: u32;                    // in scope 0 at $DIR/simplify_try.rs:8:8: 8:9
-      scope 1 {
-          debug y => _2;                   // in scope 1 at $DIR/simplify_try.rs:7:9: 7:10
-      }
-      scope 2 {
-          debug err => _6;                 // in scope 2 at $DIR/simplify_try.rs:7:14: 7:15
-          scope 3 {
-              scope 7 {
-                  debug t => _9;           // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
-              }
-              scope 8 {
-                  debug v => _8;           // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
-                  let mut _12: i32;        // in scope 8 at $DIR/simplify_try.rs:7:14: 7:15
-              }
-          }
-      }
-      scope 4 {
-          debug val => _10;                // in scope 4 at $DIR/simplify_try.rs:7:13: 7:15
-          scope 5 {
-          }
-      }
-      scope 6 {
--         debug self => _4;                // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-+         debug self => _0;                // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/simplify_try.rs:7:9: 7:10
--         StorageLive(_3);                 // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
--         StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
--         _4 = _1;                         // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
--         _3 = move _4;                    // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
--         StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
--         _5 = discriminant(_3);           // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-+         _0 = _1;                         // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-+         nop;                             // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-+         _5 = discriminant(_0);           // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-          goto -> bb1;                     // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-      }
-  
-      bb1: {
--         _0 = move _3;                    // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
--         StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
-          StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:9:1: 9:2
-          goto -> bb2;                     // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
-      }
-  
-      bb2: {
-          return;                          // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
deleted file mode 100644
index 83b91309be308..0000000000000
--- a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
+++ /dev/null
@@ -1,106 +0,0 @@
-- // MIR for `try_identity` before DestinationPropagation
-+ // MIR for `try_identity` after DestinationPropagation
-  
-  fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
-      debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
-      let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
-      let _2: u32;                         // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-      let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-      let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-      let mut _5: isize;                   // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
-      let _6: i32;                         // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-      let mut _7: !;                       // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
-      let mut _8: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
-      let mut _9: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
-      let _10: u32;                        // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-      let mut _11: u32;                    // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
-      scope 1 {
--         debug y => _2;                   // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-+         debug y => ((_0 as Ok).0: u32);  // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-      }
-      scope 2 {
-          debug e => _6;                   // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
-          scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
-              debug t => _9;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          }
-          scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
-              debug e => _8;               // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
-          }
-      }
-      scope 3 {
--         debug v => _10;                  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-+         debug v => ((_0 as Ok).0: u32);  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-      }
-      scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
--         debug r => _4;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-+         debug r => _3;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-      }
-  
-      bb0: {
--         StorageLive(_2);                 // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
--         StorageLive(_3);                 // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
--         StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
--         _4 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
--         _3 = move _4;                    // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
--         StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-+         _3 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-+         nop;                             // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-          _5 = discriminant(_3);           // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-          switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
-      }
-  
-      bb1: {
--         StorageLive(_10);                // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
--         _10 = ((_3 as Ok).0: u32);       // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
--         _2 = _10;                        // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
--         StorageDead(_10);                // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
--         StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
--         StorageLive(_11);                // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
--         _11 = _2;                        // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-+         ((_0 as Ok).0: u32) = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-+         nop;                             // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-          Deinit(_0);                      // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
--         ((_0 as Ok).0: u32) = move _11;  // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-          discriminant(_0) = 0;            // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
--         StorageDead(_11);                // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
--         StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-+         nop;                             // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-      }
-  
-      bb3: {
-          StorageLive(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-          nop;                             // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-          StorageLive(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
-          StorageLive(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-          nop;                             // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-          nop;                             // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
-          nop;                             // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
-          Deinit(_0);                      // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-          discriminant(_0) = 1;            // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-          StorageDead(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
-          StorageDead(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
--         StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
--         StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-+         nop;                             // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
deleted file mode 100644
index e025ae7c55111..0000000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
+++ /dev/null
@@ -1,85 +0,0 @@
-- // MIR for `try_identity` before SimplifyArmIdentity
-+ // MIR for `try_identity` after SimplifyArmIdentity
-  
-  fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
-      debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
-      let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
-      let _2: u32;                         // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-      let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-      let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-      let mut _5: isize;                   // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
-      let _6: i32;                         // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-      let mut _7: !;                       // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
-      let mut _8: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
-      let mut _9: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
-      let _10: u32;                        // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-      let mut _11: u32;                    // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
-      scope 1 {
-          debug y => _2;                   // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-      }
-      scope 2 {
-          debug e => _6;                   // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
-          scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
-              debug t => _9;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          }
-          scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
-              debug e => _8;               // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
-          }
-      }
-      scope 3 {
-          debug v => _10;                  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-      }
-      scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
-          debug r => _4;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-          StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-          _4 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-          _3 = move _4;                    // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
-          StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-          _5 = discriminant(_3);           // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-          switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
-      }
-  
-      bb1: {
-          StorageLive(_10);                // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-          _10 = ((_3 as Ok).0: u32);       // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-          _2 = _10;                        // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
-          StorageDead(_10);                // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
-          StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-          StorageLive(_11);                // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-          _11 = _2;                        // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-          Deinit(_0);                      // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-          ((_0 as Ok).0: u32) = move _11;  // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-          discriminant(_0) = 0;            // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-          StorageDead(_11);                // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
-          StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-      }
-  
-      bb3: {
-          StorageLive(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-          _6 = ((_3 as Err).0: i32);       // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-          StorageLive(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
-          StorageLive(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-          _9 = _6;                         // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-          _8 = move _9;                    // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
-          ((_0 as Err).0: i32) = move _8;  // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
-          Deinit(_0);                      // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-          discriminant(_0) = 1;            // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-          StorageDead(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
-          StorageDead(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
-          StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-          StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-          return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-      }
-  }
-  
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
deleted file mode 100644
index eb5af2227ec9b..0000000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
+++ /dev/null
@@ -1,83 +0,0 @@
-// MIR for `try_identity` after SimplifyBranchSame
-
-fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
-    debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
-    let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
-    let _2: u32;                         // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-    let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-    let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-    let mut _5: isize;                   // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
-    let _6: i32;                         // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-    let mut _7: !;                       // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
-    let mut _8: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
-    let mut _9: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
-    let _10: u32;                        // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-    let mut _11: u32;                    // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
-    scope 1 {
-        debug y => _2;                   // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-    }
-    scope 2 {
-        debug e => _6;                   // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
-        scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
-            debug t => _9;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-        }
-        scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
-            debug e => _8;               // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
-        }
-    }
-    scope 3 {
-        debug v => _10;                  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-    }
-    scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
-        debug r => _4;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-    }
-
-    bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-        StorageLive(_3);                 // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-        StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-        _4 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-        _3 = move _4;                    // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
-        StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-        _5 = discriminant(_3);           // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-        switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
-    }
-
-    bb1: {
-        StorageLive(_10);                // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-        _10 = ((_3 as Ok).0: u32);       // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-        _2 = _10;                        // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
-        StorageDead(_10);                // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
-        StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-        StorageLive(_11);                // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-        _11 = _2;                        // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-        Deinit(_0);                      // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        ((_0 as Ok).0: u32) = move _11;  // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        discriminant(_0) = 0;            // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        StorageDead(_11);                // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
-        StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-        return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-    }
-
-    bb2: {
-        unreachable;                     // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-    }
-
-    bb3: {
-        StorageLive(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-        _6 = ((_3 as Err).0: i32);       // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-        StorageLive(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
-        StorageLive(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-        _9 = _6;                         // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-        _8 = move _9;                    // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-        StorageDead(_9);                 // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
-        ((_0 as Err).0: i32) = move _8;  // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
-        Deinit(_0);                      // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-        discriminant(_0) = 1;            // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-        StorageDead(_8);                 // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
-        StorageDead(_6);                 // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
-        StorageDead(_3);                 // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-        StorageDead(_2);                 // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-        return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-    }
-}
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
deleted file mode 100644
index 1efa8a67e5cd1..0000000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
+++ /dev/null
@@ -1,58 +0,0 @@
-// MIR for `try_identity` after SimplifyLocals
-
-fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
-    debug x => _1;                       // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
-    let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
-    let mut _2: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-    let mut _3: isize;                   // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
-    let _4: i32;                         // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-    let mut _5: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
-    let mut _6: i32;                     // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
-    scope 1 {
-        debug y => ((_0 as Ok).0: u32);  // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-    }
-    scope 2 {
-        debug e => _4;                   // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
-        scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
-            debug t => _6;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-        }
-        scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
-            debug e => _5;               // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
-        }
-    }
-    scope 3 {
-        debug v => ((_0 as Ok).0: u32);  // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-    }
-    scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
-        debug r => _2;                   // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-    }
-
-    bb0: {
-        _2 = _1;                         // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-        _3 = discriminant(_2);           // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-        switchInt(move _3) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
-    }
-
-    bb1: {
-        ((_0 as Ok).0: u32) = ((_2 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-        Deinit(_0);                      // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        discriminant(_0) = 0;            // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-        return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-    }
-
-    bb2: {
-        unreachable;                     // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-    }
-
-    bb3: {
-        StorageLive(_4);                 // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
-        StorageLive(_5);                 // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
-        StorageLive(_6);                 // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
-        StorageDead(_6);                 // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
-        Deinit(_0);                      // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-        discriminant(_0) = 1;            // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
-        StorageDead(_5);                 // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
-        StorageDead(_4);                 // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
-        return;                          // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
-    }
-}
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 41f97e4326a90..1911f0f9c941c 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -8,6 +8,7 @@ colored = "2"
 diff = "0.1.10"
 unified-diff = "0.2.1"
 getopts = "0.2"
+miropt-test-tools = { path = "../miropt-test-tools" }
 tracing = "0.1"
 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
 regex = "1.0"
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8af5f1da694b9..c37f81d17071d 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -3399,103 +3399,49 @@ impl<'test> TestCx<'test> {
             }
         }
 
-        for l in test_file_contents.lines() {
-            if l.starts_with("// EMIT_MIR ") {
-                let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
-                let mut test_names = test_name.split(' ');
-                // sometimes we specify two files so that we get a diff between the two files
-                let test_name = test_names.next().unwrap();
-                let mut expected_file;
-                let from_file;
-                let to_file;
-
-                if test_name.ends_with(".diff") {
-                    let trimmed = test_name.trim_end_matches(".diff");
-                    let test_against = format!("{}.after.mir", trimmed);
-                    from_file = format!("{}.before.mir", trimmed);
-                    expected_file = format!("{}{}.diff", trimmed, bit_width);
-                    assert!(
-                        test_names.next().is_none(),
-                        "two mir pass names specified for MIR diff"
-                    );
-                    to_file = Some(test_against);
-                } else if let Some(first_pass) = test_names.next() {
-                    let second_pass = test_names.next().unwrap();
-                    assert!(
-                        test_names.next().is_none(),
-                        "three mir pass names specified for MIR diff"
-                    );
-                    expected_file =
-                        format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass);
-                    let second_file = format!("{}.{}.mir", test_name, second_pass);
-                    from_file = format!("{}.{}.mir", test_name, first_pass);
-                    to_file = Some(second_file);
-                } else {
-                    let ext_re = Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
-                    let cap = ext_re
-                        .captures_iter(test_name)
-                        .next()
-                        .expect("test_name has an invalid extension");
-                    let extension = cap.get(1).unwrap().as_str();
-                    expected_file = format!(
-                        "{}{}{}",
-                        test_name.trim_end_matches(extension),
-                        bit_width,
-                        extension,
-                    );
-                    from_file = test_name.to_string();
-                    assert!(
-                        test_names.next().is_none(),
-                        "two mir pass names specified for MIR dump"
+        let files = miropt_test_tools::files_for_miropt_test(
+            &self.testpaths.file,
+            self.config.get_pointer_width(),
+        );
+
+        for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file } in files {
+            let dumped_string = if let Some(after) = to_file {
+                self.diff_mir_files(from_file.into(), after.into())
+            } else {
+                let mut output_file = PathBuf::new();
+                output_file.push(self.get_mir_dump_dir());
+                output_file.push(&from_file);
+                debug!(
+                    "comparing the contents of: {} with {}",
+                    output_file.display(),
+                    expected_file.display()
+                );
+                if !output_file.exists() {
+                    panic!(
+                        "Output file `{}` from test does not exist, available files are in `{}`",
+                        output_file.display(),
+                        output_file.parent().unwrap().display()
                     );
-                    to_file = None;
-                };
-                if !expected_file.starts_with(&test_crate) {
-                    expected_file = format!("{}.{}", test_crate, expected_file);
                 }
-                let expected_file = test_dir.join(expected_file);
+                self.check_mir_test_timestamp(&from_file, &output_file);
+                let dumped_string = fs::read_to_string(&output_file).unwrap();
+                self.normalize_output(&dumped_string, &[])
+            };
 
-                let dumped_string = if let Some(after) = to_file {
-                    self.diff_mir_files(from_file.into(), after.into())
-                } else {
-                    let mut output_file = PathBuf::new();
-                    output_file.push(self.get_mir_dump_dir());
-                    output_file.push(&from_file);
-                    debug!(
-                        "comparing the contents of: {} with {}",
-                        output_file.display(),
+            if self.config.bless {
+                let _ = std::fs::remove_file(&expected_file);
+                std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
+            } else {
+                if !expected_file.exists() {
+                    panic!("Output file `{}` from test does not exist", expected_file.display());
+                }
+                let expected_string = fs::read_to_string(&expected_file).unwrap();
+                if dumped_string != expected_string {
+                    print!("{}", write_diff(&expected_string, &dumped_string, 3));
+                    panic!(
+                        "Actual MIR output differs from expected MIR output {}",
                         expected_file.display()
                     );
-                    if !output_file.exists() {
-                        panic!(
-                            "Output file `{}` from test does not exist, available files are in `{}`",
-                            output_file.display(),
-                            output_file.parent().unwrap().display()
-                        );
-                    }
-                    self.check_mir_test_timestamp(&from_file, &output_file);
-                    let dumped_string = fs::read_to_string(&output_file).unwrap();
-                    self.normalize_output(&dumped_string, &[])
-                };
-
-                if self.config.bless {
-                    let _ = std::fs::remove_file(&expected_file);
-                    std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
-                } else {
-                    if !expected_file.exists() {
-                        panic!(
-                            "Output file `{}` from test does not exist",
-                            expected_file.display()
-                        );
-                    }
-                    let expected_string = fs::read_to_string(&expected_file).unwrap();
-                    if dumped_string != expected_string {
-                        print!("{}", write_diff(&expected_string, &dumped_string, 3));
-                        panic!(
-                            "Actual MIR output differs from expected MIR output {}",
-                            expected_file.display()
-                        );
-                    }
                 }
             }
         }
diff --git a/src/tools/miropt-test-tools/Cargo.toml b/src/tools/miropt-test-tools/Cargo.toml
new file mode 100644
index 0000000000000..8589a44cf1bab
--- /dev/null
+++ b/src/tools/miropt-test-tools/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "miropt-test-tools"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+regex = "1.0"
diff --git a/src/tools/miropt-test-tools/src/lib.rs b/src/tools/miropt-test-tools/src/lib.rs
new file mode 100644
index 0000000000000..96819d3547b29
--- /dev/null
+++ b/src/tools/miropt-test-tools/src/lib.rs
@@ -0,0 +1,70 @@
+use std::fs;
+
+pub struct MiroptTestFiles {
+    pub expected_file: std::path::PathBuf,
+    pub from_file: String,
+    pub to_file: Option<String>,
+}
+
+pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec<MiroptTestFiles> {
+    let mut out = Vec::new();
+    let test_file_contents = fs::read_to_string(&testfile).unwrap();
+
+    let test_dir = testfile.parent().unwrap();
+    let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace("-", "_");
+
+    let bit_width = if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") {
+        format!(".{}bit", bit_width)
+    } else {
+        String::new()
+    };
+
+    for l in test_file_contents.lines() {
+        if l.starts_with("// EMIT_MIR ") {
+            let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
+            let mut test_names = test_name.split(' ');
+            // sometimes we specify two files so that we get a diff between the two files
+            let test_name = test_names.next().unwrap();
+            let mut expected_file;
+            let from_file;
+            let to_file;
+
+            if test_name.ends_with(".diff") {
+                let trimmed = test_name.trim_end_matches(".diff");
+                let test_against = format!("{}.after.mir", trimmed);
+                from_file = format!("{}.before.mir", trimmed);
+                expected_file = format!("{}{}.diff", trimmed, bit_width);
+                assert!(test_names.next().is_none(), "two mir pass names specified for MIR diff");
+                to_file = Some(test_against);
+            } else if let Some(first_pass) = test_names.next() {
+                let second_pass = test_names.next().unwrap();
+                assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff");
+                expected_file =
+                    format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass);
+                let second_file = format!("{}.{}.mir", test_name, second_pass);
+                from_file = format!("{}.{}.mir", test_name, first_pass);
+                to_file = Some(second_file);
+            } else {
+                let ext_re = regex::Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
+                let cap = ext_re
+                    .captures_iter(test_name)
+                    .next()
+                    .expect("test_name has an invalid extension");
+                let extension = cap.get(1).unwrap().as_str();
+                expected_file =
+                    format!("{}{}{}", test_name.trim_end_matches(extension), bit_width, extension,);
+                from_file = test_name.to_string();
+                assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump");
+                to_file = None;
+            };
+            if !expected_file.starts_with(&test_crate) {
+                expected_file = format!("{}.{}", test_crate, expected_file);
+            }
+            let expected_file = test_dir.join(expected_file);
+
+            out.push(MiroptTestFiles { expected_file, from_file, to_file });
+        }
+    }
+
+    out
+}
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 471d78a2922a0..774c97b7777d2 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -7,6 +7,7 @@ autobins = false
 [dependencies]
 cargo_metadata = "0.14"
 regex = "1"
+miropt-test-tools = { path = "../miropt-test-tools" }
 lazy_static = "1"
 walkdir = "2"
 
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index fc0bce5857233..698e4850bea9b 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -47,6 +47,7 @@ pub mod error_codes_check;
 pub mod errors;
 pub mod extdeps;
 pub mod features;
+pub mod mir_opt_tests;
 pub mod pal;
 pub mod primitive_docs;
 pub mod style;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index ca785042aaa6a..ee883777c31d9 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -64,6 +64,7 @@ fn main() {
         // Checks over tests.
         check!(debug_artifacts, &src_path);
         check!(ui_tests, &src_path);
+        check!(mir_opt_tests, &src_path);
 
         // Checks that only make sense for the compiler.
         check!(errors, &compiler_path);
diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs
new file mode 100644
index 0000000000000..f9e8b55497b58
--- /dev/null
+++ b/src/tools/tidy/src/mir_opt_tests.rs
@@ -0,0 +1,37 @@
+//! Tidy check to ensure that mir opt directories do not have stale files.
+
+use std::collections::HashSet;
+use std::path::{Path, PathBuf};
+
+pub fn check(path: &Path, bad: &mut bool) {
+    let mut rs_files = Vec::<PathBuf>::new();
+    let mut output_files = HashSet::<PathBuf>::new();
+    let files = walkdir::WalkDir::new(&path.join("test/mir-opt")).into_iter();
+
+    for file in files.filter_map(Result::ok).filter(|e| e.file_type().is_file()) {
+        let filepath = file.path();
+        if filepath.extension() == Some("rs".as_ref()) {
+            rs_files.push(filepath.to_owned());
+        } else {
+            output_files.insert(filepath.to_owned());
+        }
+    }
+
+    for file in rs_files {
+        for bw in [32, 64] {
+            for output_file in miropt_test_tools::files_for_miropt_test(&file, bw) {
+                output_files.remove(&output_file.expected_file);
+            }
+        }
+    }
+
+    for extra in output_files {
+        if extra.file_name() != Some("README.md".as_ref()) {
+            tidy_error!(
+                bad,
+                "the following output file is not associated with any mir-opt test, you can remove it: {}",
+                extra.display()
+            );
+        }
+    }
+}