1- // skip-filecheck
21// unit-test: DataflowConstProp
32// EMIT_MIR_FOR_EACH_BIT_WIDTH
43
@@ -13,34 +12,76 @@ enum E {
1312}
1413
1514// EMIT_MIR enum.simple.DataflowConstProp.diff
15+
16+ // CHECK-LABEL: fn simple(
1617fn simple ( ) {
18+ // CHECK: debug e => [[e:_.*]];
19+ // CHECK: debug x => [[x:_.*]];
20+ // CHECK: [[e]] = const E::V1(0_i32);
1721 let e = E :: V1 ( 0 ) ;
18- let x = match e { E :: V1 ( x) => x, E :: V2 ( x) => x } ;
22+
23+ // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
24+ // CHECK: [[target_bb]]: {
25+ // CHECK: [[x]] = const 0_i32;
26+ let x = match e { E :: V1 ( x1) => x1, E :: V2 ( x2) => x2 } ;
1927}
2028
2129// EMIT_MIR enum.constant.DataflowConstProp.diff
30+
31+ // CHECK-LABEL: fn constant(
2232fn constant ( ) {
33+ // CHECK: debug e => [[e:_.*]];
34+ // CHECK: debug x => [[x:_.*]];
2335 const C : E = E :: V1 ( 0 ) ;
36+
37+ // CHECK: [[e]] = const _;
2438 let e = C ;
25- let x = match e { E :: V1 ( x) => x, E :: V2 ( x) => x } ;
39+ // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
40+ // CHECK: [[target_bb]]: {
41+ // CHECK: [[x]] = const 0_i32;
42+ let x = match e { E :: V1 ( x1) => x1, E :: V2 ( x2) => x2 } ;
2643}
2744
2845// EMIT_MIR enum.statics.DataflowConstProp.diff
46+
47+ // CHECK-LABEL: fn statics(
2948fn statics ( ) {
49+ // CHECK: debug e1 => [[e1:_.*]];
50+ // CHECK: debug x1 => [[x1:_.*]];
51+ // CHECK: debug e2 => [[e2:_.*]];
52+ // CHECK: debug x2 => [[x2:_.*]];
53+
3054 static C : E = E :: V1 ( 0 ) ;
31- let e = C ;
32- let x = match e { E :: V1 ( x) => x, E :: V2 ( x) => x } ;
55+
56+ // CHECK: [[e1]] = const E::V1(0_i32);
57+ let e1 = C ;
58+ // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
59+ // CHECK: [[target_bb]]: {
60+ // CHECK: [[x1]] = const 0_i32;
61+ let x1 = match e1 { E :: V1 ( x11) => x11, E :: V2 ( x12) => x12 } ;
3362
3463 static RC : & E = & E :: V2 ( 4 ) ;
35- let e = RC ;
36- let x = match e { E :: V1 ( x) => x, E :: V2 ( x) => x } ;
64+
65+ // CHECK: [[t:_.*]] = const {alloc2: &&E};
66+ // CHECK: [[e2]] = (*[[t]]);
67+ let e2 = RC ;
68+
69+ // CHECK: switchInt({{move _.*}}) -> {{.*}}
70+ // FIXME: add checks for x2. Currently, their MIRs are not symmetric in the two
71+ // switch branches.
72+ // One is `_9 = &(*_12) and another is `_9 = _11`. It is different from what we can
73+ // get by printing MIR directly. It is better to check if there are any bugs in the
74+ // MIR passes around this stage.
75+ let x2 = match e2 { E :: V1 ( x21) => x21, E :: V2 ( x22) => x22 } ;
3776}
3877
3978#[ rustc_layout_scalar_valid_range_start( 1 ) ]
4079#[ rustc_nonnull_optimization_guaranteed]
4180struct NonZeroUsize ( usize ) ;
4281
4382// EMIT_MIR enum.mutate_discriminant.DataflowConstProp.diff
83+
84+ // CHECK-LABEL: fn mutate_discriminant(
4485#[ custom_mir( dialect = "runtime" , phase = "post-cleanup" ) ]
4586fn mutate_discriminant ( ) -> u8 {
4687 mir ! (
@@ -50,7 +91,11 @@ fn mutate_discriminant() -> u8 {
5091 // This assignment overwrites the niche in which the discriminant is stored.
5192 place!( Field ( Field ( Variant ( x, 1 ) , 0 ) , 0 ) ) = 0_usize ;
5293 // So we cannot know the value of this discriminant.
94+
95+ // CHECK: [[a:_.*]] = discriminant({{_.*}});
5396 let a = Discriminant ( x) ;
97+
98+ // CHECK: switchInt([[a]]) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
5499 match a {
55100 0 => bb1,
56101 _ => bad,
@@ -68,18 +113,33 @@ fn mutate_discriminant() -> u8 {
68113}
69114
70115// EMIT_MIR enum.multiple.DataflowConstProp.diff
116+ // CHECK-LABEL: fn multiple(
71117fn multiple ( x : bool , i : u8 ) {
118+ // CHECK: debug x => [[x:_.*]];
119+ // CHECK: debug e => [[e:_.*]];
120+ // CHECK: debug x2 => [[x2:_.*]];
121+ // CHECK: debug y => [[y:_.*]];
72122 let e = if x {
123+ // CHECK: [[e]] = Option::<u8>::Some(move {{_.*}});
73124 Some ( i)
74125 } else {
126+ // CHECK: [[e]] = Option::<u8>::None;
75127 None
76128 } ;
77129 // The dataflow state must have:
78130 // discriminant(e) => Top
79131 // (e as Some).0 => Top
80- let x = match e { Some ( i) => i, None => 0 } ;
81- // Therefore, `x` should be `Top` here, and no replacement shall happen.
82- let y = x;
132+ // CHECK: [[x2]] = const 0_u8;
133+ // CHECK: [[some:_.*]] = (({{_.*}} as Some).0: u8)
134+ // CHECK: [[x2]] = [[some]];
135+ let x2 = match e { Some ( i) => i, None => 0 } ;
136+
137+ // Therefore, `x2` should be `Top` here, and no replacement shall happen.
138+
139+ // CHECK-NOT: [[y]] = const
140+ // CHECK: [[y]] = [[x2]];
141+ // CHECK-NOT: [[y]] = const
142+ let y = x2;
83143}
84144
85145fn main ( ) {
0 commit comments