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