Skip to content

Commit 829b703

Browse files
committed
always add an unreachable branch on matches to give more info to llvm about which values are possible
1 parent 9b53f0a commit 829b703

File tree

3 files changed

+42
-31
lines changed

3 files changed

+42
-31
lines changed

src/librustc_mir/build/matches/test.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
187187
let num_enum_variants = self.hir.num_variants(adt_def);
188188
let used_variants = variants.count();
189189
let mut otherwise_block = None;
190-
let mut target_blocks = Vec::with_capacity(num_enum_variants);
190+
let mut target_blocks = Vec::with_capacity(num_enum_variants + 1);
191191
let mut targets = Vec::with_capacity(used_variants + 1);
192192
let mut values = Vec::with_capacity(used_variants);
193193
let tcx = self.hir.tcx();
@@ -205,7 +205,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
205205
if let Some(otherwise_block) = otherwise_block {
206206
targets.push(otherwise_block);
207207
} else {
208-
values.pop();
208+
let unreachable_block = self.cfg.start_new_block();
209+
targets.push(unreachable_block);
210+
target_blocks.push(unreachable_block);
209211
}
210212
debug!("num_enum_variants: {}, tested variants: {:?}, variants: {:?}",
211213
num_enum_variants, values, variants);

src/test/codegen/match.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ pub enum E {
2121
#[no_mangle]
2222
pub fn exhaustive_match(e: E) {
2323
// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
24-
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[TRUE:[a-zA-Z0-9_]+]]
24+
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
25+
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
2526
// CHECK-NEXT: ]
26-
// CHECK: [[TRUE]]:
27+
// CHECK: [[A]]:
2728
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
28-
// CHECK: [[OTHERWISE]]:
29+
// CHECK: [[B]]:
2930
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
31+
// CHECK: [[OTHERWISE]]:
32+
// CHECK-NEXT: unreachable
3033
match e {
3134
E::A => (),
3235
E::B => (),

src/test/mir-opt/match_false_edges.rs

+32-26
Original file line numberDiff line numberDiff line change
@@ -54,53 +54,56 @@ fn main() {
5454
// ...
5555
// _2 = std::option::Option<i32>::Some(const 42i32,);
5656
// _5 = discriminant(_2);
57-
// switchInt(_5) -> [0isize: bb5, otherwise: bb3];
57+
// switchInt(_5) -> [0isize: bb5, 1isize: bb3, otherwise: bb7];
5858
// }
5959
// bb1: { // arm1
6060
// StorageLive(_7);
6161
// _7 = _3;
6262
// _1 = (const 1i32, _7);
6363
// StorageDead(_7);
64-
// goto -> bb11;
64+
// goto -> bb12;
6565
// }
6666
// bb2: { // binding3(empty) and arm3
6767
// _1 = (const 3i32, const 3i32);
68-
// goto -> bb11;
68+
// goto -> bb12;
6969
// }
7070
// bb3: {
71-
// falseEdges -> [real: bb7, imaginary: bb4]; //pre_binding1
71+
// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1
7272
// }
7373
// bb4: {
74-
// falseEdges -> [real: bb10, imaginary: bb5]; //pre_binding2
74+
// falseEdges -> [real: bb11, imaginary: bb5]; //pre_binding2
7575
// }
7676
// bb5: {
7777
// falseEdges -> [real: bb2, imaginary: bb6]; //pre_binding3
7878
// }
7979
// bb6: {
8080
// unreachable;
8181
// }
82-
// bb7: { // binding1 and guard
82+
// bb7: {
83+
// unreachable;
84+
// }
85+
// bb8: { // binding1 and guard
8386
// StorageLive(_3);
8487
// _3 = ((_2 as Some).0: i32);
8588
// StorageLive(_6);
86-
// _6 = const guard() -> bb8;
89+
// _6 = const guard() -> bb9;
8790
// }
88-
// bb8: { // end of guard
89-
// switchInt(_6) -> [0u8: bb9, otherwise: bb1];
91+
// bb9: { // end of guard
92+
// switchInt(_6) -> [0u8: bb10, otherwise: bb1];
9093
// }
91-
// bb9: { // to pre_binding2
94+
// bb10: { // to pre_binding2
9295
// falseEdges -> [real: bb4, imaginary: bb4];
9396
// }
94-
// bb10: { // bindingNoLandingPads.before.mir2 and arm2
97+
// bb11: { // bindingNoLandingPads.before.mir2 and arm2
9598
// StorageLive(_4);
9699
// _4 = ((_2 as Some).0: i32);
97100
// StorageLive(_8);
98101
// _8 = _4;
99102
// _1 = (const 2i32, _8);
100103
// StorageDead(_8);
101-
// goto -> bb11;
104+
// goto -> bb12;
102105
// }
103-
// bb11: {
106+
// bb12: {
104107
// ...
105108
// return;
106109
// }
@@ -111,53 +114,56 @@ fn main() {
111114
// ...
112115
// _2 = std::option::Option<i32>::Some(const 42i32,);
113116
// _5 = discriminant(_2);
114-
// switchInt(_5) -> [0isize: bb4, otherwise: bb3];
117+
// switchInt(_5) -> [0isize: bb4, 1isize: bb3, otherwise: bb7];
115118
// }
116119
// bb1: { // arm1
117120
// StorageLive(_7);
118121
// _7 = _3;
119122
// _1 = (const 1i32, _7);
120123
// StorageDead(_7);
121-
// goto -> bb11;
124+
// goto -> bb12;
122125
// }
123126
// bb2: { // binding3(empty) and arm3
124127
// _1 = (const 3i32, const 3i32);
125-
// goto -> bb11;
128+
// goto -> bb12;
126129
// }
127130
// bb3: {
128-
// falseEdges -> [real: bb7, imaginary: bb4]; //pre_binding1
131+
// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1
129132
// }
130133
// bb4: {
131134
// falseEdges -> [real: bb2, imaginary: bb5]; //pre_binding2
132135
// }
133136
// bb5: {
134-
// falseEdges -> [real: bb10, imaginary: bb6]; //pre_binding3
137+
// falseEdges -> [real: bb11, imaginary: bb6]; //pre_binding3
135138
// }
136139
// bb6: {
137140
// unreachable;
138141
// }
139-
// bb7: { // binding1 and guard
142+
// bb7: {
143+
// unreachable;
144+
// }
145+
// bb8: { // binding1 and guard
140146
// StorageLive(_3);
141147
// _3 = ((_2 as Some).0: i32);
142148
// StorageLive(_6);
143-
// _6 = const guard() -> bb8;
149+
// _6 = const guard() -> bb9;
144150
// }
145-
// bb8: { // end of guard
146-
// switchInt(_6) -> [0u8: bb9, otherwise: bb1];
151+
// bb9: { // end of guard
152+
// switchInt(_6) -> [0u8: bb10, otherwise: bb1];
147153
// }
148-
// bb9: { // to pre_binding2
154+
// bb10: { // to pre_binding2
149155
// falseEdges -> [real: bb5, imaginary: bb4];
150156
// }
151-
// bb10: { // binding2 and arm2
157+
// bb11: { // binding2 and arm2
152158
// StorageLive(_4);
153159
// _4 = ((_2 as Some).0: i32);
154160
// StorageLive(_8);
155161
// _8 = _4;
156162
// _1 = (const 2i32, _8);
157163
// StorageDead(_8);
158-
// goto -> bb11;
164+
// goto -> bb12;
159165
// }
160-
// bb11: {
166+
// bb12: {
161167
// ...
162168
// return;
163169
// }

0 commit comments

Comments
 (0)