From d02299c2267cf5e402ee9f07fac3bb51bb54ef3b Mon Sep 17 00:00:00 2001 From: DianQK Date: Wed, 24 Jan 2024 20:47:39 +0800 Subject: [PATCH] Get all variants to eliminate the default branching if we cannot get the layout of type --- .../src/uninhabited_enum_branching.rs | 6 ++ ..._to_digit.PreCodegen.after.panic-abort.mir | 60 ++++++++++++------- ...to_digit.PreCodegen.after.panic-unwind.mir | 60 ++++++++++++------- ...cked_ops.step_forward.PreCodegen.after.mir | 56 +---------------- ....foo.SimplifyLocals-final.panic-abort.diff | 2 +- ...foo.SimplifyLocals-final.panic-unwind.diff | 2 +- ...ited_default.UninhabitedEnumBranching.diff | 9 ++- tests/mir-opt/uninhabited_enum_branching.rs | 16 ++--- 8 files changed, 100 insertions(+), 111 deletions(-) diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs index dbe9ba08d7c55..e4723e8d74af4 100644 --- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs @@ -95,6 +95,12 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { let mut allowed_variants = if let Ok(layout) = layout { variant_discriminants(&layout, discriminant_ty, tcx) + } else if let Some(variant_range) = discriminant_ty.variant_range(tcx) { + variant_range + .map(|variant| { + discriminant_ty.discriminant_for_variant(tcx, variant).unwrap().val + }) + .collect() } else { continue; }; diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir index f7be8b75db7b8..ea400ac9b2998 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir @@ -3,7 +3,8 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; let mut _0: u32; - let mut _5: std::option::Option; + let mut _5: bool; + let mut _6: std::option::Option; scope 1 (inlined char::methods::::is_digit) { debug self => _1; debug radix => const 8_u32; @@ -15,15 +16,16 @@ fn num_to_digit(_1: char) -> u32 { } } scope 3 (inlined #[track_caller] Option::::unwrap) { - debug self => _5; - let mut _6: isize; - let mut _7: !; + debug self => _6; + let mut _7: isize; + let mut _8: !; scope 4 { debug val => _0; } } bb0: { + StorageLive(_5); StorageLive(_3); StorageLive(_2); _2 = char::methods::::to_digit(_1, const 8_u32) -> [return: bb1, unwind unreachable]; @@ -33,45 +35,59 @@ fn num_to_digit(_1: char) -> u32 { _3 = &_2; StorageLive(_4); _4 = discriminant(_2); - StorageDead(_3); - StorageDead(_2); - switchInt(move _4) -> [1: bb2, otherwise: bb7]; + switchInt(move _4) -> [1: bb2, 0: bb3, otherwise: bb11]; } bb2: { - StorageDead(_4); - StorageLive(_5); - _5 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable]; + _5 = const true; + goto -> bb4; } bb3: { - StorageLive(_6); - _6 = discriminant(_5); - switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb6]; + _5 = const false; + goto -> bb4; } bb4: { - _7 = option::unwrap_failed() -> unwind unreachable; + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + switchInt(move _5) -> [0: bb5, otherwise: bb6]; } bb5: { - _0 = move ((_5 as Some).0: u32); - StorageDead(_6); - StorageDead(_5); - goto -> bb8; + _0 = const 0_u32; + goto -> bb10; } bb6: { - unreachable; + StorageLive(_6); + _6 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb7, unwind unreachable]; } bb7: { - StorageDead(_4); - _0 = const 0_u32; - goto -> bb8; + StorageLive(_7); + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb8, 1: bb9, otherwise: bb11]; } bb8: { + _8 = option::unwrap_failed() -> unwind unreachable; + } + + bb9: { + _0 = move ((_6 as Some).0: u32); + StorageDead(_7); + StorageDead(_6); + goto -> bb10; + } + + bb10: { + StorageDead(_5); return; } + + bb11: { + unreachable; + } } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir index e76fe992ac7d3..ca7dd89e5589a 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir @@ -3,7 +3,8 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; let mut _0: u32; - let mut _5: std::option::Option; + let mut _5: bool; + let mut _6: std::option::Option; scope 1 (inlined char::methods::::is_digit) { debug self => _1; debug radix => const 8_u32; @@ -15,15 +16,16 @@ fn num_to_digit(_1: char) -> u32 { } } scope 3 (inlined #[track_caller] Option::::unwrap) { - debug self => _5; - let mut _6: isize; - let mut _7: !; + debug self => _6; + let mut _7: isize; + let mut _8: !; scope 4 { debug val => _0; } } bb0: { + StorageLive(_5); StorageLive(_3); StorageLive(_2); _2 = char::methods::::to_digit(_1, const 8_u32) -> [return: bb1, unwind continue]; @@ -33,45 +35,59 @@ fn num_to_digit(_1: char) -> u32 { _3 = &_2; StorageLive(_4); _4 = discriminant(_2); - StorageDead(_3); - StorageDead(_2); - switchInt(move _4) -> [1: bb2, otherwise: bb7]; + switchInt(move _4) -> [1: bb2, 0: bb3, otherwise: bb11]; } bb2: { - StorageDead(_4); - StorageLive(_5); - _5 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue]; + _5 = const true; + goto -> bb4; } bb3: { - StorageLive(_6); - _6 = discriminant(_5); - switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb6]; + _5 = const false; + goto -> bb4; } bb4: { - _7 = option::unwrap_failed() -> unwind continue; + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + switchInt(move _5) -> [0: bb5, otherwise: bb6]; } bb5: { - _0 = move ((_5 as Some).0: u32); - StorageDead(_6); - StorageDead(_5); - goto -> bb8; + _0 = const 0_u32; + goto -> bb10; } bb6: { - unreachable; + StorageLive(_6); + _6 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb7, unwind continue]; } bb7: { - StorageDead(_4); - _0 = const 0_u32; - goto -> bb8; + StorageLive(_7); + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb8, 1: bb9, otherwise: bb11]; } bb8: { + _8 = option::unwrap_failed() -> unwind continue; + } + + bb9: { + _0 = move ((_6 as Some).0: u32); + StorageDead(_7); + StorageDead(_6); + goto -> bb10; + } + + bb10: { + StorageDead(_5); return; } + + bb11: { + unreachable; + } } diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir index cf7feef00514a..f1d0da28b4ef1 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir @@ -4,66 +4,12 @@ fn step_forward(_1: u32, _2: usize) -> u32 { debug x => _1; debug n => _2; let mut _0: u32; - scope 1 (inlined ::forward) { - debug start => _1; - debug n => _2; - let _3: std::option::Option; - let mut _4: &std::option::Option; - let mut _7: bool; - let mut _8: u32; - scope 2 { - } - scope 3 (inlined Option::::is_none) { - debug self => _4; - let mut _6: bool; - scope 4 (inlined Option::::is_some) { - debug self => _4; - let mut _5: isize; - } - } - scope 5 (inlined core::num::::wrapping_add) { - debug self => _1; - debug rhs => _8; - } - } bb0: { - StorageLive(_7); - StorageLive(_4); - StorageLive(_3); - _3 = ::forward_checked(_1, _2) -> [return: bb1, unwind continue]; + _0 = ::forward(move _1, move _2) -> [return: bb1, unwind continue]; } bb1: { - _4 = &_3; - StorageLive(_6); - StorageLive(_5); - _5 = discriminant(_3); - _6 = Eq(_5, const 1_isize); - StorageDead(_5); - _7 = Not(move _6); - StorageDead(_6); - switchInt(move _7) -> [0: bb2, otherwise: bb3]; - } - - bb2: { - StorageDead(_3); - StorageDead(_4); - goto -> bb4; - } - - bb3: { - StorageDead(_3); - StorageDead(_4); - assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> [success: bb4, unwind continue]; - } - - bb4: { - StorageDead(_7); - StorageLive(_8); - _8 = _2 as u32 (IntToInt); - _0 = Add(_1, _8); - StorageDead(_8); return; } } diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff index 3108b7d3e13d7..c520a159f47b2 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff @@ -28,7 +28,7 @@ bb1: { _4 = discriminant((_1.1: std::option::Option)); - switchInt(move _4) -> [0: bb2, otherwise: bb3]; + switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb5]; } bb2: { diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff index 3ef3be198ede3..686581591fc4e 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff @@ -28,7 +28,7 @@ bb1: { _4 = discriminant((_1.1: std::option::Option)); - switchInt(move _4) -> [0: bb2, otherwise: bb3]; + switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb5]; } bb2: { diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.diff index edaaa0db588b0..b13d5816aed9d 100644 --- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.diff @@ -5,7 +5,7 @@ let mut _0: (); let _1: &str; let mut _2: Test5; - let mut _3: isize; + let mut _3: i8; let _4: &str; let _5: &str; let _6: &str; @@ -15,7 +15,8 @@ StorageLive(_2); _2 = Test5::::C; _3 = discriminant(_2); - switchInt(move _3) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb1]; +- switchInt(move _3) -> [255: bb2, 0: bb3, 5: bb4, otherwise: bb1]; ++ switchInt(move _3) -> [255: bb2, 0: bb3, 5: bb4, 3: bb1, otherwise: bb8]; } bb1: { @@ -60,6 +61,10 @@ bb7 (cleanup): { resume; ++ } ++ ++ bb8: { ++ unreachable; } } diff --git a/tests/mir-opt/uninhabited_enum_branching.rs b/tests/mir-opt/uninhabited_enum_branching.rs index 9cd5c70a3e6a2..353a1c9fcb4f6 100644 --- a/tests/mir-opt/uninhabited_enum_branching.rs +++ b/tests/mir-opt/uninhabited_enum_branching.rs @@ -30,11 +30,12 @@ enum Test4 { D, } +#[repr(i8)] enum Test5 { - A(T), - B(T), - C, - D, + A(T) = -1, + B(T) = 0, + C = 5, + D = 3, } struct Plop { @@ -163,10 +164,9 @@ fn otherwise_t4() { fn otherwise_t5_uninhabited_default() { // CHECK-LABEL: fn otherwise_t5_uninhabited_default( // CHECK: [[discr:_.*]] = discriminant( - // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb1]; - // CHECK: bb1: { - // CHECK-NOT: unreachable; - // CHECK: } + // CHECK: switchInt(move [[discr]]) -> [255: bb2, 0: bb3, 5: bb4, 3: bb1, otherwise: [[unreachable:bb.*]]]; + // CHECK: [[unreachable]]: { + // CHECK-NEXT: unreachable; match Test5::::C { Test5::A(_) => "A(T)", Test5::B(_) => "B(T)",