Skip to content

Commit

Permalink
Get all variants to eliminate the default branching if we cannot get …
Browse files Browse the repository at this point in the history
…the layout of type
  • Loading branch information
DianQK committed Jan 24, 2024
1 parent e8c09fd commit d02299c
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 111 deletions.
Expand Up @@ -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;
};
Expand Down
Expand Up @@ -3,7 +3,8 @@
fn num_to_digit(_1: char) -> u32 {
debug num => _1;
let mut _0: u32;
let mut _5: std::option::Option<u32>;
let mut _5: bool;
let mut _6: std::option::Option<u32>;
scope 1 (inlined char::methods::<impl char>::is_digit) {
debug self => _1;
debug radix => const 8_u32;
Expand All @@ -15,15 +16,16 @@ fn num_to_digit(_1: char) -> u32 {
}
}
scope 3 (inlined #[track_caller] Option::<u32>::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::<impl char>::to_digit(_1, const 8_u32) -> [return: bb1, unwind unreachable];
Expand All @@ -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::<impl char>::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::<impl char>::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;
}
}
Expand Up @@ -3,7 +3,8 @@
fn num_to_digit(_1: char) -> u32 {
debug num => _1;
let mut _0: u32;
let mut _5: std::option::Option<u32>;
let mut _5: bool;
let mut _6: std::option::Option<u32>;
scope 1 (inlined char::methods::<impl char>::is_digit) {
debug self => _1;
debug radix => const 8_u32;
Expand All @@ -15,15 +16,16 @@ fn num_to_digit(_1: char) -> u32 {
}
}
scope 3 (inlined #[track_caller] Option::<u32>::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::<impl char>::to_digit(_1, const 8_u32) -> [return: bb1, unwind continue];
Expand All @@ -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::<impl char>::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::<impl char>::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;
}
}
Expand Up @@ -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 <u32 as Step>::forward) {
debug start => _1;
debug n => _2;
let _3: std::option::Option<u32>;
let mut _4: &std::option::Option<u32>;
let mut _7: bool;
let mut _8: u32;
scope 2 {
}
scope 3 (inlined Option::<u32>::is_none) {
debug self => _4;
let mut _6: bool;
scope 4 (inlined Option::<u32>::is_some) {
debug self => _4;
let mut _5: isize;
}
}
scope 5 (inlined core::num::<impl u32>::wrapping_add) {
debug self => _1;
debug rhs => _8;
}
}

bb0: {
StorageLive(_7);
StorageLive(_4);
StorageLive(_3);
_3 = <u32 as Step>::forward_checked(_1, _2) -> [return: bb1, unwind continue];
_0 = <u32 as Step>::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;
}
}
Expand Up @@ -28,7 +28,7 @@

bb1: {
_4 = discriminant((_1.1: std::option::Option<T>));
switchInt(move _4) -> [0: bb2, otherwise: bb3];
switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb5];
}

bb2: {
Expand Down
Expand Up @@ -28,7 +28,7 @@

bb1: {
_4 = discriminant((_1.1: std::option::Option<T>));
switchInt(move _4) -> [0: bb2, otherwise: bb3];
switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb5];
}

bb2: {
Expand Down
Expand Up @@ -5,7 +5,7 @@
let mut _0: ();
let _1: &str;
let mut _2: Test5<T>;
let mut _3: isize;
let mut _3: i8;
let _4: &str;
let _5: &str;
let _6: &str;
Expand All @@ -15,7 +15,8 @@
StorageLive(_2);
_2 = Test5::<T>::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: {
Expand Down Expand Up @@ -60,6 +61,10 @@

bb7 (cleanup): {
resume;
+ }
+
+ bb8: {
+ unreachable;
}
}

16 changes: 8 additions & 8 deletions tests/mir-opt/uninhabited_enum_branching.rs
Expand Up @@ -30,11 +30,12 @@ enum Test4 {
D,
}

#[repr(i8)]
enum Test5<T> {
A(T),
B(T),
C,
D,
A(T) = -1,
B(T) = 0,
C = 5,
D = 3,
}

struct Plop {
Expand Down Expand Up @@ -163,10 +164,9 @@ fn otherwise_t4() {
fn otherwise_t5_uninhabited_default<T>() {
// 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::<T>::C {
Test5::A(_) => "A(T)",
Test5::B(_) => "B(T)",
Expand Down

0 comments on commit d02299c

Please sign in to comment.