diff options
| author | Djzin <djzin@users.noreply.github.com> | 2017-11-07 00:07:32 +0000 |
|---|---|---|
| committer | Djzin <djzin@users.noreply.github.com> | 2017-11-14 06:33:39 +0000 |
| commit | 829b70330e93779575daa35fc4ddc1dd0df15efa (patch) | |
| tree | 7a099761e087209ab308405a69ed2dc0b641c62d | |
| parent | 9b53f0a6620c3451a10573ea5c5a51b4c18088ec (diff) | |
| download | rust-829b70330e93779575daa35fc4ddc1dd0df15efa.tar.gz rust-829b70330e93779575daa35fc4ddc1dd0df15efa.zip | |
always add an unreachable branch on matches to give more info to llvm about which values are possible
| -rw-r--r-- | src/librustc_mir/build/matches/test.rs | 6 | ||||
| -rw-r--r-- | src/test/codegen/match.rs | 9 | ||||
| -rw-r--r-- | src/test/mir-opt/match_false_edges.rs | 58 |
3 files changed, 42 insertions, 31 deletions
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 4792bf2b213..439f028ca8a 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -187,7 +187,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let num_enum_variants = self.hir.num_variants(adt_def); let used_variants = variants.count(); let mut otherwise_block = None; - let mut target_blocks = Vec::with_capacity(num_enum_variants); + let mut target_blocks = Vec::with_capacity(num_enum_variants + 1); let mut targets = Vec::with_capacity(used_variants + 1); let mut values = Vec::with_capacity(used_variants); let tcx = self.hir.tcx(); @@ -205,7 +205,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { if let Some(otherwise_block) = otherwise_block { targets.push(otherwise_block); } else { - values.pop(); + let unreachable_block = self.cfg.start_new_block(); + targets.push(unreachable_block); + target_blocks.push(unreachable_block); } debug!("num_enum_variants: {}, tested variants: {:?}, variants: {:?}", num_enum_variants, values, variants); diff --git a/src/test/codegen/match.rs b/src/test/codegen/match.rs index aa100da6013..660b6346c57 100644 --- a/src/test/codegen/match.rs +++ b/src/test/codegen/match.rs @@ -21,12 +21,15 @@ pub enum E { #[no_mangle] pub fn exhaustive_match(e: E) { // CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [ -// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[TRUE:[a-zA-Z0-9_]+]] +// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]] +// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]] // CHECK-NEXT: ] -// CHECK: [[TRUE]]: +// CHECK: [[A]]: // CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]] -// CHECK: [[OTHERWISE]]: +// CHECK: [[B]]: // CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]] +// CHECK: [[OTHERWISE]]: +// CHECK-NEXT: unreachable match e { E::A => (), E::B => (), diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index 02e9d39668d..318db7a9e3e 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -54,24 +54,24 @@ fn main() { // ... // _2 = std::option::Option<i32>::Some(const 42i32,); // _5 = discriminant(_2); -// switchInt(_5) -> [0isize: bb5, otherwise: bb3]; +// switchInt(_5) -> [0isize: bb5, 1isize: bb3, otherwise: bb7]; // } // bb1: { // arm1 // StorageLive(_7); // _7 = _3; // _1 = (const 1i32, _7); // StorageDead(_7); -// goto -> bb11; +// goto -> bb12; // } // bb2: { // binding3(empty) and arm3 // _1 = (const 3i32, const 3i32); -// goto -> bb11; +// goto -> bb12; // } // bb3: { -// falseEdges -> [real: bb7, imaginary: bb4]; //pre_binding1 +// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1 // } // bb4: { -// falseEdges -> [real: bb10, imaginary: bb5]; //pre_binding2 +// falseEdges -> [real: bb11, imaginary: bb5]; //pre_binding2 // } // bb5: { // falseEdges -> [real: bb2, imaginary: bb6]; //pre_binding3 @@ -79,28 +79,31 @@ fn main() { // bb6: { // unreachable; // } -// bb7: { // binding1 and guard +// bb7: { +// unreachable; +// } +// bb8: { // binding1 and guard // StorageLive(_3); // _3 = ((_2 as Some).0: i32); // StorageLive(_6); -// _6 = const guard() -> bb8; +// _6 = const guard() -> bb9; // } -// bb8: { // end of guard -// switchInt(_6) -> [0u8: bb9, otherwise: bb1]; +// bb9: { // end of guard +// switchInt(_6) -> [0u8: bb10, otherwise: bb1]; // } -// bb9: { // to pre_binding2 +// bb10: { // to pre_binding2 // falseEdges -> [real: bb4, imaginary: bb4]; // } -// bb10: { // bindingNoLandingPads.before.mir2 and arm2 +// bb11: { // bindingNoLandingPads.before.mir2 and arm2 // StorageLive(_4); // _4 = ((_2 as Some).0: i32); // StorageLive(_8); // _8 = _4; // _1 = (const 2i32, _8); // StorageDead(_8); -// goto -> bb11; +// goto -> bb12; // } -// bb11: { +// bb12: { // ... // return; // } @@ -111,53 +114,56 @@ fn main() { // ... // _2 = std::option::Option<i32>::Some(const 42i32,); // _5 = discriminant(_2); -// switchInt(_5) -> [0isize: bb4, otherwise: bb3]; +// switchInt(_5) -> [0isize: bb4, 1isize: bb3, otherwise: bb7]; // } // bb1: { // arm1 // StorageLive(_7); // _7 = _3; // _1 = (const 1i32, _7); // StorageDead(_7); -// goto -> bb11; +// goto -> bb12; // } // bb2: { // binding3(empty) and arm3 // _1 = (const 3i32, const 3i32); -// goto -> bb11; +// goto -> bb12; // } // bb3: { -// falseEdges -> [real: bb7, imaginary: bb4]; //pre_binding1 +// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1 // } // bb4: { // falseEdges -> [real: bb2, imaginary: bb5]; //pre_binding2 // } // bb5: { -// falseEdges -> [real: bb10, imaginary: bb6]; //pre_binding3 +// falseEdges -> [real: bb11, imaginary: bb6]; //pre_binding3 // } // bb6: { // unreachable; // } -// bb7: { // binding1 and guard +// bb7: { +// unreachable; +// } +// bb8: { // binding1 and guard // StorageLive(_3); // _3 = ((_2 as Some).0: i32); // StorageLive(_6); -// _6 = const guard() -> bb8; +// _6 = const guard() -> bb9; // } -// bb8: { // end of guard -// switchInt(_6) -> [0u8: bb9, otherwise: bb1]; +// bb9: { // end of guard +// switchInt(_6) -> [0u8: bb10, otherwise: bb1]; // } -// bb9: { // to pre_binding2 +// bb10: { // to pre_binding2 // falseEdges -> [real: bb5, imaginary: bb4]; // } -// bb10: { // binding2 and arm2 +// bb11: { // binding2 and arm2 // StorageLive(_4); // _4 = ((_2 as Some).0: i32); // StorageLive(_8); // _8 = _4; // _1 = (const 2i32, _8); // StorageDead(_8); -// goto -> bb11; +// goto -> bb12; // } -// bb11: { +// bb12: { // ... // return; // } |
