about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDianQK <dianqk@dianqk.net>2024-07-04 12:43:37 +0800
committerDianQK <dianqk@dianqk.net>2024-08-03 10:55:43 +0800
commit8b9d7b1489ddd90a69820b6b4f146a79351e850d (patch)
treedf585694d645b39c3c964b5050e519b1810845b6
parent1df0458781d6fd753a68c4cdc4de5313b1635dbd (diff)
downloadrust-8b9d7b1489ddd90a69820b6b4f146a79351e850d.tar.gz
rust-8b9d7b1489ddd90a69820b6b4f146a79351e850d.zip
Simplify match based on the cast result of `IntToInt`.
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_mir_transform/Cargo.toml1
-rw-r--r--compiler/rustc_mir_transform/src/match_branches.rs141
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_i128_u128.MatchBranchSimplification.diff61
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_i16_i8.MatchBranchSimplification.diff37
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_i8_i16.MatchBranchSimplification.diff37
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_i8_i16_failed.MatchBranchSimplification.diff37
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_sext_i8_i16.MatchBranchSimplification.diff52
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_sext_i8_i16_failed.MatchBranchSimplification.diff47
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_sext_i8_u16.MatchBranchSimplification.diff52
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_sext_i8_u16_failed.MatchBranchSimplification.diff47
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_trunc_i16_i8.MatchBranchSimplification.diff77
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_trunc_i16_i8_failed.MatchBranchSimplification.diff72
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_trunc_i16_u8.MatchBranchSimplification.diff77
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_trunc_i16_u8_failed.MatchBranchSimplification.diff72
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_trunc_u16_i8.MatchBranchSimplification.diff67
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_trunc_u16_i8_failed.MatchBranchSimplification.diff62
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_trunc_u16_u8.MatchBranchSimplification.diff67
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_trunc_u16_u8_failed.MatchBranchSimplification.diff62
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i16.MatchBranchSimplification.diff32
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i16_2.MatchBranchSimplification.diff26
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i16_failed.MatchBranchSimplification.diff32
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i16_fallback.MatchBranchSimplification.diff31
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i8.MatchBranchSimplification.diff47
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i8_2.MatchBranchSimplification.diff80
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i8_2_failed.MatchBranchSimplification.diff74
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i8_failed.MatchBranchSimplification.diff42
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i8_failed_len_1.MatchBranchSimplification.diff42
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i8_failed_len_2.MatchBranchSimplification.diff42
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_i8_fallback.MatchBranchSimplification.diff38
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_u16.MatchBranchSimplification.diff37
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_u8_u16_2.MatchBranchSimplification.diff37
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_zext_u8_i16.MatchBranchSimplification.diff47
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_zext_u8_i16_failed.MatchBranchSimplification.diff42
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_zext_u8_u16.MatchBranchSimplification.diff47
-rw-r--r--tests/mir-opt/matches_reduce_branches.match_zext_u8_u16_failed.MatchBranchSimplification.diff42
-rw-r--r--tests/mir-opt/matches_reduce_branches.rs579
-rw-r--r--tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff41
-rw-r--r--tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff41
-rw-r--r--tests/mir-opt/matches_u8.rs1
40 files changed, 1937 insertions, 532 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 316926e584e..0b5aa7db319 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4346,6 +4346,7 @@ dependencies = [
  "rustc_span",
  "rustc_target",
  "rustc_trait_selection",
+ "rustc_type_ir",
  "smallvec",
  "tracing",
 ]
diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml
index f864a13a31b..07ca51a67ae 100644
--- a/compiler/rustc_mir_transform/Cargo.toml
+++ b/compiler/rustc_mir_transform/Cargo.toml
@@ -25,6 +25,7 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
+rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs
index df4f3ccb9b5..68000fe0ef8 100644
--- a/compiler/rustc_mir_transform/src/match_branches.rs
+++ b/compiler/rustc_mir_transform/src/match_branches.rs
@@ -3,8 +3,10 @@ use std::iter;
 use rustc_index::IndexSlice;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::*;
+use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
 use rustc_middle::ty::{ParamEnv, ScalarInt, Ty, TyCtxt};
-use rustc_target::abi::Size;
+use rustc_target::abi::Integer;
+use rustc_type_ir::TyKind::*;
 
 use super::simplify::simplify_cfg;
 
@@ -264,33 +266,56 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf {
     }
 }
 
+/// Check if the cast constant using `IntToInt` is equal to the target constant.
+fn can_cast(
+    tcx: TyCtxt<'_>,
+    src_val: impl Into<u128>,
+    src_layout: TyAndLayout<'_>,
+    cast_ty: Ty<'_>,
+    target_scalar: ScalarInt,
+) -> bool {
+    let from_scalar = ScalarInt::try_from_uint(src_val.into(), src_layout.size).unwrap();
+    let v = match src_layout.ty.kind() {
+        Uint(_) => from_scalar.to_uint(src_layout.size),
+        Int(_) => from_scalar.to_int(src_layout.size) as u128,
+        _ => unreachable!("invalid int"),
+    };
+    let size = match *cast_ty.kind() {
+        Int(t) => Integer::from_int_ty(&tcx, t).size(),
+        Uint(t) => Integer::from_uint_ty(&tcx, t).size(),
+        _ => unreachable!("invalid int"),
+    };
+    let v = size.truncate(v);
+    let cast_scalar = ScalarInt::try_from_uint(v, size).unwrap();
+    cast_scalar == target_scalar
+}
+
 #[derive(Default)]
 struct SimplifyToExp {
-    transfrom_types: Vec<TransfromType>,
+    transfrom_kinds: Vec<TransfromKind>,
 }
 
 #[derive(Clone, Copy)]
-enum CompareType<'tcx, 'a> {
+enum ExpectedTransformKind<'tcx, 'a> {
     /// Identical statements.
     Same(&'a StatementKind<'tcx>),
     /// Assignment statements have the same value.
-    Eq(&'a Place<'tcx>, Ty<'tcx>, ScalarInt),
+    SameByEq { place: &'a Place<'tcx>, ty: Ty<'tcx>, scalar: ScalarInt },
     /// Enum variant comparison type.
-    Discr { place: &'a Place<'tcx>, ty: Ty<'tcx>, is_signed: bool },
+    Cast { place: &'a Place<'tcx>, ty: Ty<'tcx> },
 }
 
-enum TransfromType {
+enum TransfromKind {
     Same,
-    Eq,
-    Discr,
+    Cast,
 }
 
-impl From<CompareType<'_, '_>> for TransfromType {
-    fn from(compare_type: CompareType<'_, '_>) -> Self {
+impl From<ExpectedTransformKind<'_, '_>> for TransfromKind {
+    fn from(compare_type: ExpectedTransformKind<'_, '_>) -> Self {
         match compare_type {
-            CompareType::Same(_) => TransfromType::Same,
-            CompareType::Eq(_, _, _) => TransfromType::Eq,
-            CompareType::Discr { .. } => TransfromType::Discr,
+            ExpectedTransformKind::Same(_) => TransfromKind::Same,
+            ExpectedTransformKind::SameByEq { .. } => TransfromKind::Same,
+            ExpectedTransformKind::Cast { .. } => TransfromKind::Cast,
         }
     }
 }
@@ -354,7 +379,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
             return None;
         }
         let mut target_iter = targets.iter();
-        let (first_val, first_target) = target_iter.next().unwrap();
+        let (first_case_val, first_target) = target_iter.next().unwrap();
         let first_terminator_kind = &bbs[first_target].terminator().kind;
         // Check that destinations are identical, and if not, then don't optimize this block
         if !targets
@@ -364,24 +389,20 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
             return None;
         }
 
-        let discr_size = tcx.layout_of(param_env.and(discr_ty)).unwrap().size;
+        let discr_layout = tcx.layout_of(param_env.and(discr_ty)).unwrap();
         let first_stmts = &bbs[first_target].statements;
-        let (second_val, second_target) = target_iter.next().unwrap();
+        let (second_case_val, second_target) = target_iter.next().unwrap();
         let second_stmts = &bbs[second_target].statements;
         if first_stmts.len() != second_stmts.len() {
             return None;
         }
 
-        fn int_equal(l: ScalarInt, r: impl Into<u128>, size: Size) -> bool {
-            l.to_bits_unchecked() == ScalarInt::try_from_uint(r, size).unwrap().to_bits_unchecked()
-        }
-
         // We first compare the two branches, and then the other branches need to fulfill the same conditions.
-        let mut compare_types = Vec::new();
+        let mut expected_transform_kinds = Vec::new();
         for (f, s) in iter::zip(first_stmts, second_stmts) {
             let compare_type = match (&f.kind, &s.kind) {
                 // If two statements are exactly the same, we can optimize.
-                (f_s, s_s) if f_s == s_s => CompareType::Same(f_s),
+                (f_s, s_s) if f_s == s_s => ExpectedTransformKind::Same(f_s),
 
                 // If two statements are assignments with the match values to the same place, we can optimize.
                 (
@@ -395,22 +416,29 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
                         f_c.const_.try_eval_scalar_int(tcx, param_env),
                         s_c.const_.try_eval_scalar_int(tcx, param_env),
                     ) {
-                        (Some(f), Some(s)) if f == s => CompareType::Eq(lhs_f, f_c.const_.ty(), f),
-                        // Enum variants can also be simplified to an assignment statement if their values are equal.
-                        // We need to consider both unsigned and signed scenarios here.
+                        (Some(f), Some(s)) if f == s => ExpectedTransformKind::SameByEq {
+                            place: lhs_f,
+                            ty: f_c.const_.ty(),
+                            scalar: f,
+                        },
+                        // Enum variants can also be simplified to an assignment statement,
+                        // if we can use `IntToInt` cast to get an equal value.
                         (Some(f), Some(s))
-                            if ((f_c.const_.ty().is_signed() || discr_ty.is_signed())
-                                && int_equal(f, first_val, discr_size)
-                                && int_equal(s, second_val, discr_size))
-                                || (Some(f) == ScalarInt::try_from_uint(first_val, f.size())
-                                    && Some(s)
-                                        == ScalarInt::try_from_uint(second_val, s.size())) =>
+                            if (can_cast(
+                                tcx,
+                                first_case_val,
+                                discr_layout,
+                                f_c.const_.ty(),
+                                f,
+                            ) && can_cast(
+                                tcx,
+                                second_case_val,
+                                discr_layout,
+                                f_c.const_.ty(),
+                                s,
+                            )) =>
                         {
-                            CompareType::Discr {
-                                place: lhs_f,
-                                ty: f_c.const_.ty(),
-                                is_signed: f_c.const_.ty().is_signed() || discr_ty.is_signed(),
-                            }
+                            ExpectedTransformKind::Cast { place: lhs_f, ty: f_c.const_.ty() }
                         }
                         _ => {
                             return None;
@@ -421,47 +449,36 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
                 // Otherwise we cannot optimize. Try another block.
                 _ => return None,
             };
-            compare_types.push(compare_type);
+            expected_transform_kinds.push(compare_type);
         }
 
         // All remaining BBs need to fulfill the same pattern as the two BBs from the previous step.
         for (other_val, other_target) in target_iter {
             let other_stmts = &bbs[other_target].statements;
-            if compare_types.len() != other_stmts.len() {
+            if expected_transform_kinds.len() != other_stmts.len() {
                 return None;
             }
-            for (f, s) in iter::zip(&compare_types, other_stmts) {
+            for (f, s) in iter::zip(&expected_transform_kinds, other_stmts) {
                 match (*f, &s.kind) {
-                    (CompareType::Same(f_s), s_s) if f_s == s_s => {}
+                    (ExpectedTransformKind::Same(f_s), s_s) if f_s == s_s => {}
                     (
-                        CompareType::Eq(lhs_f, f_ty, val),
+                        ExpectedTransformKind::SameByEq { place: lhs_f, ty: f_ty, scalar },
                         StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))),
                     ) if lhs_f == lhs_s
                         && s_c.const_.ty() == f_ty
-                        && s_c.const_.try_eval_scalar_int(tcx, param_env) == Some(val) => {}
+                        && s_c.const_.try_eval_scalar_int(tcx, param_env) == Some(scalar) => {}
                     (
-                        CompareType::Discr { place: lhs_f, ty: f_ty, is_signed },
+                        ExpectedTransformKind::Cast { place: lhs_f, ty: f_ty },
                         StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))),
-                    ) if lhs_f == lhs_s && s_c.const_.ty() == f_ty => {
-                        let Some(f) = s_c.const_.try_eval_scalar_int(tcx, param_env) else {
-                            return None;
-                        };
-                        if is_signed
-                            && s_c.const_.ty().is_signed()
-                            && int_equal(f, other_val, discr_size)
-                        {
-                            continue;
-                        }
-                        if Some(f) == ScalarInt::try_from_uint(other_val, f.size()) {
-                            continue;
-                        }
-                        return None;
-                    }
+                    ) if let Some(f) = s_c.const_.try_eval_scalar_int(tcx, param_env)
+                        && lhs_f == lhs_s
+                        && s_c.const_.ty() == f_ty
+                        && can_cast(tcx, other_val, discr_layout, f_ty, f) => {}
                     _ => return None,
                 }
             }
         }
-        self.transfrom_types = compare_types.into_iter().map(|c| c.into()).collect();
+        self.transfrom_kinds = expected_transform_kinds.into_iter().map(|c| c.into()).collect();
         Some(())
     }
 
@@ -479,13 +496,13 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
         let (_, first) = targets.iter().next().unwrap();
         let first = &bbs[first];
 
-        for (t, s) in iter::zip(&self.transfrom_types, &first.statements) {
+        for (t, s) in iter::zip(&self.transfrom_kinds, &first.statements) {
             match (t, &s.kind) {
-                (TransfromType::Same, _) | (TransfromType::Eq, _) => {
+                (TransfromKind::Same, _) => {
                     patch.add_statement(parent_end, s.kind.clone());
                 }
                 (
-                    TransfromType::Discr,
+                    TransfromKind::Cast,
                     StatementKind::Assign(box (lhs, Rvalue::Use(Operand::Constant(f_c)))),
                 ) => {
                     let operand = Operand::Copy(Place::from(discr_local));
diff --git a/tests/mir-opt/matches_reduce_branches.match_i128_u128.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_i128_u128.MatchBranchSimplification.diff
index dc50ae95472..fc34ce7125e 100644
--- a/tests/mir-opt/matches_reduce_branches.match_i128_u128.MatchBranchSimplification.diff
+++ b/tests/mir-opt/matches_reduce_branches.match_i128_u128.MatchBranchSimplification.diff
@@ -5,37 +5,42 @@
       debug i => _1;
       let mut _0: u128;
       let mut _2: i128;
++     let mut _3: i128;
   
       bb0: {
           _2 = discriminant(_1);
-          switchInt(move _2) -> [1: bb5, 2: bb4, 3: bb3, 340282366920938463463374607431768211455: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const core::num::<impl u128>::MAX;
-          goto -> bb6;
-      }
-  
-      bb3: {
-          _0 = const 3_u128;
-          goto -> bb6;
-      }
-  
-      bb4: {
-          _0 = const 2_u128;
-          goto -> bb6;
-      }
-  
-      bb5: {
-          _0 = const 1_u128;
-          goto -> bb6;
-      }
-  
-      bb6: {
+-         switchInt(move _2) -> [1: bb5, 2: bb4, 3: bb3, 340282366920938463463374607431768211455: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const core::num::<impl u128>::MAX;
+-         goto -> bb6;
+-     }
+- 
+-     bb3: {
+-         _0 = const 3_u128;
+-         goto -> bb6;
+-     }
+- 
+-     bb4: {
+-         _0 = const 2_u128;
+-         goto -> bb6;
+-     }
+- 
+-     bb5: {
+-         _0 = const 1_u128;
+-         goto -> bb6;
+-     }
+- 
+-     bb6: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as u128 (IntToInt);
++         StorageDead(_3);
           return;
       }
   }
diff --git a/tests/mir-opt/matches_reduce_branches.match_i16_i8.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_i16_i8.MatchBranchSimplification.diff
deleted file mode 100644
index 3514914b8ec..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_i16_i8.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,37 +0,0 @@
-- // MIR for `match_i16_i8` before MatchBranchSimplification
-+ // MIR for `match_i16_i8` after MatchBranchSimplification
-  
-  fn match_i16_i8(_1: EnumAi16) -> i8 {
-      debug i => _1;
-      let mut _0: i8;
-      let mut _2: i16;
-  
-      bb0: {
-          _2 = discriminant(_1);
-          switchInt(move _2) -> [65535: bb4, 2: bb3, 65533: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const -3_i8;
-          goto -> bb5;
-      }
-  
-      bb3: {
-          _0 = const 2_i8;
-          goto -> bb5;
-      }
-  
-      bb4: {
-          _0 = const -1_i8;
-          goto -> bb5;
-      }
-  
-      bb5: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_i8_i16.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_i8_i16.MatchBranchSimplification.diff
deleted file mode 100644
index ff4255ec8cc..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_i8_i16.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,37 +0,0 @@
-- // MIR for `match_i8_i16` before MatchBranchSimplification
-+ // MIR for `match_i8_i16` after MatchBranchSimplification
-  
-  fn match_i8_i16(_1: EnumAi8) -> i16 {
-      debug i => _1;
-      let mut _0: i16;
-      let mut _2: i8;
-  
-      bb0: {
-          _2 = discriminant(_1);
-          switchInt(move _2) -> [255: bb4, 2: bb3, 253: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const -3_i16;
-          goto -> bb5;
-      }
-  
-      bb3: {
-          _0 = const 2_i16;
-          goto -> bb5;
-      }
-  
-      bb4: {
-          _0 = const -1_i16;
-          goto -> bb5;
-      }
-  
-      bb5: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_i8_i16_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_i8_i16_failed.MatchBranchSimplification.diff
deleted file mode 100644
index 022039ecee6..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_i8_i16_failed.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,37 +0,0 @@
-- // MIR for `match_i8_i16_failed` before MatchBranchSimplification
-+ // MIR for `match_i8_i16_failed` after MatchBranchSimplification
-  
-  fn match_i8_i16_failed(_1: EnumAi8) -> i16 {
-      debug i => _1;
-      let mut _0: i16;
-      let mut _2: i8;
-  
-      bb0: {
-          _2 = discriminant(_1);
-          switchInt(move _2) -> [255: bb4, 2: bb3, 253: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const 3_i16;
-          goto -> bb5;
-      }
-  
-      bb3: {
-          _0 = const 2_i16;
-          goto -> bb5;
-      }
-  
-      bb4: {
-          _0 = const -1_i16;
-          goto -> bb5;
-      }
-  
-      bb5: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_sext_i8_i16.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_sext_i8_i16.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..7f8c2ab8d37
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_sext_i8_i16.MatchBranchSimplification.diff
@@ -0,0 +1,52 @@
+- // MIR for `match_sext_i8_i16` before MatchBranchSimplification
++ // MIR for `match_sext_i8_i16` after MatchBranchSimplification
+  
+  fn match_sext_i8_i16(_1: EnumAi8) -> i16 {
+      debug i => _1;
+      let mut _0: i16;
+      let mut _2: i8;
++     let mut _3: i8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [128: bb6, 255: bb5, 0: bb4, 1: bb3, 127: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const 127_i16;
+-         goto -> bb7;
+-     }
+- 
+-     bb3: {
+-         _0 = const 1_i16;
+-         goto -> bb7;
+-     }
+- 
+-     bb4: {
+-         _0 = const 0_i16;
+-         goto -> bb7;
+-     }
+- 
+-     bb5: {
+-         _0 = const -1_i16;
+-         goto -> bb7;
+-     }
+- 
+-     bb6: {
+-         _0 = const -128_i16;
+-         goto -> bb7;
+-     }
+- 
+-     bb7: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as i16 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_sext_i8_i16_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_sext_i8_i16_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..94ec2293222
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_sext_i8_i16_failed.MatchBranchSimplification.diff
@@ -0,0 +1,47 @@
+- // MIR for `match_sext_i8_i16_failed` before MatchBranchSimplification
++ // MIR for `match_sext_i8_i16_failed` after MatchBranchSimplification
+  
+  fn match_sext_i8_i16_failed(_1: EnumAi8) -> i16 {
+      debug i => _1;
+      let mut _0: i16;
+      let mut _2: i8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [128: bb6, 255: bb5, 0: bb4, 1: bb3, 127: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const 127_i16;
+          goto -> bb7;
+      }
+  
+      bb3: {
+          _0 = const 1_i16;
+          goto -> bb7;
+      }
+  
+      bb4: {
+          _0 = const 0_i16;
+          goto -> bb7;
+      }
+  
+      bb5: {
+          _0 = const 255_i16;
+          goto -> bb7;
+      }
+  
+      bb6: {
+          _0 = const -128_i16;
+          goto -> bb7;
+      }
+  
+      bb7: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_sext_i8_u16.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_sext_i8_u16.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..86d0d0ba6cf
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_sext_i8_u16.MatchBranchSimplification.diff
@@ -0,0 +1,52 @@
+- // MIR for `match_sext_i8_u16` before MatchBranchSimplification
++ // MIR for `match_sext_i8_u16` after MatchBranchSimplification
+  
+  fn match_sext_i8_u16(_1: EnumAi8) -> u16 {
+      debug i => _1;
+      let mut _0: u16;
+      let mut _2: i8;
++     let mut _3: i8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [128: bb6, 255: bb5, 0: bb4, 1: bb3, 127: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const 127_u16;
+-         goto -> bb7;
+-     }
+- 
+-     bb3: {
+-         _0 = const 1_u16;
+-         goto -> bb7;
+-     }
+- 
+-     bb4: {
+-         _0 = const 0_u16;
+-         goto -> bb7;
+-     }
+- 
+-     bb5: {
+-         _0 = const u16::MAX;
+-         goto -> bb7;
+-     }
+- 
+-     bb6: {
+-         _0 = const 65408_u16;
+-         goto -> bb7;
+-     }
+- 
+-     bb7: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as u16 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_sext_i8_u16_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_sext_i8_u16_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..281f373bf87
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_sext_i8_u16_failed.MatchBranchSimplification.diff
@@ -0,0 +1,47 @@
+- // MIR for `match_sext_i8_u16_failed` before MatchBranchSimplification
++ // MIR for `match_sext_i8_u16_failed` after MatchBranchSimplification
+  
+  fn match_sext_i8_u16_failed(_1: EnumAi8) -> u16 {
+      debug i => _1;
+      let mut _0: u16;
+      let mut _2: i8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [128: bb6, 255: bb5, 0: bb4, 1: bb3, 127: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const 127_u16;
+          goto -> bb7;
+      }
+  
+      bb3: {
+          _0 = const 1_u16;
+          goto -> bb7;
+      }
+  
+      bb4: {
+          _0 = const 0_u16;
+          goto -> bb7;
+      }
+  
+      bb5: {
+          _0 = const 255_u16;
+          goto -> bb7;
+      }
+  
+      bb6: {
+          _0 = const 65408_u16;
+          goto -> bb7;
+      }
+  
+      bb7: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_trunc_i16_i8.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_trunc_i16_i8.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..d3d27be2070
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_trunc_i16_i8.MatchBranchSimplification.diff
@@ -0,0 +1,77 @@
+- // MIR for `match_trunc_i16_i8` before MatchBranchSimplification
++ // MIR for `match_trunc_i16_i8` after MatchBranchSimplification
+  
+  fn match_trunc_i16_i8(_1: EnumAi16) -> i8 {
+      debug i => _1;
+      let mut _0: i8;
+      let mut _2: i16;
++     let mut _3: i16;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [128: bb11, 255: bb10, 0: bb9, 1: bb8, 127: bb7, 65408: bb6, 65535: bb5, 65280: bb4, 65281: bb3, 65407: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const i8::MAX;
+-         goto -> bb12;
+-     }
+- 
+-     bb3: {
+-         _0 = const 1_i8;
+-         goto -> bb12;
+-     }
+- 
+-     bb4: {
+-         _0 = const 0_i8;
+-         goto -> bb12;
+-     }
+- 
+-     bb5: {
+-         _0 = const -1_i8;
+-         goto -> bb12;
+-     }
+- 
+-     bb6: {
+-         _0 = const i8::MIN;
+-         goto -> bb12;
+-     }
+- 
+-     bb7: {
+-         _0 = const i8::MAX;
+-         goto -> bb12;
+-     }
+- 
+-     bb8: {
+-         _0 = const 1_i8;
+-         goto -> bb12;
+-     }
+- 
+-     bb9: {
+-         _0 = const 0_i8;
+-         goto -> bb12;
+-     }
+- 
+-     bb10: {
+-         _0 = const -1_i8;
+-         goto -> bb12;
+-     }
+- 
+-     bb11: {
+-         _0 = const i8::MIN;
+-         goto -> bb12;
+-     }
+- 
+-     bb12: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as i8 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_trunc_i16_i8_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_trunc_i16_i8_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..7f663baefba
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_trunc_i16_i8_failed.MatchBranchSimplification.diff
@@ -0,0 +1,72 @@
+- // MIR for `match_trunc_i16_i8_failed` before MatchBranchSimplification
++ // MIR for `match_trunc_i16_i8_failed` after MatchBranchSimplification
+  
+  fn match_trunc_i16_i8_failed(_1: EnumAi16) -> i8 {
+      debug i => _1;
+      let mut _0: i8;
+      let mut _2: i16;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [128: bb11, 255: bb10, 0: bb9, 1: bb8, 127: bb7, 65408: bb6, 65535: bb5, 65280: bb4, 65281: bb3, 65407: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const -127_i8;
+          goto -> bb12;
+      }
+  
+      bb3: {
+          _0 = const 1_i8;
+          goto -> bb12;
+      }
+  
+      bb4: {
+          _0 = const 0_i8;
+          goto -> bb12;
+      }
+  
+      bb5: {
+          _0 = const -1_i8;
+          goto -> bb12;
+      }
+  
+      bb6: {
+          _0 = const i8::MIN;
+          goto -> bb12;
+      }
+  
+      bb7: {
+          _0 = const i8::MAX;
+          goto -> bb12;
+      }
+  
+      bb8: {
+          _0 = const 1_i8;
+          goto -> bb12;
+      }
+  
+      bb9: {
+          _0 = const 0_i8;
+          goto -> bb12;
+      }
+  
+      bb10: {
+          _0 = const -1_i8;
+          goto -> bb12;
+      }
+  
+      bb11: {
+          _0 = const i8::MIN;
+          goto -> bb12;
+      }
+  
+      bb12: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_trunc_i16_u8.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_trunc_i16_u8.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..5fe899148eb
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_trunc_i16_u8.MatchBranchSimplification.diff
@@ -0,0 +1,77 @@
+- // MIR for `match_trunc_i16_u8` before MatchBranchSimplification
++ // MIR for `match_trunc_i16_u8` after MatchBranchSimplification
+  
+  fn match_trunc_i16_u8(_1: EnumAi16) -> u8 {
+      debug i => _1;
+      let mut _0: u8;
+      let mut _2: i16;
++     let mut _3: i16;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [128: bb11, 255: bb10, 0: bb9, 1: bb8, 127: bb7, 65408: bb6, 65535: bb5, 65280: bb4, 65281: bb3, 65407: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const 127_u8;
+-         goto -> bb12;
+-     }
+- 
+-     bb3: {
+-         _0 = const 1_u8;
+-         goto -> bb12;
+-     }
+- 
+-     bb4: {
+-         _0 = const 0_u8;
+-         goto -> bb12;
+-     }
+- 
+-     bb5: {
+-         _0 = const u8::MAX;
+-         goto -> bb12;
+-     }
+- 
+-     bb6: {
+-         _0 = const 128_u8;
+-         goto -> bb12;
+-     }
+- 
+-     bb7: {
+-         _0 = const 127_u8;
+-         goto -> bb12;
+-     }
+- 
+-     bb8: {
+-         _0 = const 1_u8;
+-         goto -> bb12;
+-     }
+- 
+-     bb9: {
+-         _0 = const 0_u8;
+-         goto -> bb12;
+-     }
+- 
+-     bb10: {
+-         _0 = const u8::MAX;
+-         goto -> bb12;
+-     }
+- 
+-     bb11: {
+-         _0 = const 128_u8;
+-         goto -> bb12;
+-     }
+- 
+-     bb12: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as u8 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_trunc_i16_u8_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_trunc_i16_u8_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..1c0ffb30c5b
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_trunc_i16_u8_failed.MatchBranchSimplification.diff
@@ -0,0 +1,72 @@
+- // MIR for `match_trunc_i16_u8_failed` before MatchBranchSimplification
++ // MIR for `match_trunc_i16_u8_failed` after MatchBranchSimplification
+  
+  fn match_trunc_i16_u8_failed(_1: EnumAi16) -> u8 {
+      debug i => _1;
+      let mut _0: u8;
+      let mut _2: i16;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [128: bb11, 255: bb10, 0: bb9, 1: bb8, 127: bb7, 65408: bb6, 65535: bb5, 65280: bb4, 65281: bb3, 65407: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const -127_i8 as u8 (IntToInt);
+          goto -> bb12;
+      }
+  
+      bb3: {
+          _0 = const 1_u8;
+          goto -> bb12;
+      }
+  
+      bb4: {
+          _0 = const 0_u8;
+          goto -> bb12;
+      }
+  
+      bb5: {
+          _0 = const u8::MAX;
+          goto -> bb12;
+      }
+  
+      bb6: {
+          _0 = const 128_u8;
+          goto -> bb12;
+      }
+  
+      bb7: {
+          _0 = const 127_u8;
+          goto -> bb12;
+      }
+  
+      bb8: {
+          _0 = const 1_u8;
+          goto -> bb12;
+      }
+  
+      bb9: {
+          _0 = const 0_u8;
+          goto -> bb12;
+      }
+  
+      bb10: {
+          _0 = const u8::MAX;
+          goto -> bb12;
+      }
+  
+      bb11: {
+          _0 = const 128_u8;
+          goto -> bb12;
+      }
+  
+      bb12: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_trunc_u16_i8.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_trunc_u16_i8.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..85f97a13cac
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_trunc_u16_i8.MatchBranchSimplification.diff
@@ -0,0 +1,67 @@
+- // MIR for `match_trunc_u16_i8` before MatchBranchSimplification
++ // MIR for `match_trunc_u16_i8` after MatchBranchSimplification
+  
+  fn match_trunc_u16_i8(_1: EnumAu16) -> i8 {
+      debug i => _1;
+      let mut _0: i8;
+      let mut _2: u16;
++     let mut _3: u16;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [0: bb9, 127: bb8, 128: bb7, 255: bb6, 65280: bb5, 65407: bb4, 65408: bb3, 65535: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const -1_i8;
+-         goto -> bb10;
+-     }
+- 
+-     bb3: {
+-         _0 = const i8::MIN;
+-         goto -> bb10;
+-     }
+- 
+-     bb4: {
+-         _0 = const i8::MAX;
+-         goto -> bb10;
+-     }
+- 
+-     bb5: {
+-         _0 = const 0_i8;
+-         goto -> bb10;
+-     }
+- 
+-     bb6: {
+-         _0 = const -1_i8;
+-         goto -> bb10;
+-     }
+- 
+-     bb7: {
+-         _0 = const i8::MIN;
+-         goto -> bb10;
+-     }
+- 
+-     bb8: {
+-         _0 = const i8::MAX;
+-         goto -> bb10;
+-     }
+- 
+-     bb9: {
+-         _0 = const 0_i8;
+-         goto -> bb10;
+-     }
+- 
+-     bb10: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as i8 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_trunc_u16_i8_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_trunc_u16_i8_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..cf6c86a71ad
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_trunc_u16_i8_failed.MatchBranchSimplification.diff
@@ -0,0 +1,62 @@
+- // MIR for `match_trunc_u16_i8_failed` before MatchBranchSimplification
++ // MIR for `match_trunc_u16_i8_failed` after MatchBranchSimplification
+  
+  fn match_trunc_u16_i8_failed(_1: EnumAu16) -> i8 {
+      debug i => _1;
+      let mut _0: i8;
+      let mut _2: u16;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [0: bb9, 127: bb8, 128: bb7, 255: bb6, 65280: bb5, 65407: bb4, 65408: bb3, 65535: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const 1_i8;
+          goto -> bb10;
+      }
+  
+      bb3: {
+          _0 = const i8::MIN;
+          goto -> bb10;
+      }
+  
+      bb4: {
+          _0 = const i8::MAX;
+          goto -> bb10;
+      }
+  
+      bb5: {
+          _0 = const 0_i8;
+          goto -> bb10;
+      }
+  
+      bb6: {
+          _0 = const -1_i8;
+          goto -> bb10;
+      }
+  
+      bb7: {
+          _0 = const i8::MIN;
+          goto -> bb10;
+      }
+  
+      bb8: {
+          _0 = const i8::MAX;
+          goto -> bb10;
+      }
+  
+      bb9: {
+          _0 = const 0_i8;
+          goto -> bb10;
+      }
+  
+      bb10: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_trunc_u16_u8.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_trunc_u16_u8.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..768d838eaa6
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_trunc_u16_u8.MatchBranchSimplification.diff
@@ -0,0 +1,67 @@
+- // MIR for `match_trunc_u16_u8` before MatchBranchSimplification
++ // MIR for `match_trunc_u16_u8` after MatchBranchSimplification
+  
+  fn match_trunc_u16_u8(_1: EnumAu16) -> u8 {
+      debug i => _1;
+      let mut _0: u8;
+      let mut _2: u16;
++     let mut _3: u16;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [0: bb9, 127: bb8, 128: bb7, 255: bb6, 65280: bb5, 65407: bb4, 65408: bb3, 65535: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const u8::MAX;
+-         goto -> bb10;
+-     }
+- 
+-     bb3: {
+-         _0 = const 128_u8;
+-         goto -> bb10;
+-     }
+- 
+-     bb4: {
+-         _0 = const 127_u8;
+-         goto -> bb10;
+-     }
+- 
+-     bb5: {
+-         _0 = const 0_u8;
+-         goto -> bb10;
+-     }
+- 
+-     bb6: {
+-         _0 = const u8::MAX;
+-         goto -> bb10;
+-     }
+- 
+-     bb7: {
+-         _0 = const 128_u8;
+-         goto -> bb10;
+-     }
+- 
+-     bb8: {
+-         _0 = const 127_u8;
+-         goto -> bb10;
+-     }
+- 
+-     bb9: {
+-         _0 = const 0_u8;
+-         goto -> bb10;
+-     }
+- 
+-     bb10: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as u8 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_trunc_u16_u8_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_trunc_u16_u8_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..109e97bb578
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_trunc_u16_u8_failed.MatchBranchSimplification.diff
@@ -0,0 +1,62 @@
+- // MIR for `match_trunc_u16_u8_failed` before MatchBranchSimplification
++ // MIR for `match_trunc_u16_u8_failed` after MatchBranchSimplification
+  
+  fn match_trunc_u16_u8_failed(_1: EnumAu16) -> u8 {
+      debug i => _1;
+      let mut _0: u8;
+      let mut _2: u16;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [0: bb9, 127: bb8, 128: bb7, 255: bb6, 65280: bb5, 65407: bb4, 65408: bb3, 65535: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const 127_u8;
+          goto -> bb10;
+      }
+  
+      bb3: {
+          _0 = const 128_u8;
+          goto -> bb10;
+      }
+  
+      bb4: {
+          _0 = const 127_u8;
+          goto -> bb10;
+      }
+  
+      bb5: {
+          _0 = const 0_u8;
+          goto -> bb10;
+      }
+  
+      bb6: {
+          _0 = const u8::MAX;
+          goto -> bb10;
+      }
+  
+      bb7: {
+          _0 = const 128_u8;
+          goto -> bb10;
+      }
+  
+      bb8: {
+          _0 = const 127_u8;
+          goto -> bb10;
+      }
+  
+      bb9: {
+          _0 = const 0_u8;
+          goto -> bb10;
+      }
+  
+      bb10: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i16.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i16.MatchBranchSimplification.diff
deleted file mode 100644
index 72ad60956ab..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_u8_i16.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,32 +0,0 @@
-- // MIR for `match_u8_i16` before MatchBranchSimplification
-+ // MIR for `match_u8_i16` after MatchBranchSimplification
-  
-  fn match_u8_i16(_1: EnumAu8) -> i16 {
-      debug i => _1;
-      let mut _0: i16;
-      let mut _2: u8;
-  
-      bb0: {
-          _2 = discriminant(_1);
-          switchInt(move _2) -> [1: bb3, 2: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const 2_i16;
-          goto -> bb4;
-      }
-  
-      bb3: {
-          _0 = const 1_i16;
-          goto -> bb4;
-      }
-  
-      bb4: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i16_2.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i16_2.MatchBranchSimplification.diff
deleted file mode 100644
index 3333cd765a8..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_u8_i16_2.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-- // MIR for `match_u8_i16_2` before MatchBranchSimplification
-+ // MIR for `match_u8_i16_2` after MatchBranchSimplification
-  
-  fn match_u8_i16_2(_1: EnumAu8) -> i16 {
-      let mut _0: i16;
-      let mut _2: u8;
-  
-      bb0: {
-          _2 = discriminant(_1);
-          switchInt(_2) -> [1: bb3, 2: bb1, otherwise: bb2];
-      }
-  
-      bb1: {
-          _0 = const 2_i16;
-          goto -> bb3;
-      }
-  
-      bb2: {
-          unreachable;
-      }
-  
-      bb3: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i16_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i16_failed.MatchBranchSimplification.diff
deleted file mode 100644
index 6da19e46dab..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_u8_i16_failed.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,32 +0,0 @@
-- // MIR for `match_u8_i16_failed` before MatchBranchSimplification
-+ // MIR for `match_u8_i16_failed` after MatchBranchSimplification
-  
-  fn match_u8_i16_failed(_1: EnumAu8) -> i16 {
-      debug i => _1;
-      let mut _0: i16;
-      let mut _2: u8;
-  
-      bb0: {
-          _2 = discriminant(_1);
-          switchInt(move _2) -> [1: bb3, 2: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const 3_i16;
-          goto -> bb4;
-      }
-  
-      bb3: {
-          _0 = const 1_i16;
-          goto -> bb4;
-      }
-  
-      bb4: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i16_fallback.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i16_fallback.MatchBranchSimplification.diff
deleted file mode 100644
index 5690f17f24f..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_u8_i16_fallback.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,31 +0,0 @@
-- // MIR for `match_u8_i16_fallback` before MatchBranchSimplification
-+ // MIR for `match_u8_i16_fallback` after MatchBranchSimplification
-  
-  fn match_u8_i16_fallback(_1: u8) -> i16 {
-      debug i => _1;
-      let mut _0: i16;
-  
-      bb0: {
-          switchInt(_1) -> [1: bb3, 2: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          _0 = const 3_i16;
-          goto -> bb4;
-      }
-  
-      bb2: {
-          _0 = const 2_i16;
-          goto -> bb4;
-      }
-  
-      bb3: {
-          _0 = const 1_i16;
-          goto -> bb4;
-      }
-  
-      bb4: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i8.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i8.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..d63eed7c019
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_u8_i8.MatchBranchSimplification.diff
@@ -0,0 +1,47 @@
+- // MIR for `match_u8_i8` before MatchBranchSimplification
++ // MIR for `match_u8_i8` after MatchBranchSimplification
+  
+  fn match_u8_i8(_1: EnumAu8) -> i8 {
+      debug i => _1;
+      let mut _0: i8;
+      let mut _2: u8;
++     let mut _3: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [0: bb5, 127: bb4, 128: bb3, 255: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const -1_i8;
+-         goto -> bb6;
+-     }
+- 
+-     bb3: {
+-         _0 = const i8::MIN;
+-         goto -> bb6;
+-     }
+- 
+-     bb4: {
+-         _0 = const i8::MAX;
+-         goto -> bb6;
+-     }
+- 
+-     bb5: {
+-         _0 = const 0_i8;
+-         goto -> bb6;
+-     }
+- 
+-     bb6: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as i8 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i8_2.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i8_2.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..98dee1835a8
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_u8_i8_2.MatchBranchSimplification.diff
@@ -0,0 +1,80 @@
+- // MIR for `match_u8_i8_2` before MatchBranchSimplification
++ // MIR for `match_u8_i8_2` after MatchBranchSimplification
+  
+  fn match_u8_i8_2(_1: EnumAu8) -> (i8, i8) {
+      debug i => _1;
+      let mut _0: (i8, i8);
+      let _2: i8;
+      let _4: ();
+      let mut _5: u8;
+      let mut _6: i8;
+      let mut _7: i8;
++     let mut _8: u8;
+      scope 1 {
+          debug a => _2;
+          let _3: i8;
+          scope 2 {
+              debug b => _3;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _5 = discriminant(_1);
+-         switchInt(move _5) -> [0: bb5, 127: bb4, 128: bb3, 255: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _2 = const -1_i8;
+-         _3 = const -1_i8;
++         StorageLive(_8);
++         _8 = move _5;
++         _2 = _8 as i8 (IntToInt);
++         _3 = _8 as i8 (IntToInt);
+          _4 = ();
+-         goto -> bb6;
+-     }
+- 
+-     bb3: {
+-         _2 = const i8::MIN;
+-         _3 = const i8::MIN;
+-         _4 = ();
+-         goto -> bb6;
+-     }
+- 
+-     bb4: {
+-         _2 = const i8::MAX;
+-         _3 = const i8::MAX;
+-         _4 = ();
+-         goto -> bb6;
+-     }
+- 
+-     bb5: {
+-         _2 = const 0_i8;
+-         _3 = const 0_i8;
+-         _4 = ();
+-         goto -> bb6;
+-     }
+- 
+-     bb6: {
++         StorageDead(_8);
+          StorageDead(_4);
+          StorageLive(_6);
+          _6 = _2;
+          StorageLive(_7);
+          _7 = _3;
+          _0 = (move _6, move _7);
+          StorageDead(_7);
+          StorageDead(_6);
+          StorageDead(_3);
+          StorageDead(_2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i8_2_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i8_2_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..901dda58617
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_u8_i8_2_failed.MatchBranchSimplification.diff
@@ -0,0 +1,74 @@
+- // MIR for `match_u8_i8_2_failed` before MatchBranchSimplification
++ // MIR for `match_u8_i8_2_failed` after MatchBranchSimplification
+  
+  fn match_u8_i8_2_failed(_1: EnumAu8) -> (i8, i8) {
+      debug i => _1;
+      let mut _0: (i8, i8);
+      let _2: i8;
+      let _4: ();
+      let mut _5: u8;
+      let mut _6: i8;
+      let mut _7: i8;
+      scope 1 {
+          debug a => _2;
+          let _3: i8;
+          scope 2 {
+              debug b => _3;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _5 = discriminant(_1);
+          switchInt(move _5) -> [0: bb5, 127: bb4, 128: bb3, 255: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _2 = const -1_i8;
+          _3 = const 1_i8;
+          _4 = ();
+          goto -> bb6;
+      }
+  
+      bb3: {
+          _2 = const i8::MIN;
+          _3 = const i8::MIN;
+          _4 = ();
+          goto -> bb6;
+      }
+  
+      bb4: {
+          _2 = const i8::MAX;
+          _3 = const i8::MAX;
+          _4 = ();
+          goto -> bb6;
+      }
+  
+      bb5: {
+          _2 = const 0_i8;
+          _3 = const 0_i8;
+          _4 = ();
+          goto -> bb6;
+      }
+  
+      bb6: {
+          StorageDead(_4);
+          StorageLive(_6);
+          _6 = _2;
+          StorageLive(_7);
+          _7 = _3;
+          _0 = (move _6, move _7);
+          StorageDead(_7);
+          StorageDead(_6);
+          StorageDead(_3);
+          StorageDead(_2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..ac96be55312
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed.MatchBranchSimplification.diff
@@ -0,0 +1,42 @@
+- // MIR for `match_u8_i8_failed` before MatchBranchSimplification
++ // MIR for `match_u8_i8_failed` after MatchBranchSimplification
+  
+  fn match_u8_i8_failed(_1: EnumAu8) -> i8 {
+      debug i => _1;
+      let mut _0: i8;
+      let mut _2: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [0: bb5, 127: bb4, 128: bb3, 255: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const 1_i8;
+          goto -> bb6;
+      }
+  
+      bb3: {
+          _0 = const i8::MIN;
+          goto -> bb6;
+      }
+  
+      bb4: {
+          _0 = const i8::MAX;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          _0 = const 0_i8;
+          goto -> bb6;
+      }
+  
+      bb6: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed_len_1.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed_len_1.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..9ebf2cf27cb
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed_len_1.MatchBranchSimplification.diff
@@ -0,0 +1,42 @@
+- // MIR for `match_u8_i8_failed_len_1` before MatchBranchSimplification
++ // MIR for `match_u8_i8_failed_len_1` after MatchBranchSimplification
+  
+  fn match_u8_i8_failed_len_1(_1: EnumAu8) -> i8 {
+      let mut _0: i8;
+      let mut _2: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(_2) -> [0: bb1, 127: bb2, 128: bb3, 255: bb4, otherwise: bb5];
+      }
+  
+      bb1: {
+          _0 = const 0_i8;
+          goto -> bb6;
+      }
+  
+      bb2: {
+          _0 = const i8::MAX;
+          _0 = const i8::MAX;
+          goto -> bb6;
+      }
+  
+      bb3: {
+          _0 = const i8::MIN;
+          goto -> bb6;
+      }
+  
+      bb4: {
+          _0 = const -1_i8;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          unreachable;
+      }
+  
+      bb6: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed_len_2.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed_len_2.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..554856777eb
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_u8_i8_failed_len_2.MatchBranchSimplification.diff
@@ -0,0 +1,42 @@
+- // MIR for `match_u8_i8_failed_len_2` before MatchBranchSimplification
++ // MIR for `match_u8_i8_failed_len_2` after MatchBranchSimplification
+  
+  fn match_u8_i8_failed_len_2(_1: EnumAu8) -> i8 {
+      let mut _0: i8;
+      let mut _2: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(_2) -> [0: bb1, 127: bb2, 128: bb3, 255: bb4, otherwise: bb5];
+      }
+  
+      bb1: {
+          _0 = const 0_i8;
+          goto -> bb6;
+      }
+  
+      bb2: {
+          _0 = const i8::MAX;
+          goto -> bb6;
+      }
+  
+      bb3: {
+          _0 = const i8::MIN;
+          goto -> bb6;
+      }
+  
+      bb4: {
+          _0 = const -1_i8;
+          _0 = const -1_i8;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          unreachable;
+      }
+  
+      bb6: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_i8_fallback.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_i8_fallback.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..356655021f7
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_u8_i8_fallback.MatchBranchSimplification.diff
@@ -0,0 +1,38 @@
+- // MIR for `match_u8_i8_fallback` before MatchBranchSimplification
++ // MIR for `match_u8_i8_fallback` after MatchBranchSimplification
+  
+  fn match_u8_i8_fallback(_1: EnumAu8) -> i8 {
+      debug i => _1;
+      let mut _0: i8;
+      let mut _2: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [0: bb4, 127: bb3, 128: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          _0 = const -1_i8;
+          goto -> bb5;
+      }
+  
+      bb2: {
+          _0 = const i8::MIN;
+          goto -> bb5;
+      }
+  
+      bb3: {
+          _0 = const i8::MAX;
+          goto -> bb5;
+      }
+  
+      bb4: {
+          _0 = const 0_i8;
+          goto -> bb5;
+      }
+  
+      bb5: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_u16.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_u16.MatchBranchSimplification.diff
deleted file mode 100644
index dc9c1c2b97f..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_u8_u16.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,37 +0,0 @@
-- // MIR for `match_u8_u16` before MatchBranchSimplification
-+ // MIR for `match_u8_u16` after MatchBranchSimplification
-  
-  fn match_u8_u16(_1: EnumBu8) -> u16 {
-      debug i => _1;
-      let mut _0: u16;
-      let mut _2: u8;
-  
-      bb0: {
-          _2 = discriminant(_1);
-          switchInt(move _2) -> [1: bb4, 2: bb3, 5: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const 5_u16;
-          goto -> bb5;
-      }
-  
-      bb3: {
-          _0 = const 2_u16;
-          goto -> bb5;
-      }
-  
-      bb4: {
-          _0 = const 1_u16;
-          goto -> bb5;
-      }
-  
-      bb5: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_u8_u16_2.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_u8_u16_2.MatchBranchSimplification.diff
deleted file mode 100644
index b47de6a52b7..00000000000
--- a/tests/mir-opt/matches_reduce_branches.match_u8_u16_2.MatchBranchSimplification.diff
+++ /dev/null
@@ -1,37 +0,0 @@
-- // MIR for `match_u8_u16_2` before MatchBranchSimplification
-+ // MIR for `match_u8_u16_2` after MatchBranchSimplification
-  
-  fn match_u8_u16_2(_1: EnumBu8) -> i16 {
-      let mut _0: i16;
-      let mut _2: u8;
-  
-      bb0: {
-          _2 = discriminant(_1);
-          switchInt(_2) -> [1: bb1, 2: bb2, 5: bb3, otherwise: bb4];
-      }
-  
-      bb1: {
-          _0 = const 1_i16;
-          goto -> bb5;
-      }
-  
-      bb2: {
-          _0 = const 2_i16;
-          goto -> bb5;
-      }
-  
-      bb3: {
-          _0 = const 5_i16;
-          _0 = const 5_i16;
-          goto -> bb5;
-      }
-  
-      bb4: {
-          unreachable;
-      }
-  
-      bb5: {
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/matches_reduce_branches.match_zext_u8_i16.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_zext_u8_i16.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..e00a604fe25
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_zext_u8_i16.MatchBranchSimplification.diff
@@ -0,0 +1,47 @@
+- // MIR for `match_zext_u8_i16` before MatchBranchSimplification
++ // MIR for `match_zext_u8_i16` after MatchBranchSimplification
+  
+  fn match_zext_u8_i16(_1: EnumAu8) -> i16 {
+      debug i => _1;
+      let mut _0: i16;
+      let mut _2: u8;
++     let mut _3: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [0: bb5, 127: bb4, 128: bb3, 255: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const 255_i16;
+-         goto -> bb6;
+-     }
+- 
+-     bb3: {
+-         _0 = const 128_i16;
+-         goto -> bb6;
+-     }
+- 
+-     bb4: {
+-         _0 = const 127_i16;
+-         goto -> bb6;
+-     }
+- 
+-     bb5: {
+-         _0 = const 0_i16;
+-         goto -> bb6;
+-     }
+- 
+-     bb6: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as i16 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_zext_u8_i16_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_zext_u8_i16_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..a19cd796c27
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_zext_u8_i16_failed.MatchBranchSimplification.diff
@@ -0,0 +1,42 @@
+- // MIR for `match_zext_u8_i16_failed` before MatchBranchSimplification
++ // MIR for `match_zext_u8_i16_failed` after MatchBranchSimplification
+  
+  fn match_zext_u8_i16_failed(_1: EnumAu8) -> i16 {
+      debug i => _1;
+      let mut _0: i16;
+      let mut _2: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [0: bb5, 127: bb4, 128: bb3, 255: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const 255_i16;
+          goto -> bb6;
+      }
+  
+      bb3: {
+          _0 = const 128_i16;
+          goto -> bb6;
+      }
+  
+      bb4: {
+          _0 = const -127_i16;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          _0 = const 0_i16;
+          goto -> bb6;
+      }
+  
+      bb6: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_zext_u8_u16.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_zext_u8_u16.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..befb9118907
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_zext_u8_u16.MatchBranchSimplification.diff
@@ -0,0 +1,47 @@
+- // MIR for `match_zext_u8_u16` before MatchBranchSimplification
++ // MIR for `match_zext_u8_u16` after MatchBranchSimplification
+  
+  fn match_zext_u8_u16(_1: EnumAu8) -> u16 {
+      debug i => _1;
+      let mut _0: u16;
+      let mut _2: u8;
++     let mut _3: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+-         switchInt(move _2) -> [0: bb5, 127: bb4, 128: bb3, 255: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const 255_u16;
+-         goto -> bb6;
+-     }
+- 
+-     bb3: {
+-         _0 = const 128_u16;
+-         goto -> bb6;
+-     }
+- 
+-     bb4: {
+-         _0 = const 127_u16;
+-         goto -> bb6;
+-     }
+- 
+-     bb5: {
+-         _0 = const 0_u16;
+-         goto -> bb6;
+-     }
+- 
+-     bb6: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as u16 (IntToInt);
++         StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.match_zext_u8_u16_failed.MatchBranchSimplification.diff b/tests/mir-opt/matches_reduce_branches.match_zext_u8_u16_failed.MatchBranchSimplification.diff
new file mode 100644
index 00000000000..f781f88449d
--- /dev/null
+++ b/tests/mir-opt/matches_reduce_branches.match_zext_u8_u16_failed.MatchBranchSimplification.diff
@@ -0,0 +1,42 @@
+- // MIR for `match_zext_u8_u16_failed` before MatchBranchSimplification
++ // MIR for `match_zext_u8_u16_failed` after MatchBranchSimplification
+  
+  fn match_zext_u8_u16_failed(_1: EnumAu8) -> u16 {
+      debug i => _1;
+      let mut _0: u16;
+      let mut _2: u8;
+  
+      bb0: {
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [0: bb5, 127: bb4, 128: bb3, 255: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          _0 = const 255_u16;
+          goto -> bb6;
+      }
+  
+      bb3: {
+          _0 = const 128_u16;
+          goto -> bb6;
+      }
+  
+      bb4: {
+          _0 = const 65407_u16;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          _0 = const 0_u16;
+          goto -> bb6;
+      }
+  
+      bb6: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/matches_reduce_branches.rs b/tests/mir-opt/matches_reduce_branches.rs
index 176d68bcd40..9328c616127 100644
--- a/tests/mir-opt/matches_reduce_branches.rs
+++ b/tests/mir-opt/matches_reduce_branches.rs
@@ -1,8 +1,10 @@
 //@ test-mir-pass: MatchBranchSimplification
+//@ compile-flags: -Zunsound-mir-opts
 
 #![feature(repr128)]
 #![feature(core_intrinsics)]
 #![feature(custom_mir)]
+#![allow(non_camel_case_types)]
 
 use std::intrinsics::mir::*;
 
@@ -12,6 +14,7 @@ fn foo(bar: Option<()>) {
     // CHECK: = Eq(
     // CHECK: switchInt
     // CHECK-NOT: switchInt
+    // CHECK: return
     if matches!(bar, None) {
         ()
     }
@@ -23,6 +26,7 @@ fn bar(i: i32) -> (bool, bool, bool, bool) {
     // CHECK: = Ne(
     // CHECK: = Eq(
     // CHECK-NOT: switchInt
+    // CHECK: return
     let a;
     let b;
     let c;
@@ -52,6 +56,7 @@ fn bar(i: i32) -> (bool, bool, bool, bool) {
 fn match_nested_if() -> bool {
     // CHECK-LABEL: fn match_nested_if(
     // CHECK-NOT: switchInt
+    // CHECK: return
     let val = match () {
         () if if if if true { true } else { false } { true } else { false } {
             true
@@ -66,42 +71,170 @@ fn match_nested_if() -> bool {
     val
 }
 
+// # Fold switchInt into IntToInt.
+// To simplify writing and checking these test cases, I use the first character of
+// each case to distinguish the sign of the number:
+// 'u' for unsigned, '_' for negative, and 'o' for non-negative.
+// Followed by a decimal number, and add the corresponding radix representation.
+// For example, o127_0x7f represents 127i8, and _1_0xff represents -1i8.
+
+// ## Cast but without numeric conversion.
+
 #[repr(u8)]
 enum EnumAu8 {
-    A = 1,
-    B = 2,
+    u0_0x00 = 0,
+    u127_0x7f = 127,
+    u128_0x80 = 128,
+    u255_0xff = 255,
+}
+
+#[repr(i8)]
+enum EnumAi8 {
+    _128_0x80 = -128,
+    _1_0xff = -1,
+    o0_0x00 = 0,
+    o1_0x01 = 1,
+    o127_0x7f = 127,
 }
 
-// EMIT_MIR matches_reduce_branches.match_u8_i16.MatchBranchSimplification.diff
-fn match_u8_i16(i: EnumAu8) -> i16 {
-    // CHECK-LABEL: fn match_u8_i16(
+// EMIT_MIR matches_reduce_branches.match_u8_i8.MatchBranchSimplification.diff
+fn match_u8_i8(i: EnumAu8) -> i8 {
+    // CHECK-LABEL: fn match_u8_i8(
+    // CHECK-NOT: switchInt
+    // CHECK: return
+    match i {
+        EnumAu8::u0_0x00 => 0,
+        EnumAu8::u127_0x7f => 127,
+        EnumAu8::u128_0x80 => -128,
+        EnumAu8::u255_0xff => -1,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_u8_i8_failed.MatchBranchSimplification.diff
+fn match_u8_i8_failed(i: EnumAu8) -> i8 {
+    // CHECK-LABEL: fn match_u8_i8_failed(
     // CHECK: switchInt
+    // CHECK: return
     match i {
-        EnumAu8::A => 1,
-        EnumAu8::B => 2,
+        EnumAu8::u0_0x00 => 0,
+        EnumAu8::u127_0x7f => 127,
+        EnumAu8::u128_0x80 => -128,
+        EnumAu8::u255_0xff => 1, // failed
     }
 }
 
-// EMIT_MIR matches_reduce_branches.match_u8_i16_2.MatchBranchSimplification.diff
+// EMIT_MIR matches_reduce_branches.match_u8_i8_2.MatchBranchSimplification.diff
+fn match_u8_i8_2(i: EnumAu8) -> (i8, i8) {
+    // CHECK-LABEL: fn match_u8_i8_2(
+    // CHECK-NOT: switchInt
+    // CHECK: IntToInt
+    // CHECK: IntToInt
+    // CHECK: return
+    let a: i8;
+    let b: i8;
+    match i {
+        EnumAu8::u0_0x00 => {
+            a = 0;
+            b = 0;
+            ()
+        }
+        EnumAu8::u127_0x7f => {
+            a = 127;
+            b = 127;
+            ()
+        }
+        EnumAu8::u128_0x80 => {
+            a = -128;
+            b = -128;
+            ()
+        }
+        EnumAu8::u255_0xff => {
+            a = -1;
+            b = -1;
+            ()
+        }
+    };
+    (a, b)
+}
+
+// EMIT_MIR matches_reduce_branches.match_u8_i8_2_failed.MatchBranchSimplification.diff
+fn match_u8_i8_2_failed(i: EnumAu8) -> (i8, i8) {
+    // CHECK-LABEL: fn match_u8_i8_2_failed(
+    // CHECK: switchInt
+    // CHECK: return
+    let a: i8;
+    let b: i8;
+    match i {
+        EnumAu8::u0_0x00 => {
+            a = 0;
+            b = 0;
+            ()
+        }
+        EnumAu8::u127_0x7f => {
+            a = 127;
+            b = 127;
+            ()
+        }
+        EnumAu8::u128_0x80 => {
+            a = -128;
+            b = -128;
+            ()
+        }
+        EnumAu8::u255_0xff => {
+            a = -1;
+            b = 1; // failed
+            ()
+        }
+    };
+    (a, b)
+}
+
+// EMIT_MIR matches_reduce_branches.match_u8_i8_fallback.MatchBranchSimplification.diff
+fn match_u8_i8_fallback(i: EnumAu8) -> i8 {
+    // CHECK-LABEL: fn match_u8_i8_fallback(
+    // CHECK: switchInt
+    // CHECK: return
+    match i {
+        EnumAu8::u0_0x00 => 0,
+        EnumAu8::u127_0x7f => 127,
+        EnumAu8::u128_0x80 => -128,
+        _ => -1,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_u8_i8_failed_len_1.MatchBranchSimplification.diff
 // Check for different instruction lengths
 #[custom_mir(dialect = "built")]
-fn match_u8_i16_2(i: EnumAu8) -> i16 {
-    // CHECK-LABEL: fn match_u8_i16_2(
+fn match_u8_i8_failed_len_1(i: EnumAu8) -> i8 {
+    // CHECK-LABEL: fn match_u8_i8_failed_len_1(
     // CHECK: switchInt
+    // CHECK: return
     mir! {
         {
             let a = Discriminant(i);
             match a {
-                1 => bb1,
-                2 => bb2,
+                0 => bb1,
+                127 => bb2,
+                128 => bb3,
+                255 => bb4,
                 _ => unreachable_bb,
             }
         }
         bb1 = {
+            RET = 0;
             Goto(ret)
         }
         bb2 = {
-            RET = 2;
+            RET = 127;
+            RET = 127;
+            Goto(ret)
+        }
+        bb3 = {
+            RET = -128;
+            Goto(ret)
+        }
+        bb4 = {
+            RET = -1;
             Goto(ret)
         }
         unreachable_bb = {
@@ -113,72 +246,39 @@ fn match_u8_i16_2(i: EnumAu8) -> i16 {
     }
 }
 
-// EMIT_MIR matches_reduce_branches.match_u8_i16_failed.MatchBranchSimplification.diff
-fn match_u8_i16_failed(i: EnumAu8) -> i16 {
-    // CHECK-LABEL: fn match_u8_i16_failed(
-    // CHECK: switchInt
-    match i {
-        EnumAu8::A => 1,
-        EnumAu8::B => 3,
-    }
-}
-
-// EMIT_MIR matches_reduce_branches.match_u8_i16_fallback.MatchBranchSimplification.diff
-fn match_u8_i16_fallback(i: u8) -> i16 {
-    // CHECK-LABEL: fn match_u8_i16_fallback(
-    // CHECK: switchInt
-    match i {
-        1 => 1,
-        2 => 2,
-        _ => 3,
-    }
-}
-
-#[repr(u8)]
-enum EnumBu8 {
-    A = 1,
-    B = 2,
-    C = 5,
-}
-
-// EMIT_MIR matches_reduce_branches.match_u8_u16.MatchBranchSimplification.diff
-fn match_u8_u16(i: EnumBu8) -> u16 {
-    // CHECK-LABEL: fn match_u8_u16(
-    // CHECK: switchInt
-    match i {
-        EnumBu8::A => 1,
-        EnumBu8::B => 2,
-        EnumBu8::C => 5,
-    }
-}
-
-// EMIT_MIR matches_reduce_branches.match_u8_u16_2.MatchBranchSimplification.diff
+// EMIT_MIR matches_reduce_branches.match_u8_i8_failed_len_2.MatchBranchSimplification.diff
 // Check for different instruction lengths
 #[custom_mir(dialect = "built")]
-fn match_u8_u16_2(i: EnumBu8) -> i16 {
-    // CHECK-LABEL: fn match_u8_u16_2(
+fn match_u8_i8_failed_len_2(i: EnumAu8) -> i8 {
+    // CHECK-LABEL: fn match_u8_i8_failed_len_2(
     // CHECK: switchInt
+    // CHECK: return
     mir! {
         {
             let a = Discriminant(i);
             match a {
-                1 => bb1,
-                2 => bb2,
-                5 => bb5,
+                0 => bb1,
+                127 => bb2,
+                128 => bb3,
+                255 => bb4,
                 _ => unreachable_bb,
             }
         }
         bb1 = {
-            RET = 1;
+            RET = 0;
             Goto(ret)
         }
         bb2 = {
-            RET = 2;
+            RET = 127;
             Goto(ret)
         }
-        bb5 = {
-            RET = 5;
-            RET = 5;
+        bb3 = {
+            RET = -128;
+            Goto(ret)
+        }
+        bb4 = {
+            RET = -1;
+            RET = -1;
             Goto(ret)
         }
         unreachable_bb = {
@@ -190,50 +290,309 @@ fn match_u8_u16_2(i: EnumBu8) -> i16 {
     }
 }
 
-#[repr(i8)]
-enum EnumAi8 {
-    A = -1,
-    B = 2,
-    C = -3,
+// ## Cast with sext.
+
+// EMIT_MIR matches_reduce_branches.match_sext_i8_i16.MatchBranchSimplification.diff
+fn match_sext_i8_i16(i: EnumAi8) -> i16 {
+    // CHECK-LABEL: fn match_sext_i8_i16(
+    // CHECK-NOT: switchInt
+    // CHECK: return
+    match i {
+        EnumAi8::_128_0x80 => -128,
+        EnumAi8::_1_0xff => -1,
+        EnumAi8::o0_0x00 => 0,
+        EnumAi8::o1_0x01 => 1,
+        EnumAi8::o127_0x7f => 127,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_sext_i8_i16_failed.MatchBranchSimplification.diff
+// Converting `-1i8` to `255i16` is zext.
+fn match_sext_i8_i16_failed(i: EnumAi8) -> i16 {
+    // CHECK-LABEL: fn match_sext_i8_i16_failed(
+    // CHECK: switchInt
+    // CHECK: return
+    match i {
+        EnumAi8::_128_0x80 => -128,
+        EnumAi8::_1_0xff => 255, // failed
+        EnumAi8::o0_0x00 => 0,
+        EnumAi8::o1_0x01 => 1,
+        EnumAi8::o127_0x7f => 127,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_sext_i8_u16.MatchBranchSimplification.diff
+fn match_sext_i8_u16(i: EnumAi8) -> u16 {
+    // CHECK-LABEL: fn match_sext_i8_u16(
+    // CHECK-NOT: switchInt
+    // CHECK: return
+    match i {
+        EnumAi8::_128_0x80 => 0xff80,
+        EnumAi8::_1_0xff => 0xffff,
+        EnumAi8::o0_0x00 => 0,
+        EnumAi8::o1_0x01 => 1,
+        EnumAi8::o127_0x7f => 127,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_sext_i8_u16_failed.MatchBranchSimplification.diff
+// Converting `-1i8` to `255u16` is zext.
+fn match_sext_i8_u16_failed(i: EnumAi8) -> u16 {
+    // CHECK-LABEL: fn match_sext_i8_u16_failed(
+    // CHECK: switchInt
+    // CHECK: return
+    match i {
+        EnumAi8::_128_0x80 => 0xff80,
+        EnumAi8::_1_0xff => 0x00ff, // failed
+        EnumAi8::o0_0x00 => 0,
+        EnumAi8::o1_0x01 => 1,
+        EnumAi8::o127_0x7f => 127,
+    }
+}
+
+// ## Cast with zext.
+
+// EMIT_MIR matches_reduce_branches.match_zext_u8_u16.MatchBranchSimplification.diff
+fn match_zext_u8_u16(i: EnumAu8) -> u16 {
+    // CHECK-LABEL: fn match_zext_u8_u16(
+    // CHECK-NOT: switchInt
+    // CHECK: return
+    match i {
+        EnumAu8::u0_0x00 => 0,
+        EnumAu8::u127_0x7f => 0x7f,
+        EnumAu8::u128_0x80 => 128,
+        EnumAu8::u255_0xff => 255,
+    }
 }
 
-// EMIT_MIR matches_reduce_branches.match_i8_i16.MatchBranchSimplification.diff
-fn match_i8_i16(i: EnumAi8) -> i16 {
-    // CHECK-LABEL: fn match_i8_i16(
+// EMIT_MIR matches_reduce_branches.match_zext_u8_u16_failed.MatchBranchSimplification.diff
+fn match_zext_u8_u16_failed(i: EnumAu8) -> u16 {
+    // CHECK-LABEL: fn match_zext_u8_u16_failed(
     // CHECK: switchInt
+    // CHECK: return
+    match i {
+        EnumAu8::u0_0x00 => 0,
+        EnumAu8::u127_0x7f => 0xff7f, // failed
+        EnumAu8::u128_0x80 => 128,
+        EnumAu8::u255_0xff => 255,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_zext_u8_i16.MatchBranchSimplification.diff
+fn match_zext_u8_i16(i: EnumAu8) -> i16 {
+    // CHECK-LABEL: fn match_zext_u8_i16(
+    // CHECK-NOT: switchInt
+    // CHECK: return
     match i {
-        EnumAi8::A => -1,
-        EnumAi8::B => 2,
-        EnumAi8::C => -3,
+        EnumAu8::u0_0x00 => 0,
+        EnumAu8::u127_0x7f => 127,
+        EnumAu8::u128_0x80 => 128,
+        EnumAu8::u255_0xff => 255,
     }
 }
 
-// EMIT_MIR matches_reduce_branches.match_i8_i16_failed.MatchBranchSimplification.diff
-fn match_i8_i16_failed(i: EnumAi8) -> i16 {
-    // CHECK-LABEL: fn match_i8_i16_failed(
+// EMIT_MIR matches_reduce_branches.match_zext_u8_i16_failed.MatchBranchSimplification.diff
+fn match_zext_u8_i16_failed(i: EnumAu8) -> i16 {
+    // CHECK-LABEL: fn match_zext_u8_i16_failed(
     // CHECK: switchInt
+    // CHECK: return
     match i {
-        EnumAi8::A => -1,
-        EnumAi8::B => 2,
-        EnumAi8::C => 3,
+        EnumAu8::u0_0x00 => 0,
+        EnumAu8::u127_0x7f => -127, // failed
+        EnumAu8::u128_0x80 => 128,
+        EnumAu8::u255_0xff => 255,
     }
 }
 
+// ## Cast with trunc.
+
+#[repr(u16)]
+enum EnumAu16 {
+    // 0x00nn
+    u0_0x0000 = 0,
+    u127_0x007f = 127,
+    u128_0x0080 = 128,
+    u255_0x00ff = 255,
+    // 0xffnn
+    u65280_0xff00 = 65280,
+    u65407_0xff7f = 65407,
+    u65408_0xff80 = 65408,
+    u65535_0xffff = 65535,
+}
+
 #[repr(i16)]
 enum EnumAi16 {
-    A = -1,
-    B = 2,
-    C = -3,
+    // 0x00nn
+    o128_0x0080 = 128,
+    o255_0x00ff = 255,
+    o0_0x0000 = 0,
+    o1_0x0001 = 1,
+    o127_0x007f = 127,
+    // 0xffnn
+    _128_0xff80 = -128,
+    _1_0xffff = -1,
+    o0_0xff00 = -256,
+    o1_0xff01 = -255,
+    o127_0xff7f = -129,
 }
 
-// EMIT_MIR matches_reduce_branches.match_i16_i8.MatchBranchSimplification.diff
-fn match_i16_i8(i: EnumAi16) -> i8 {
-    // CHECK-LABEL: fn match_i16_i8(
+// EMIT_MIR matches_reduce_branches.match_trunc_i16_i8.MatchBranchSimplification.diff
+fn match_trunc_i16_i8(i: EnumAi16) -> i8 {
+    // CHECK-LABEL: fn match_trunc_i16_i8(
+    // CHECK-NOT: switchInt
+    // CHECK: return
+    match i {
+        // 0x00nn
+        EnumAi16::o128_0x0080 => -128,
+        EnumAi16::o255_0x00ff => -1,
+        EnumAi16::o0_0x0000 => 0,
+        EnumAi16::o1_0x0001 => 1,
+        EnumAi16::o127_0x007f => 127,
+        // 0xffnn
+        EnumAi16::_128_0xff80 => -128,
+        EnumAi16::_1_0xffff => -1,
+        EnumAi16::o0_0xff00 => 0,
+        EnumAi16::o1_0xff01 => 1,
+        EnumAi16::o127_0xff7f => 127,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_trunc_i16_i8_failed.MatchBranchSimplification.diff
+fn match_trunc_i16_i8_failed(i: EnumAi16) -> i8 {
+    // CHECK-LABEL: fn match_trunc_i16_i8_failed(
     // CHECK: switchInt
+    // CHECK: return
     match i {
-        EnumAi16::A => -1,
-        EnumAi16::B => 2,
-        EnumAi16::C => -3,
+        // 0x00nn
+        EnumAi16::o128_0x0080 => -128,
+        EnumAi16::o255_0x00ff => -1,
+        EnumAi16::o0_0x0000 => 0,
+        EnumAi16::o1_0x0001 => 1,
+        EnumAi16::o127_0x007f => 127,
+        // 0xffnn
+        EnumAi16::_128_0xff80 => -128,
+        EnumAi16::_1_0xffff => -1,
+        EnumAi16::o0_0xff00 => 0,
+        EnumAi16::o1_0xff01 => 1,
+        EnumAi16::o127_0xff7f => -127, // failed
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_trunc_i16_u8.MatchBranchSimplification.diff
+fn match_trunc_i16_u8(i: EnumAi16) -> u8 {
+    // CHECK-LABEL: fn match_trunc_i16_u8(
+    // CHECK-NOT: switchInt
+    // CHECK: return
+    match i {
+        // 0x00nn
+        EnumAi16::o128_0x0080 => 128,
+        EnumAi16::o255_0x00ff => 255,
+        EnumAi16::o0_0x0000 => 0,
+        EnumAi16::o1_0x0001 => 1,
+        EnumAi16::o127_0x007f => 127,
+        // 0xffnn
+        EnumAi16::_128_0xff80 => 128,
+        EnumAi16::_1_0xffff => 255,
+        EnumAi16::o0_0xff00 => 0,
+        EnumAi16::o1_0xff01 => 1,
+        EnumAi16::o127_0xff7f => 127,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_trunc_i16_u8_failed.MatchBranchSimplification.diff
+fn match_trunc_i16_u8_failed(i: EnumAi16) -> u8 {
+    // CHECK-LABEL: fn match_trunc_i16_u8_failed(
+    // CHECK: switchInt
+    // CHECK: return
+    match i {
+        // 0x00nn
+        EnumAi16::o128_0x0080 => 128,
+        EnumAi16::o255_0x00ff => 255,
+        EnumAi16::o0_0x0000 => 0,
+        EnumAi16::o1_0x0001 => 1,
+        EnumAi16::o127_0x007f => 127,
+        // 0xffnn
+        EnumAi16::_128_0xff80 => 128,
+        EnumAi16::_1_0xffff => 255,
+        EnumAi16::o0_0xff00 => 0,
+        EnumAi16::o1_0xff01 => 1,
+        EnumAi16::o127_0xff7f => -127i8 as u8, // failed
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_trunc_u16_u8.MatchBranchSimplification.diff
+fn match_trunc_u16_u8(i: EnumAu16) -> u8 {
+    // CHECK-LABEL: fn match_trunc_u16_u8(
+    // CHECK-NOT: switchInt
+    // CHECK: return
+    match i {
+        // 0x00nn
+        EnumAu16::u0_0x0000 => 0,
+        EnumAu16::u127_0x007f => 127,
+        EnumAu16::u128_0x0080 => 128,
+        EnumAu16::u255_0x00ff => 255,
+        // 0xffnn
+        EnumAu16::u65280_0xff00 => 0,
+        EnumAu16::u65407_0xff7f => 127,
+        EnumAu16::u65408_0xff80 => 128,
+        EnumAu16::u65535_0xffff => 255,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_trunc_u16_u8_failed.MatchBranchSimplification.diff
+fn match_trunc_u16_u8_failed(i: EnumAu16) -> u8 {
+    // CHECK-LABEL: fn match_trunc_u16_u8_failed(
+    // CHECK: switchInt
+    // CHECK: return
+    match i {
+        // 0x00nn
+        EnumAu16::u0_0x0000 => 0,
+        EnumAu16::u127_0x007f => 127,
+        EnumAu16::u128_0x0080 => 128,
+        EnumAu16::u255_0x00ff => 255,
+        // 0xffnn
+        EnumAu16::u65280_0xff00 => 0,
+        EnumAu16::u65407_0xff7f => 127,
+        EnumAu16::u65408_0xff80 => 128,
+        EnumAu16::u65535_0xffff => 127, // failed
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_trunc_u16_i8.MatchBranchSimplification.diff
+fn match_trunc_u16_i8(i: EnumAu16) -> i8 {
+    // CHECK-LABEL: fn match_trunc_u16_i8(
+    // CHECK-NOT: switchInt
+    // CHECK: return
+    match i {
+        // 0x00nn
+        EnumAu16::u0_0x0000 => 0,
+        EnumAu16::u127_0x007f => 127,
+        EnumAu16::u128_0x0080 => -128,
+        EnumAu16::u255_0x00ff => -1,
+        // 0xffnn
+        EnumAu16::u65280_0xff00 => 0,
+        EnumAu16::u65407_0xff7f => 127,
+        EnumAu16::u65408_0xff80 => -128,
+        EnumAu16::u65535_0xffff => -1,
+    }
+}
+
+// EMIT_MIR matches_reduce_branches.match_trunc_u16_i8_failed.MatchBranchSimplification.diff
+fn match_trunc_u16_i8_failed(i: EnumAu16) -> i8 {
+    // CHECK-LABEL: fn match_trunc_u16_i8_failed(
+    // CHECK: switchInt
+    // CHECK: return
+    match i {
+        // 0x00nn
+        EnumAu16::u0_0x0000 => 0,
+        EnumAu16::u127_0x007f => 127,
+        EnumAu16::u128_0x0080 => -128,
+        EnumAu16::u255_0x00ff => -1,
+        // 0xffnn
+        EnumAu16::u65280_0xff00 => 0,
+        EnumAu16::u65407_0xff7f => 127,
+        EnumAu16::u65408_0xff80 => -128,
+        EnumAu16::u65535_0xffff => 1,
     }
 }
 
@@ -248,7 +607,8 @@ enum EnumAi128 {
 // EMIT_MIR matches_reduce_branches.match_i128_u128.MatchBranchSimplification.diff
 fn match_i128_u128(i: EnumAi128) -> u128 {
     // CHECK-LABEL: fn match_i128_u128(
-    // CHECK: switchInt
+    // CHECK-NOT: switchInt
+    // CHECK: return
     match i {
         EnumAi128::A => 1,
         EnumAi128::B => 2,
@@ -262,15 +622,34 @@ fn main() {
     let _ = foo(Some(()));
     let _ = bar(0);
     let _ = match_nested_if();
-    let _ = match_u8_i16(EnumAu8::A);
-    let _ = match_u8_i16_2(EnumAu8::A);
-    let _ = match_u8_i16_failed(EnumAu8::A);
-    let _ = match_u8_i16_fallback(1);
-    let _ = match_u8_u16(EnumBu8::A);
-    let _ = match_u8_u16_2(EnumBu8::A);
-    let _ = match_i8_i16(EnumAi8::A);
-    let _ = match_i8_i16_failed(EnumAi8::A);
-    let _ = match_i8_i16(EnumAi8::A);
-    let _ = match_i16_i8(EnumAi16::A);
+
+    let _: i8 = match_u8_i8(EnumAu8::u0_0x00);
+    let _: i8 = match_u8_i8_failed(EnumAu8::u0_0x00);
+    let _: (i8, i8) = match_u8_i8_2(EnumAu8::u0_0x00);
+    let _: (i8, i8) = match_u8_i8_2_failed(EnumAu8::u0_0x00);
+    let _: i8 = match_u8_i8_fallback(EnumAu8::u0_0x00);
+    let _: i8 = match_u8_i8_failed_len_1(EnumAu8::u0_0x00);
+    let _: i8 = match_u8_i8_failed_len_2(EnumAu8::u0_0x00);
+
+    let _: i16 = match_sext_i8_i16(EnumAi8::o0_0x00);
+    let _: i16 = match_sext_i8_i16_failed(EnumAi8::o0_0x00);
+    let _: u16 = match_sext_i8_u16(EnumAi8::o0_0x00);
+    let _: u16 = match_sext_i8_u16_failed(EnumAi8::o0_0x00);
+
+    let _: u16 = match_zext_u8_u16(EnumAu8::u0_0x00);
+    let _: u16 = match_zext_u8_u16_failed(EnumAu8::u0_0x00);
+    let _: i16 = match_zext_u8_i16(EnumAu8::u0_0x00);
+    let _: i16 = match_zext_u8_i16_failed(EnumAu8::u0_0x00);
+
+    let _: i8 = match_trunc_i16_i8(EnumAi16::o0_0x0000);
+    let _: i8 = match_trunc_i16_i8_failed(EnumAi16::o0_0x0000);
+    let _: u8 = match_trunc_i16_u8(EnumAi16::o0_0x0000);
+    let _: u8 = match_trunc_i16_u8_failed(EnumAi16::o0_0x0000);
+
+    let _: i8 = match_trunc_u16_i8(EnumAu16::u0_0x0000);
+    let _: i8 = match_trunc_u16_i8_failed(EnumAu16::u0_0x0000);
+    let _: u8 = match_trunc_u16_u8(EnumAu16::u0_0x0000);
+    let _: u8 = match_trunc_u16_u8_failed(EnumAu16::u0_0x0000);
+
     let _ = match_i128_u128(EnumAi128::A);
 }
diff --git a/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff b/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff
index 157f9c98353..11a18f58e3a 100644
--- a/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff
+++ b/tests/mir-opt/matches_u8.exhaustive_match.MatchBranchSimplification.diff
@@ -5,27 +5,32 @@
       debug e => _1;
       let mut _0: u8;
       let mut _2: isize;
++     let mut _3: isize;
   
       bb0: {
           _2 = discriminant(_1);
-          switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const 1_u8;
-          goto -> bb4;
-      }
-  
-      bb3: {
-          _0 = const 0_u8;
-          goto -> bb4;
-      }
-  
-      bb4: {
+-         switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const 1_u8;
+-         goto -> bb4;
+-     }
+- 
+-     bb3: {
+-         _0 = const 0_u8;
+-         goto -> bb4;
+-     }
+- 
+-     bb4: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as u8 (IntToInt);
++         StorageDead(_3);
           return;
       }
   }
diff --git a/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff b/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
index 19083771fd9..809badc41ba 100644
--- a/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
+++ b/tests/mir-opt/matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff
@@ -5,27 +5,32 @@
       debug e => _1;
       let mut _0: i8;
       let mut _2: isize;
++     let mut _3: isize;
   
       bb0: {
           _2 = discriminant(_1);
-          switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
-          _0 = const 1_i8;
-          goto -> bb4;
-      }
-  
-      bb3: {
-          _0 = const 0_i8;
-          goto -> bb4;
-      }
-  
-      bb4: {
+-         switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1];
+-     }
+- 
+-     bb1: {
+-         unreachable;
+-     }
+- 
+-     bb2: {
+-         _0 = const 1_i8;
+-         goto -> bb4;
+-     }
+- 
+-     bb3: {
+-         _0 = const 0_i8;
+-         goto -> bb4;
+-     }
+- 
+-     bb4: {
++         StorageLive(_3);
++         _3 = move _2;
++         _0 = _3 as i8 (IntToInt);
++         StorageDead(_3);
           return;
       }
   }
diff --git a/tests/mir-opt/matches_u8.rs b/tests/mir-opt/matches_u8.rs
index 86d64625674..89deead461e 100644
--- a/tests/mir-opt/matches_u8.rs
+++ b/tests/mir-opt/matches_u8.rs
@@ -1,5 +1,6 @@
 // skip-filecheck
 //@ test-mir-pass: MatchBranchSimplification
+//@ compile-flags: -Zunsound-mir-opts
 
 // EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff
 // EMIT_MIR matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff