about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDjzin <djzin@users.noreply.github.com>2017-11-07 00:07:32 +0000
committerDjzin <djzin@users.noreply.github.com>2017-11-14 06:33:39 +0000
commit829b70330e93779575daa35fc4ddc1dd0df15efa (patch)
tree7a099761e087209ab308405a69ed2dc0b641c62d
parent9b53f0a6620c3451a10573ea5c5a51b4c18088ec (diff)
downloadrust-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.rs6
-rw-r--r--src/test/codegen/match.rs9
-rw-r--r--src/test/mir-opt/match_false_edges.rs58
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;
 //  }