about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-abort.diff57
-rw-r--r--tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-unwind.diff57
-rw-r--r--tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff87
-rw-r--r--tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff87
-rw-r--r--tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-abort.diff57
-rw-r--r--tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-unwind.diff57
-rw-r--r--tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-abort.diff45
-rw-r--r--tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-unwind.diff45
-rw-r--r--tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff139
-rw-r--r--tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff139
-rw-r--r--tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-abort.diff54
-rw-r--r--tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-unwind.diff54
-rw-r--r--tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff56
-rw-r--r--tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff56
-rw-r--r--tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-abort.diff26
-rw-r--r--tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-unwind.diff26
-rw-r--r--tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-abort.diff53
-rw-r--r--tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-unwind.diff53
-rw-r--r--tests/mir-opt/jump_threading.rs291
-rw-r--r--tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff98
-rw-r--r--tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff98
21 files changed, 1635 insertions, 0 deletions
diff --git a/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..462cc207785
--- /dev/null
+++ b/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-abort.diff
@@ -0,0 +1,57 @@
+- // MIR for `custom_discr` before JumpThreading
++ // MIR for `custom_discr` after JumpThreading
+  
+  fn custom_discr(_1: bool) -> u8 {
+      debug x => _1;
+      let mut _0: u8;
+      let mut _2: CustomDiscr;
+      let mut _3: bool;
+      let mut _4: u8;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = _1;
+          switchInt(move _3) -> [0: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          _2 = CustomDiscr::A;
+-         goto -> bb3;
++         goto -> bb7;
+      }
+  
+      bb2: {
+          _2 = CustomDiscr::B;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_3);
+          _4 = discriminant(_2);
+-         switchInt(move _4) -> [35: bb5, otherwise: bb4];
++         goto -> bb4;
+      }
+  
+      bb4: {
+          _0 = const 13_u8;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          _0 = const 5_u8;
+          goto -> bb6;
+      }
+  
+      bb6: {
+          StorageDead(_2);
+          return;
++     }
++ 
++     bb7: {
++         StorageDead(_3);
++         _4 = discriminant(_2);
++         goto -> bb5;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..462cc207785
--- /dev/null
+++ b/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-unwind.diff
@@ -0,0 +1,57 @@
+- // MIR for `custom_discr` before JumpThreading
++ // MIR for `custom_discr` after JumpThreading
+  
+  fn custom_discr(_1: bool) -> u8 {
+      debug x => _1;
+      let mut _0: u8;
+      let mut _2: CustomDiscr;
+      let mut _3: bool;
+      let mut _4: u8;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = _1;
+          switchInt(move _3) -> [0: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          _2 = CustomDiscr::A;
+-         goto -> bb3;
++         goto -> bb7;
+      }
+  
+      bb2: {
+          _2 = CustomDiscr::B;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_3);
+          _4 = discriminant(_2);
+-         switchInt(move _4) -> [35: bb5, otherwise: bb4];
++         goto -> bb4;
+      }
+  
+      bb4: {
+          _0 = const 13_u8;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          _0 = const 5_u8;
+          goto -> bb6;
+      }
+  
+      bb6: {
+          StorageDead(_2);
+          return;
++     }
++ 
++     bb7: {
++         StorageDead(_3);
++         _4 = discriminant(_2);
++         goto -> bb5;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..bad733268a3
--- /dev/null
+++ b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff
@@ -0,0 +1,87 @@
+- // MIR for `dfa` before JumpThreading
++ // MIR for `dfa` after JumpThreading
+  
+  fn dfa() -> () {
+      let mut _0: ();
+      let mut _1: DFA;
+      let mut _2: !;
+      let mut _3: ();
+      let mut _4: isize;
+      let mut _5: DFA;
+      let mut _6: DFA;
+      let mut _7: DFA;
+      let mut _8: !;
+      scope 1 {
+          debug state => _1;
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          _1 = DFA::A;
+          StorageLive(_2);
+-         goto -> bb1;
++         goto -> bb7;
+      }
+  
+      bb1: {
+          _4 = discriminant(_1);
+-         switchInt(move _4) -> [0: bb4, 1: bb5, 2: bb6, 3: bb2, otherwise: bb3];
++         goto -> bb2;
+      }
+  
+      bb2: {
+          _0 = const ();
+          StorageDead(_2);
+          StorageDead(_1);
+          return;
+      }
+  
+      bb3: {
+          unreachable;
+      }
+  
+      bb4: {
+          StorageLive(_5);
+          _5 = DFA::B;
+          _1 = move _5;
+          _3 = const ();
+          StorageDead(_5);
+-         goto -> bb1;
++         goto -> bb8;
+      }
+  
+      bb5: {
+          StorageLive(_6);
+          _6 = DFA::C;
+          _1 = move _6;
+          _3 = const ();
+          StorageDead(_6);
+-         goto -> bb1;
++         goto -> bb9;
+      }
+  
+      bb6: {
+          StorageLive(_7);
+          _7 = DFA::D;
+          _1 = move _7;
+          _3 = const ();
+          StorageDead(_7);
+          goto -> bb1;
++     }
++ 
++     bb7: {
++         _4 = discriminant(_1);
++         goto -> bb4;
++     }
++ 
++     bb8: {
++         _4 = discriminant(_1);
++         goto -> bb5;
++     }
++ 
++     bb9: {
++         _4 = discriminant(_1);
++         goto -> bb6;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..bad733268a3
--- /dev/null
+++ b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff
@@ -0,0 +1,87 @@
+- // MIR for `dfa` before JumpThreading
++ // MIR for `dfa` after JumpThreading
+  
+  fn dfa() -> () {
+      let mut _0: ();
+      let mut _1: DFA;
+      let mut _2: !;
+      let mut _3: ();
+      let mut _4: isize;
+      let mut _5: DFA;
+      let mut _6: DFA;
+      let mut _7: DFA;
+      let mut _8: !;
+      scope 1 {
+          debug state => _1;
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          _1 = DFA::A;
+          StorageLive(_2);
+-         goto -> bb1;
++         goto -> bb7;
+      }
+  
+      bb1: {
+          _4 = discriminant(_1);
+-         switchInt(move _4) -> [0: bb4, 1: bb5, 2: bb6, 3: bb2, otherwise: bb3];
++         goto -> bb2;
+      }
+  
+      bb2: {
+          _0 = const ();
+          StorageDead(_2);
+          StorageDead(_1);
+          return;
+      }
+  
+      bb3: {
+          unreachable;
+      }
+  
+      bb4: {
+          StorageLive(_5);
+          _5 = DFA::B;
+          _1 = move _5;
+          _3 = const ();
+          StorageDead(_5);
+-         goto -> bb1;
++         goto -> bb8;
+      }
+  
+      bb5: {
+          StorageLive(_6);
+          _6 = DFA::C;
+          _1 = move _6;
+          _3 = const ();
+          StorageDead(_6);
+-         goto -> bb1;
++         goto -> bb9;
+      }
+  
+      bb6: {
+          StorageLive(_7);
+          _7 = DFA::D;
+          _1 = move _7;
+          _3 = const ();
+          StorageDead(_7);
+          goto -> bb1;
++     }
++ 
++     bb7: {
++         _4 = discriminant(_1);
++         goto -> bb4;
++     }
++ 
++     bb8: {
++         _4 = discriminant(_1);
++         goto -> bb5;
++     }
++ 
++     bb9: {
++         _4 = discriminant(_1);
++         goto -> bb6;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..d3f737b324c
--- /dev/null
+++ b/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-abort.diff
@@ -0,0 +1,57 @@
+- // MIR for `disappearing_bb` before JumpThreading
++ // MIR for `disappearing_bb` after JumpThreading
+  
+  fn disappearing_bb(_1: u8) -> u8 {
+      let mut _0: u8;
+      let mut _2: i8;
+      let mut _3: bool;
+      let mut _4: bool;
+  
+      bb0: {
+          _4 = const false;
+          _3 = const false;
+          _4 = const true;
+          _3 = const true;
+          switchInt(_1) -> [0: bb3, 1: bb3, 2: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _3 = const false;
+-         goto -> bb4;
++         goto -> bb9;
+      }
+  
+      bb2: {
+          unreachable;
+      }
+  
+      bb3: {
+          _4 = const false;
+          goto -> bb4;
+      }
+  
+      bb4: {
+          switchInt(_3) -> [0: bb5, otherwise: bb7];
+      }
+  
+      bb5: {
+          switchInt(_4) -> [0: bb6, otherwise: bb8];
+      }
+  
+      bb6: {
+          return;
+      }
+  
+      bb7: {
+          goto -> bb5;
+      }
+  
+      bb8: {
+          goto -> bb6;
++     }
++ 
++     bb9: {
++         goto -> bb5;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..d3f737b324c
--- /dev/null
+++ b/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-unwind.diff
@@ -0,0 +1,57 @@
+- // MIR for `disappearing_bb` before JumpThreading
++ // MIR for `disappearing_bb` after JumpThreading
+  
+  fn disappearing_bb(_1: u8) -> u8 {
+      let mut _0: u8;
+      let mut _2: i8;
+      let mut _3: bool;
+      let mut _4: bool;
+  
+      bb0: {
+          _4 = const false;
+          _3 = const false;
+          _4 = const true;
+          _3 = const true;
+          switchInt(_1) -> [0: bb3, 1: bb3, 2: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _3 = const false;
+-         goto -> bb4;
++         goto -> bb9;
+      }
+  
+      bb2: {
+          unreachable;
+      }
+  
+      bb3: {
+          _4 = const false;
+          goto -> bb4;
+      }
+  
+      bb4: {
+          switchInt(_3) -> [0: bb5, otherwise: bb7];
+      }
+  
+      bb5: {
+          switchInt(_4) -> [0: bb6, otherwise: bb8];
+      }
+  
+      bb6: {
+          return;
+      }
+  
+      bb7: {
+          goto -> bb5;
+      }
+  
+      bb8: {
+          goto -> bb6;
++     }
++ 
++     bb9: {
++         goto -> bb5;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..adcedfb3667
--- /dev/null
+++ b/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-abort.diff
@@ -0,0 +1,45 @@
+- // MIR for `duplicate_chain` before JumpThreading
++ // MIR for `duplicate_chain` after JumpThreading
+  
+  fn duplicate_chain(_1: bool) -> u8 {
+      let mut _0: u8;
+      let mut _2: u8;
+      let mut _3: i32;
+      let mut _4: i32;
+  
+      bb0: {
+          switchInt(_1) -> [1: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _2 = const 5_u8;
+          goto -> bb3;
+      }
+  
+      bb2: {
+          _2 = const 5_u8;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          _3 = const 13_i32;
+          goto -> bb4;
+      }
+  
+      bb4: {
+          _4 = const 15_i32;
+-         switchInt(_2) -> [5: bb5, otherwise: bb6];
++         goto -> bb5;
+      }
+  
+      bb5: {
+          _0 = const 7_u8;
+          return;
+      }
+  
+      bb6: {
+          _0 = const 9_u8;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..adcedfb3667
--- /dev/null
+++ b/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-unwind.diff
@@ -0,0 +1,45 @@
+- // MIR for `duplicate_chain` before JumpThreading
++ // MIR for `duplicate_chain` after JumpThreading
+  
+  fn duplicate_chain(_1: bool) -> u8 {
+      let mut _0: u8;
+      let mut _2: u8;
+      let mut _3: i32;
+      let mut _4: i32;
+  
+      bb0: {
+          switchInt(_1) -> [1: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _2 = const 5_u8;
+          goto -> bb3;
+      }
+  
+      bb2: {
+          _2 = const 5_u8;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          _3 = const 13_i32;
+          goto -> bb4;
+      }
+  
+      bb4: {
+          _4 = const 15_i32;
+-         switchInt(_2) -> [5: bb5, otherwise: bb6];
++         goto -> bb5;
+      }
+  
+      bb5: {
+          _0 = const 7_u8;
+          return;
+      }
+  
+      bb6: {
+          _0 = const 9_u8;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..f17c9ba3f9f
--- /dev/null
+++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff
@@ -0,0 +1,139 @@
+- // MIR for `identity` before JumpThreading
++ // MIR for `identity` after JumpThreading
+  
+  fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
+      debug x => _1;
+      let mut _0: std::result::Result<i32, i32>;
+      let mut _2: i32;
+      let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>;
+      let mut _4: std::result::Result<i32, i32>;
+      let mut _5: isize;
+      let _6: std::result::Result<std::convert::Infallible, i32>;
+      let mut _7: !;
+      let mut _8: std::result::Result<std::convert::Infallible, i32>;
+      let _9: i32;
+      scope 1 {
+          debug residual => _6;
+          scope 2 {
+              scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) {
+                  debug residual => _8;
+                  let _14: i32;
+                  let mut _15: i32;
+                  scope 9 {
+                      debug e => _14;
+                      scope 10 (inlined <i32 as From<i32>>::from) {
+                          debug t => _14;
+                      }
+                  }
+              }
+          }
+      }
+      scope 3 {
+          debug val => _9;
+          scope 4 {
+          }
+      }
+      scope 5 (inlined <Result<i32, i32> as Try>::branch) {
+          debug self => _4;
+          let mut _10: isize;
+          let _11: i32;
+          let _12: i32;
+          let mut _13: std::result::Result<std::convert::Infallible, i32>;
+          scope 6 {
+              debug v => _11;
+          }
+          scope 7 {
+              debug e => _12;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _4 = _1;
+          StorageLive(_10);
+          StorageLive(_11);
+          StorageLive(_12);
+          _10 = discriminant(_4);
+          switchInt(move _10) -> [0: bb8, 1: bb6, otherwise: bb7];
+      }
+  
+      bb1: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageDead(_10);
+          StorageDead(_4);
+          _5 = discriminant(_3);
+-         switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3];
++         goto -> bb2;
+      }
+  
+      bb2: {
+          StorageLive(_9);
+          _9 = ((_3 as Continue).0: i32);
+          _2 = _9;
+          StorageDead(_9);
+          _0 = Result::<i32, i32>::Ok(move _2);
+          StorageDead(_2);
+          StorageDead(_3);
+          goto -> bb5;
+      }
+  
+      bb3: {
+          unreachable;
+      }
+  
+      bb4: {
+          StorageLive(_6);
+          _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>);
+          StorageLive(_8);
+          _8 = _6;
+          StorageLive(_14);
+          _14 = move ((_8 as Err).0: i32);
+          StorageLive(_15);
+          _15 = move _14;
+          _0 = Result::<i32, i32>::Err(move _15);
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageDead(_8);
+          StorageDead(_6);
+          StorageDead(_2);
+          StorageDead(_3);
+          goto -> bb5;
+      }
+  
+      bb5: {
+          return;
+      }
+  
+      bb6: {
+          _12 = move ((_4 as Err).0: i32);
+          StorageLive(_13);
+          _13 = Result::<Infallible, i32>::Err(move _12);
+          _3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _13);
+          StorageDead(_13);
+-         goto -> bb1;
++         goto -> bb9;
+      }
+  
+      bb7: {
+          unreachable;
+      }
+  
+      bb8: {
+          _11 = move ((_4 as Ok).0: i32);
+          _3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _11);
+          goto -> bb1;
++     }
++ 
++     bb9: {
++         StorageDead(_12);
++         StorageDead(_11);
++         StorageDead(_10);
++         StorageDead(_4);
++         _5 = discriminant(_3);
++         goto -> bb4;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..f17c9ba3f9f
--- /dev/null
+++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff
@@ -0,0 +1,139 @@
+- // MIR for `identity` before JumpThreading
++ // MIR for `identity` after JumpThreading
+  
+  fn identity(_1: Result<i32, i32>) -> Result<i32, i32> {
+      debug x => _1;
+      let mut _0: std::result::Result<i32, i32>;
+      let mut _2: i32;
+      let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>;
+      let mut _4: std::result::Result<i32, i32>;
+      let mut _5: isize;
+      let _6: std::result::Result<std::convert::Infallible, i32>;
+      let mut _7: !;
+      let mut _8: std::result::Result<std::convert::Infallible, i32>;
+      let _9: i32;
+      scope 1 {
+          debug residual => _6;
+          scope 2 {
+              scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) {
+                  debug residual => _8;
+                  let _14: i32;
+                  let mut _15: i32;
+                  scope 9 {
+                      debug e => _14;
+                      scope 10 (inlined <i32 as From<i32>>::from) {
+                          debug t => _14;
+                      }
+                  }
+              }
+          }
+      }
+      scope 3 {
+          debug val => _9;
+          scope 4 {
+          }
+      }
+      scope 5 (inlined <Result<i32, i32> as Try>::branch) {
+          debug self => _4;
+          let mut _10: isize;
+          let _11: i32;
+          let _12: i32;
+          let mut _13: std::result::Result<std::convert::Infallible, i32>;
+          scope 6 {
+              debug v => _11;
+          }
+          scope 7 {
+              debug e => _12;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _4 = _1;
+          StorageLive(_10);
+          StorageLive(_11);
+          StorageLive(_12);
+          _10 = discriminant(_4);
+          switchInt(move _10) -> [0: bb8, 1: bb6, otherwise: bb7];
+      }
+  
+      bb1: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageDead(_10);
+          StorageDead(_4);
+          _5 = discriminant(_3);
+-         switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3];
++         goto -> bb2;
+      }
+  
+      bb2: {
+          StorageLive(_9);
+          _9 = ((_3 as Continue).0: i32);
+          _2 = _9;
+          StorageDead(_9);
+          _0 = Result::<i32, i32>::Ok(move _2);
+          StorageDead(_2);
+          StorageDead(_3);
+          goto -> bb5;
+      }
+  
+      bb3: {
+          unreachable;
+      }
+  
+      bb4: {
+          StorageLive(_6);
+          _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>);
+          StorageLive(_8);
+          _8 = _6;
+          StorageLive(_14);
+          _14 = move ((_8 as Err).0: i32);
+          StorageLive(_15);
+          _15 = move _14;
+          _0 = Result::<i32, i32>::Err(move _15);
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageDead(_8);
+          StorageDead(_6);
+          StorageDead(_2);
+          StorageDead(_3);
+          goto -> bb5;
+      }
+  
+      bb5: {
+          return;
+      }
+  
+      bb6: {
+          _12 = move ((_4 as Err).0: i32);
+          StorageLive(_13);
+          _13 = Result::<Infallible, i32>::Err(move _12);
+          _3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _13);
+          StorageDead(_13);
+-         goto -> bb1;
++         goto -> bb9;
+      }
+  
+      bb7: {
+          unreachable;
+      }
+  
+      bb8: {
+          _11 = move ((_4 as Ok).0: i32);
+          _3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _11);
+          goto -> bb1;
++     }
++ 
++     bb9: {
++         StorageDead(_12);
++         StorageDead(_11);
++         StorageDead(_10);
++         StorageDead(_4);
++         _5 = discriminant(_3);
++         goto -> bb4;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..2ca03e439a0
--- /dev/null
+++ b/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-abort.diff
@@ -0,0 +1,54 @@
+- // MIR for `multiple_match` before JumpThreading
++ // MIR for `multiple_match` after JumpThreading
+  
+  fn multiple_match(_1: u8) -> u8 {
+      let mut _0: u8;
+      let mut _2: u8;
+      let mut _3: u8;
+  
+      bb0: {
+          switchInt(_1) -> [3: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _2 = _1;
+-         switchInt(_2) -> [3: bb3, otherwise: bb4];
++         goto -> bb3;
+      }
+  
+      bb2: {
+          _3 = _1;
+-         switchInt(_3) -> [3: bb5, otherwise: bb6];
++         goto -> bb6;
+      }
+  
+      bb3: {
+          _0 = const 5_u8;
+          return;
+      }
+  
+      bb4: {
+          _0 = const 7_u8;
+          return;
+      }
+  
+      bb5: {
+          _0 = const 9_u8;
+          return;
+      }
+  
+      bb6: {
+          switchInt(_3) -> [1: bb7, otherwise: bb8];
+      }
+  
+      bb7: {
+          _0 = const 9_u8;
+          return;
+      }
+  
+      bb8: {
+          _0 = const 11_u8;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..2ca03e439a0
--- /dev/null
+++ b/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-unwind.diff
@@ -0,0 +1,54 @@
+- // MIR for `multiple_match` before JumpThreading
++ // MIR for `multiple_match` after JumpThreading
+  
+  fn multiple_match(_1: u8) -> u8 {
+      let mut _0: u8;
+      let mut _2: u8;
+      let mut _3: u8;
+  
+      bb0: {
+          switchInt(_1) -> [3: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _2 = _1;
+-         switchInt(_2) -> [3: bb3, otherwise: bb4];
++         goto -> bb3;
+      }
+  
+      bb2: {
+          _3 = _1;
+-         switchInt(_3) -> [3: bb5, otherwise: bb6];
++         goto -> bb6;
+      }
+  
+      bb3: {
+          _0 = const 5_u8;
+          return;
+      }
+  
+      bb4: {
+          _0 = const 7_u8;
+          return;
+      }
+  
+      bb5: {
+          _0 = const 9_u8;
+          return;
+      }
+  
+      bb6: {
+          switchInt(_3) -> [1: bb7, otherwise: bb8];
+      }
+  
+      bb7: {
+          _0 = const 9_u8;
+          return;
+      }
+  
+      bb8: {
+          _0 = const 11_u8;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..80a42263643
--- /dev/null
+++ b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff
@@ -0,0 +1,56 @@
+- // MIR for `mutable_ref` before JumpThreading
++ // MIR for `mutable_ref` after JumpThreading
+  
+  fn mutable_ref() -> bool {
+      let mut _0: bool;
+      let mut _1: i32;
+      let _3: ();
+      let mut _4: bool;
+      let mut _5: i32;
+      scope 1 {
+          debug x => _1;
+          let _2: *mut i32;
+          scope 2 {
+              debug a => _2;
+              scope 3 {
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          _1 = const 5_i32;
+          StorageLive(_2);
+          _2 = &raw mut _1;
+          _1 = const 7_i32;
+          StorageLive(_3);
+          (*_2) = const 8_i32;
+          _3 = const ();
+          StorageDead(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          _5 = _1;
+          _4 = Eq(move _5, const 7_i32);
+          switchInt(move _4) -> [0: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          StorageDead(_5);
+          _0 = const true;
+          goto -> bb3;
+      }
+  
+      bb2: {
+          StorageDead(_5);
+          _0 = const false;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_4);
+          StorageDead(_2);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..80a42263643
--- /dev/null
+++ b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff
@@ -0,0 +1,56 @@
+- // MIR for `mutable_ref` before JumpThreading
++ // MIR for `mutable_ref` after JumpThreading
+  
+  fn mutable_ref() -> bool {
+      let mut _0: bool;
+      let mut _1: i32;
+      let _3: ();
+      let mut _4: bool;
+      let mut _5: i32;
+      scope 1 {
+          debug x => _1;
+          let _2: *mut i32;
+          scope 2 {
+              debug a => _2;
+              scope 3 {
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          _1 = const 5_i32;
+          StorageLive(_2);
+          _2 = &raw mut _1;
+          _1 = const 7_i32;
+          StorageLive(_3);
+          (*_2) = const 8_i32;
+          _3 = const ();
+          StorageDead(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          _5 = _1;
+          _4 = Eq(move _5, const 7_i32);
+          switchInt(move _4) -> [0: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          StorageDead(_5);
+          _0 = const true;
+          goto -> bb3;
+      }
+  
+      bb2: {
+          StorageDead(_5);
+          _0 = const false;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_4);
+          StorageDead(_2);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..8821b47c345
--- /dev/null
+++ b/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-abort.diff
@@ -0,0 +1,26 @@
+- // MIR for `mutate_discriminant` before JumpThreading
++ // MIR for `mutate_discriminant` after JumpThreading
+  
+  fn mutate_discriminant() -> u8 {
+      let mut _0: u8;
+      let mut _1: std::option::Option<NonZeroUsize>;
+      let mut _2: isize;
+  
+      bb0: {
+          discriminant(_1) = 1;
+          (((_1 as variant#1).0: NonZeroUsize).0: usize) = const 0_usize;
+          _2 = discriminant(_1);
+          switchInt(_2) -> [0: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _0 = const 1_u8;
+          return;
+      }
+  
+      bb2: {
+          _0 = const 2_u8;
+          unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..8821b47c345
--- /dev/null
+++ b/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-unwind.diff
@@ -0,0 +1,26 @@
+- // MIR for `mutate_discriminant` before JumpThreading
++ // MIR for `mutate_discriminant` after JumpThreading
+  
+  fn mutate_discriminant() -> u8 {
+      let mut _0: u8;
+      let mut _1: std::option::Option<NonZeroUsize>;
+      let mut _2: isize;
+  
+      bb0: {
+          discriminant(_1) = 1;
+          (((_1 as variant#1).0: NonZeroUsize).0: usize) = const 0_usize;
+          _2 = discriminant(_1);
+          switchInt(_2) -> [0: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _0 = const 1_u8;
+          return;
+      }
+  
+      bb2: {
+          _0 = const 2_u8;
+          unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..20f6861e8db
--- /dev/null
+++ b/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-abort.diff
@@ -0,0 +1,53 @@
+- // MIR for `renumbered_bb` before JumpThreading
++ // MIR for `renumbered_bb` after JumpThreading
+  
+  fn renumbered_bb(_1: bool) -> u8 {
+      let mut _0: u8;
+      let mut _2: bool;
+      let mut _3: bool;
+  
+      bb0: {
+          _3 = const false;
+          switchInt(_1) -> [1: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _2 = const false;
+-         goto -> bb3;
++         goto -> bb8;
+      }
+  
+      bb2: {
+          _2 = _1;
+          _3 = _1;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          switchInt(_2) -> [0: bb4, otherwise: bb5];
+      }
+  
+      bb4: {
+          switchInt(_3) -> [0: bb6, otherwise: bb7];
+      }
+  
+      bb5: {
+          _0 = const 7_u8;
+          return;
+      }
+  
+      bb6: {
+          _0 = const 9_u8;
+          return;
+      }
+  
+      bb7: {
+          _0 = const 11_u8;
+          return;
++     }
++ 
++     bb8: {
++         goto -> bb4;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..20f6861e8db
--- /dev/null
+++ b/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-unwind.diff
@@ -0,0 +1,53 @@
+- // MIR for `renumbered_bb` before JumpThreading
++ // MIR for `renumbered_bb` after JumpThreading
+  
+  fn renumbered_bb(_1: bool) -> u8 {
+      let mut _0: u8;
+      let mut _2: bool;
+      let mut _3: bool;
+  
+      bb0: {
+          _3 = const false;
+          switchInt(_1) -> [1: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _2 = const false;
+-         goto -> bb3;
++         goto -> bb8;
+      }
+  
+      bb2: {
+          _2 = _1;
+          _3 = _1;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          switchInt(_2) -> [0: bb4, otherwise: bb5];
+      }
+  
+      bb4: {
+          switchInt(_3) -> [0: bb6, otherwise: bb7];
+      }
+  
+      bb5: {
+          _0 = const 7_u8;
+          return;
+      }
+  
+      bb6: {
+          _0 = const 9_u8;
+          return;
+      }
+  
+      bb7: {
+          _0 = const 11_u8;
+          return;
++     }
++ 
++     bb8: {
++         goto -> bb4;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.rs b/tests/mir-opt/jump_threading.rs
new file mode 100644
index 00000000000..00dd98d825f
--- /dev/null
+++ b/tests/mir-opt/jump_threading.rs
@@ -0,0 +1,291 @@
+// unit-test: JumpThreading
+// compile-flags: -Zmir-enable-passes=+Inline
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+#![feature(control_flow_enum)]
+#![feature(try_trait_v2)]
+#![feature(custom_mir, core_intrinsics, rustc_attrs)]
+
+use std::intrinsics::mir::*;
+use std::ops::ControlFlow;
+
+fn too_complex(x: Result<i32, usize>) -> Option<i32> {
+    match {
+        match x {
+            Ok(v) => ControlFlow::Continue(v),
+            Err(r) => ControlFlow::Break(r),
+        }
+    } {
+        ControlFlow::Continue(v) => Some(v),
+        ControlFlow::Break(r) => None,
+    }
+}
+
+fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
+    Ok(x?)
+}
+
+enum DFA {
+    A,
+    B,
+    C,
+    D,
+}
+
+fn dfa() {
+    let mut state = DFA::A;
+    loop {
+        match state {
+            DFA::A => state = DFA::B,
+            DFA::B => state = DFA::C,
+            DFA::C => state = DFA::D,
+            DFA::D => return,
+        }
+    }
+}
+
+#[repr(u8)]
+enum CustomDiscr {
+    A = 35,
+    B = 73,
+    C = 99,
+}
+
+fn custom_discr(x: bool) -> u8 {
+    match if x { CustomDiscr::A } else { CustomDiscr::B } {
+        CustomDiscr::A => 5,
+        _ => 13,
+    }
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn multiple_match(x: u8) -> u8 {
+    mir!(
+        {
+            match x { 3 => bb1, _ => bb2 }
+        }
+        bb1 = {
+            // We know `x == 3`, so we can take `bb3`.
+            let y = x;
+            match y { 3 => bb3, _ => bb4 }
+        }
+        bb2 = {
+            // We know `x != 3`, so we can take `bb6`.
+            let z = x;
+            match z { 3 => bb5, _ => bb6 }
+        }
+        bb3 = {
+            RET = 5;
+            Return()
+        }
+        bb4 = {
+            RET = 7;
+            Return()
+        }
+        bb5 = {
+            RET = 9;
+            Return()
+        }
+        bb6 = {
+            // We know `z != 3`, so we CANNOT take `bb7`.
+            match z { 1 => bb7, _ => bb8 }
+        }
+        bb7 = {
+            RET = 9;
+            Return()
+        }
+        bb8 = {
+            RET = 11;
+            Return()
+        }
+    )
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn duplicate_chain(x: bool) -> u8 {
+    mir!(
+        let a: u8;
+        {
+            match x { true => bb1, _ => bb2 }
+        }
+        bb1 = {
+            a = 5;
+            Goto(bb3)
+        }
+        bb2 = {
+            a = 5;
+            Goto(bb3)
+        }
+        // Verify that we do not create multiple copied of `bb3`.
+        bb3 = {
+            let b = 13;
+            Goto(bb4)
+        }
+        bb4 = {
+            let c = 15;
+            match a { 5 => bb5, _ => bb6 }
+        }
+        bb5 = {
+            RET = 7;
+            Return()
+        }
+        bb6 = {
+            RET = 9;
+            Return()
+        }
+    )
+}
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[rustc_nonnull_optimization_guaranteed]
+struct NonZeroUsize(usize);
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn mutate_discriminant() -> u8 {
+    mir!(
+        let x: Option<NonZeroUsize>;
+        {
+            SetDiscriminant(x, 1);
+            // This assignment overwrites the niche in which the discriminant is stored.
+            place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize;
+            // So we cannot know the value of this discriminant.
+            let a = Discriminant(x);
+            match a {
+                0 => bb1,
+                _ => bad,
+            }
+        }
+        bb1 = {
+            RET = 1;
+            Return()
+        }
+        bad = {
+            RET = 2;
+            Unreachable()
+        }
+    )
+}
+
+// Verify that we do not try to reason when there are mutable pointers involved.
+fn mutable_ref() -> bool {
+    let mut x = 5;
+    let a = std::ptr::addr_of_mut!(x);
+    x = 7;
+    unsafe { *a = 8 };
+    if x == 7 {
+        true
+    } else {
+        false
+    }
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn renumbered_bb(x: bool) -> u8 {
+    // This function has 2 TOs: 1-3-4 and 0-1-3-4-6.
+    // We verify that the second TO does not modify 3 once the first has been applied.
+    mir!(
+        let a: bool;
+        let b: bool;
+        {
+            b = false;
+            match x { true => bb1, _ => bb2 }
+        }
+        bb1 = {
+            a = false;
+            Goto(bb3)
+        }
+        bb2 = {
+            a = x;
+            b = x;
+            Goto(bb3)
+        }
+        bb3 = {
+            match a { false => bb4, _ => bb5 }
+        }
+        bb4 = {
+            match b { false => bb6, _ => bb7 }
+        }
+        bb5 = {
+            RET = 7;
+            Return()
+        }
+        bb6 = {
+            RET = 9;
+            Return()
+        }
+        bb7 = {
+            RET = 11;
+            Return()
+        }
+    )
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn disappearing_bb(x: u8) -> u8 {
+    // This function has 3 TOs: 1-4-5, 0-1-4-7-5-8 and 3-4-7-5-6
+    // After applying the first TO, we create bb9 to replace 4, and rename 1-4 edge by 1-9. The
+    // second TO may try to thread non-existing edge 9-4.
+    // This test verifies that we preserve semantics by bailing out of this second TO.
+    mir!(
+        let _11: i8;
+        let _12: bool;
+        let _13: bool;
+        {
+            _13 = false;
+            _12 = false;
+            _13 = true;
+            _12 = true;
+            match x { 0 => bb3, 1 => bb3, 2 => bb1, _ => bb2 }
+        }
+        bb1 = {
+            _12 = false;
+            Goto(bb4)
+        }
+        bb2 = {
+            Unreachable()
+        }
+        bb3 = {
+            _13 = false;
+            Goto(bb4)
+        }
+        bb4 = {
+            match _12 { false => bb5, _ => bb7 }
+        }
+        bb5 = {
+            match _13 { false => bb6, _ => bb8 }
+        }
+        bb6 = {
+            Return()
+        }
+        bb7 = {
+            Goto(bb5)
+        }
+        bb8 = {
+            Goto(bb6)
+        }
+    )
+}
+
+fn main() {
+    too_complex(Ok(0));
+    identity(Ok(0));
+    custom_discr(false);
+    dfa();
+    multiple_match(5);
+    duplicate_chain(false);
+    mutate_discriminant();
+    mutable_ref();
+    renumbered_bb(true);
+    disappearing_bb(7);
+}
+
+// EMIT_MIR jump_threading.too_complex.JumpThreading.diff
+// EMIT_MIR jump_threading.identity.JumpThreading.diff
+// EMIT_MIR jump_threading.custom_discr.JumpThreading.diff
+// EMIT_MIR jump_threading.dfa.JumpThreading.diff
+// EMIT_MIR jump_threading.multiple_match.JumpThreading.diff
+// EMIT_MIR jump_threading.duplicate_chain.JumpThreading.diff
+// EMIT_MIR jump_threading.mutate_discriminant.JumpThreading.diff
+// EMIT_MIR jump_threading.mutable_ref.JumpThreading.diff
+// EMIT_MIR jump_threading.renumbered_bb.JumpThreading.diff
+// EMIT_MIR jump_threading.disappearing_bb.JumpThreading.diff
diff --git a/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..f5eade4a914
--- /dev/null
+++ b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff
@@ -0,0 +1,98 @@
+- // MIR for `too_complex` before JumpThreading
++ // MIR for `too_complex` after JumpThreading
+  
+  fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
+      debug x => _1;
+      let mut _0: std::option::Option<i32>;
+      let mut _2: std::ops::ControlFlow<usize, i32>;
+      let mut _3: isize;
+      let _4: i32;
+      let mut _5: i32;
+      let _6: usize;
+      let mut _7: usize;
+      let mut _8: isize;
+      let _9: i32;
+      let mut _10: i32;
+      let _11: usize;
+      scope 1 {
+          debug v => _4;
+      }
+      scope 2 {
+          debug r => _6;
+      }
+      scope 3 {
+          debug v => _9;
+      }
+      scope 4 {
+          debug r => _11;
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          _3 = discriminant(_1);
+          switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+          _6 = ((_1 as Err).0: usize);
+          StorageLive(_7);
+          _7 = _6;
+          _2 = ControlFlow::<usize, i32>::Break(move _7);
+          StorageDead(_7);
+          StorageDead(_6);
+-         goto -> bb4;
++         goto -> bb8;
+      }
+  
+      bb2: {
+          unreachable;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = ((_1 as Ok).0: i32);
+          StorageLive(_5);
+          _5 = _4;
+          _2 = ControlFlow::<usize, i32>::Continue(move _5);
+          StorageDead(_5);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb4: {
+          _8 = discriminant(_2);
+-         switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb2];
++         goto -> bb6;
+      }
+  
+      bb5: {
+          StorageLive(_11);
+          _11 = ((_2 as Break).0: usize);
+          _0 = Option::<i32>::None;
+          StorageDead(_11);
+          goto -> bb7;
+      }
+  
+      bb6: {
+          StorageLive(_9);
+          _9 = ((_2 as Continue).0: i32);
+          StorageLive(_10);
+          _10 = _9;
+          _0 = Option::<i32>::Some(move _10);
+          StorageDead(_10);
+          StorageDead(_9);
+          goto -> bb7;
+      }
+  
+      bb7: {
+          StorageDead(_2);
+          return;
++     }
++ 
++     bb8: {
++         _8 = discriminant(_2);
++         goto -> bb5;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..f5eade4a914
--- /dev/null
+++ b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff
@@ -0,0 +1,98 @@
+- // MIR for `too_complex` before JumpThreading
++ // MIR for `too_complex` after JumpThreading
+  
+  fn too_complex(_1: Result<i32, usize>) -> Option<i32> {
+      debug x => _1;
+      let mut _0: std::option::Option<i32>;
+      let mut _2: std::ops::ControlFlow<usize, i32>;
+      let mut _3: isize;
+      let _4: i32;
+      let mut _5: i32;
+      let _6: usize;
+      let mut _7: usize;
+      let mut _8: isize;
+      let _9: i32;
+      let mut _10: i32;
+      let _11: usize;
+      scope 1 {
+          debug v => _4;
+      }
+      scope 2 {
+          debug r => _6;
+      }
+      scope 3 {
+          debug v => _9;
+      }
+      scope 4 {
+          debug r => _11;
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          _3 = discriminant(_1);
+          switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+          _6 = ((_1 as Err).0: usize);
+          StorageLive(_7);
+          _7 = _6;
+          _2 = ControlFlow::<usize, i32>::Break(move _7);
+          StorageDead(_7);
+          StorageDead(_6);
+-         goto -> bb4;
++         goto -> bb8;
+      }
+  
+      bb2: {
+          unreachable;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = ((_1 as Ok).0: i32);
+          StorageLive(_5);
+          _5 = _4;
+          _2 = ControlFlow::<usize, i32>::Continue(move _5);
+          StorageDead(_5);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb4: {
+          _8 = discriminant(_2);
+-         switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb2];
++         goto -> bb6;
+      }
+  
+      bb5: {
+          StorageLive(_11);
+          _11 = ((_2 as Break).0: usize);
+          _0 = Option::<i32>::None;
+          StorageDead(_11);
+          goto -> bb7;
+      }
+  
+      bb6: {
+          StorageLive(_9);
+          _9 = ((_2 as Continue).0: i32);
+          StorageLive(_10);
+          _10 = _9;
+          _0 = Option::<i32>::Some(move _10);
+          StorageDead(_10);
+          StorageDead(_9);
+          goto -> bb7;
+      }
+  
+      bb7: {
+          StorageDead(_2);
+          return;
++     }
++ 
++     bb8: {
++         _8 = discriminant(_2);
++         goto -> bb5;
+      }
+  }
+