diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs index 3d420f930076d..8f0cc489a5bb7 100644 --- a/tests/mir-opt/dataflow-const-prop/array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/array_index.rs @@ -1,9 +1,21 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR array_index.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main() -> () { fn main() { + // CHECK: let mut [[array_lit:_.*]]: [u32; 4]; + // CHECK: debug x => [[x:_.*]]; + + // CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ + // CHECK: {{_.*}} = const 4_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true + // CHECK: [[x]] = [[array_lit]][2 of 3]; let x: u32 = [0, 1, 2, 3][2]; } diff --git a/tests/mir-opt/dataflow-const-prop/boolean_identities.rs b/tests/mir-opt/dataflow-const-prop/boolean_identities.rs index 2605c7019e6f4..c9be1d65b0302 100644 --- a/tests/mir-opt/dataflow-const-prop/boolean_identities.rs +++ b/tests/mir-opt/dataflow-const-prop/boolean_identities.rs @@ -1,11 +1,18 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR boolean_identities.test.DataflowConstProp.diff + +// CHECK-LABEL: fn test( pub fn test(x: bool, y: bool) -> bool { + // CHECK-NOT: BitAnd( + // CHECK-NOT: BitOr( (y | true) & (x & false) + // CHECK: _0 = const false; + // CHECK-NOT: BitAnd( + // CHECK-NOT: BitOr( } +// CHECK-LABEL: fn main( fn main() { test(true, false); } diff --git a/tests/mir-opt/dataflow-const-prop/cast.rs b/tests/mir-opt/dataflow-const-prop/cast.rs index c87872609dcf7..298ff49803936 100644 --- a/tests/mir-opt/dataflow-const-prop/cast.rs +++ b/tests/mir-opt/dataflow-const-prop/cast.rs @@ -1,8 +1,14 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR cast.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + + // CHECK: [[a]] = const 257_i32; let a = 257; + // CHECK: [[b]] = const 2_u8; let b = a as u8 + 1; } diff --git a/tests/mir-opt/dataflow-const-prop/checked.rs b/tests/mir-opt/dataflow-const-prop/checked.rs index f7fac8890a057..30b0afa8334dd 100644 --- a/tests/mir-opt/dataflow-const-prop/checked.rs +++ b/tests/mir-opt/dataflow-const-prop/checked.rs @@ -1,15 +1,32 @@ -// skip-filecheck // unit-test: DataflowConstProp // compile-flags: -Coverflow-checks=on // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR checked.main.DataflowConstProp.diff #[allow(arithmetic_overflow)] + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: debug c => [[c:_.*]]; + // CHECK: debug d => [[d:_.*]]; + // CHECK: debug e => [[e:_.*]]; + + // CHECK: [[a]] = const 1_i32; let a = 1; + + // CHECK: [[b]] = const 2_i32; let b = 2; + + // CHECK: assert(!const false, + // CHECK: [[c]] = const 3_i32; let c = a + b; + // CHECK: [[d]] = const _; let d = i32::MAX; + + // CHECK: assert(!const true, + // CHECK: [[e]] = const i32::MIN; let e = d + 1; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs index 8006bd510e150..fb708e5084bb9 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs @@ -1,18 +1,29 @@ -// skip-filecheck // unit-test: DataflowConstProp // compile-flags: -Zmir-enable-passes=+GVN,+Inline // ignore-debug assertions change the output MIR // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR_FOR_EACH_PANIC_STRATEGY +// This test is to check ICE in issue [#115789](https://github.com/rust-lang/rust/issues/115789). + struct A { foo: Box<[bool]>, } // EMIT_MIR default_boxed_slice.main.GVN.diff // EMIT_MIR default_boxed_slice.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { // ConstProp will create a constant of type `Box<[bool]>`. + // FIXME: it is not yet a constant. + // Verify that `DataflowConstProp` does not ICE trying to dereference it directly. + + // CHECK: debug a => [[a:_.*]]; + // We may check other inlined functions as well... + + // CHECK: {{_.*}} = Box::<[bool]>( + // FIXME: should be `{{_.*}} = const Box::<[bool]>` let a: A = A { foo: Box::default() }; } diff --git a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff index 07ac5b72e244c..f50a763ef9a05 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff @@ -14,10 +14,10 @@ debug x => _2; } scope 3 { - debug x => _4; + debug x1 => _4; } scope 4 { - debug x => _5; + debug x2 => _5; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff index 07ac5b72e244c..f50a763ef9a05 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff @@ -14,10 +14,10 @@ debug x => _2; } scope 3 { - debug x => _4; + debug x1 => _4; } scope 4 { - debug x => _5; + debug x2 => _5; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff index 775325c4d0626..6bf702b856815 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff @@ -14,7 +14,7 @@ let _6: u8; let _8: u8; scope 2 { - debug x => _6; + debug x2 => _6; let _9: u8; scope 4 { debug y => _9; diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff index 775325c4d0626..6bf702b856815 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff @@ -14,7 +14,7 @@ let _6: u8; let _8: u8; scope 2 { - debug x => _6; + debug x2 => _6; let _9: u8; scope 4 { debug y => _9; diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index e35c0e6e85bed..7ad64d05be434 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH @@ -13,27 +12,67 @@ enum E { } // EMIT_MIR enum.simple.DataflowConstProp.diff + +// CHECK-LABEL: fn simple( fn simple() { + // CHECK: debug e => [[e:_.*]]; + // CHECK: debug x => [[x:_.*]]; + // CHECK: [[e]] = const E::V1(0_i32); let e = E::V1(0); - let x = match e { E::V1(x) => x, E::V2(x) => x }; + + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: [[target_bb]]: { + // CHECK: [[x]] = const 0_i32; + let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; } // EMIT_MIR enum.constant.DataflowConstProp.diff + +// CHECK-LABEL: fn constant( fn constant() { + // CHECK: debug e => [[e:_.*]]; + // CHECK: debug x => [[x:_.*]]; const C: E = E::V1(0); + + // CHECK: [[e]] = const _; let e = C; - let x = match e { E::V1(x) => x, E::V2(x) => x }; + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: [[target_bb]]: { + // CHECK: [[x]] = const 0_i32; + let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 }; } // EMIT_MIR enum.statics.DataflowConstProp.diff + +// CHECK-LABEL: fn statics( fn statics() { + // CHECK: debug e1 => [[e1:_.*]]; + // CHECK: debug x1 => [[x1:_.*]]; + // CHECK: debug e2 => [[e2:_.*]]; + // CHECK: debug x2 => [[x2:_.*]]; + static C: E = E::V1(0); - let e = C; - let x = match e { E::V1(x) => x, E::V2(x) => x }; + + // CHECK: [[e1]] = const E::V1(0_i32); + let e1 = C; + // CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2]; + // CHECK: [[target_bb]]: { + // CHECK: [[x1]] = const 0_i32; + let x1 = match e1 { E::V1(x11) => x11, E::V2(x12) => x12 }; static RC: &E = &E::V2(4); - let e = RC; - let x = match e { E::V1(x) => x, E::V2(x) => x }; + + // CHECK: [[t:_.*]] = const {alloc2: &&E}; + // CHECK: [[e2]] = (*[[t]]); + let e2 = RC; + + // CHECK: switchInt({{move _.*}}) -> {{.*}} + // FIXME: add checks for x2. Currently, their MIRs are not symmetric in the two + // switch branches. + // One is `_9 = &(*_12) and another is `_9 = _11`. It is different from what we can + // get by printing MIR directly. It is better to check if there are any bugs in the + // MIR passes around this stage. + let x2 = match e2 { E::V1(x21) => x21, E::V2(x22) => x22 }; } #[rustc_layout_scalar_valid_range_start(1)] @@ -41,6 +80,8 @@ fn statics() { struct NonZeroUsize(usize); // EMIT_MIR enum.mutate_discriminant.DataflowConstProp.diff + +// CHECK-LABEL: fn mutate_discriminant( #[custom_mir(dialect = "runtime", phase = "post-cleanup")] fn mutate_discriminant() -> u8 { mir!( @@ -50,7 +91,11 @@ fn mutate_discriminant() -> u8 { // This assignment overwrites the niche in which the discriminant is stored. place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize; // So we cannot know the value of this discriminant. + + // CHECK: [[a:_.*]] = discriminant({{_.*}}); let a = Discriminant(x); + + // CHECK: switchInt([[a]]) -> [0: {{bb.*}}, otherwise: {{bb.*}}]; match a { 0 => bb1, _ => bad, @@ -68,18 +113,33 @@ fn mutate_discriminant() -> u8 { } // EMIT_MIR enum.multiple.DataflowConstProp.diff +// CHECK-LABEL: fn multiple( fn multiple(x: bool, i: u8) { + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug e => [[e:_.*]]; + // CHECK: debug x2 => [[x2:_.*]]; + // CHECK: debug y => [[y:_.*]]; let e = if x { + // CHECK: [[e]] = Option::::Some(move {{_.*}}); Some(i) } else { + // CHECK: [[e]] = Option::::None; None }; // The dataflow state must have: // discriminant(e) => Top // (e as Some).0 => Top - let x = match e { Some(i) => i, None => 0 }; - // Therefore, `x` should be `Top` here, and no replacement shall happen. - let y = x; + // CHECK: [[x2]] = const 0_u8; + // CHECK: [[some:_.*]] = (({{_.*}} as Some).0: u8) + // CHECK: [[x2]] = [[some]]; + let x2 = match e { Some(i) => i, None => 0 }; + + // Therefore, `x2` should be `Top` here, and no replacement shall happen. + + // CHECK-NOT: [[y]] = const + // CHECK: [[y]] = [[x2]]; + // CHECK-NOT: [[y]] = const + let y = x2; } fn main() { diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff index 798b0c041b4ec..b31f98460e45b 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff @@ -14,10 +14,10 @@ debug x => _2; } scope 3 { - debug x => _4; + debug x1 => _4; } scope 4 { - debug x => _5; + debug x2 => _5; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff index 798b0c041b4ec..b31f98460e45b 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff @@ -14,10 +14,10 @@ debug x => _2; } scope 3 { - debug x => _4; + debug x1 => _4; } scope 4 { - debug x => _5; + debug x2 => _5; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff index 053981abea3ec..44e8d39cca333 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff @@ -9,34 +9,34 @@ let mut _8: &&E; let mut _10: isize; scope 1 { - debug e => _1; + debug e1 => _1; let _3: i32; let _5: i32; let _6: i32; scope 2 { - debug x => _3; + debug x1 => _3; let _7: &E; scope 5 { - debug e => _7; + debug e2 => _7; let _9: &i32; let _11: &i32; let _12: &i32; scope 6 { - debug x => _9; + debug x2 => _9; } scope 7 { - debug x => _11; + debug x21 => _11; } scope 8 { - debug x => _12; + debug x22 => _12; } } } scope 3 { - debug x => _5; + debug x11 => _5; } scope 4 { - debug x => _6; + debug x12 => _6; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff index d862bd93ff577..ac4ca086d0fed 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff @@ -9,34 +9,34 @@ let mut _8: &&E; let mut _10: isize; scope 1 { - debug e => _1; + debug e1 => _1; let _3: i32; let _5: i32; let _6: i32; scope 2 { - debug x => _3; + debug x1 => _3; let _7: &E; scope 5 { - debug e => _7; + debug e2 => _7; let _9: &i32; let _11: &i32; let _12: &i32; scope 6 { - debug x => _9; + debug x2 => _9; } scope 7 { - debug x => _11; + debug x21 => _11; } scope 8 { - debug x => _12; + debug x22 => _12; } } } scope 3 { - debug x => _5; + debug x11 => _5; } scope 4 { - debug x => _6; + debug x12 => _6; } } diff --git a/tests/mir-opt/dataflow-const-prop/if.rs b/tests/mir-opt/dataflow-const-prop/if.rs index 72aabbccf56c8..3400068baba2a 100644 --- a/tests/mir-opt/dataflow-const-prop/if.rs +++ b/tests/mir-opt/dataflow-const-prop/if.rs @@ -1,12 +1,26 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR if.main.DataflowConstProp.diff +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug b => [[b:_.*]]; + // CHECK: debug c => [[c:_.*]]; + // CHECK: debug d => [[d:_.*]]; + // CHECK: debug e => [[e:_.*]]; + let a = 1; + + // CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}]; + // CHECK: [[b]] = const 2_i32; let b = if a == 1 { 2 } else { 3 }; + + // CHECK: [[c]] = const 3_i32; let c = b + 1; + // CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}]; + // CHECK: [[d]] = const 1_i32; let d = if a == 1 { a } else { a + 1 }; + + // CHECK: [[e]] = const 2_i32; let e = d + 1; } diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs index 664cbcb2c259f..b0acc31e0dbcc 100644 --- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs @@ -1,11 +1,14 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp // compile-flags: -Zmir-enable-passes=+Inline // EMIT_MIR inherit_overflow.main.DataflowConstProp.diff +// CHECK-LABEL: fn main( fn main() { // After inlining, this will contain a `CheckedBinaryOp`. // Propagating the overflow is ok as codegen will just skip emitting the panic. + + // CHECK: {{_.*}} = const (0_u8, true); + // CHECK: assert(!const true, let _ = ::add(255, 1); } diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.rs b/tests/mir-opt/dataflow-const-prop/issue_81605.rs index 7c5eceb8a2b68..f13c364279d41 100644 --- a/tests/mir-opt/dataflow-const-prop/issue_81605.rs +++ b/tests/mir-opt/dataflow-const-prop/issue_81605.rs @@ -1,9 +1,18 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR issue_81605.f.DataflowConstProp.diff + +// Plese find the original issue [here](https://github.com/rust-lang/rust/issues/81605). +// This test program comes directly from the issue. Prior to this issue, +// the compiler cannot simplify the return value of `f` into 2. This was +// solved by adding a new MIR constant propagation based on dataflow +// analysis in [#101168](https://github.com/rust-lang/rust/pull/101168). + +// CHECK-LABEL: fn f( fn f() -> usize { + // CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}]; 1 + if true { 1 } else { 2 } + // CHECK: _0 = const 2_usize; } fn main() { diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.rs b/tests/mir-opt/dataflow-const-prop/large_array_index.rs index d611a54ba71a2..62be2c3824fa5 100644 --- a/tests/mir-opt/dataflow-const-prop/large_array_index.rs +++ b/tests/mir-opt/dataflow-const-prop/large_array_index.rs @@ -1,10 +1,18 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR large_array_index.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { // check that we don't propagate this, because it's too large + + // CHECK: debug x => [[x:_.*]]; + // CHECK: [[array_lit:_.*]] = [const 0_u8; 5000]; + // CHECK: {{_.*}} = const 5000_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true + // CHECK: [[x]] = [[array_lit]][2 of 3]; let x: u8 = [0_u8; 5000][2]; } diff --git a/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs b/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs index 16a45c8e9fb59..be8ce7310564c 100644 --- a/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs +++ b/tests/mir-opt/dataflow-const-prop/mult_by_zero.rs @@ -1,9 +1,10 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR mult_by_zero.test.DataflowConstProp.diff +// CHECK-LABEL: fn test( fn test(x : i32) -> i32 { x * 0 + // CHECK: _0 = const 0_i32; } fn main() { diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.rs b/tests/mir-opt/dataflow-const-prop/offset_of.rs index c1be691025805..ed8e8fcec16e6 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.rs +++ b/tests/mir-opt/dataflow-const-prop/offset_of.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_PANIC_STRATEGY @@ -29,18 +28,46 @@ struct Delta { } // EMIT_MIR offset_of.concrete.DataflowConstProp.diff + +// CHECK-LABEL: fn concrete( fn concrete() { + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug y => [[y:_.*]]; + // CHECK: debug z0 => [[z0:_.*]]; + // CHECK: debug z1 => [[z1:_.*]]; + + // CHECK: [[x]] = must_use::(const 4_usize) -> {{.*}} let x = offset_of!(Alpha, x); + + // CHECK: [[y]] = must_use::(const 0_usize) -> {{.*}} let y = offset_of!(Alpha, y); + + // CHECK: [[z0]] = must_use::(const 2_usize) -> {{.*}} let z0 = offset_of!(Alpha, z.0); + + // CHECK: [[z1]] = must_use::(const 3_usize) -> {{.*}} let z1 = offset_of!(Alpha, z.1); } // EMIT_MIR offset_of.generic.DataflowConstProp.diff + +// CHECK-LABEL: fn generic( fn generic() { + // CHECK: debug gx => [[gx:_.*]]; + // CHECK: debug gy => [[gy:_.*]]; + // CHECK: debug dx => [[dx:_.*]]; + // CHECK: debug dy => [[dy:_.*]]; + + // CHECK: [[gx]] = must_use::(move {{_.*}}) -> {{.*}} let gx = offset_of!(Gamma, x); + + // CHECK: [[gy]] = must_use::(move {{_.*}}) -> {{.*}} let gy = offset_of!(Gamma, y); + + // CHECK: [[dx]] = must_use::(const 0_usize) -> {{.*}} let dx = offset_of!(Delta, x); + + // CHECK: [[dy]] = must_use::(const 2_usize) -> {{.*}} let dy = offset_of!(Delta, y); } diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs index 2851c0590ad5f..7bf2b18407854 100644 --- a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp @@ -9,11 +8,23 @@ fn escape(x: &T) {} fn some_function() {} // EMIT_MIR ref_without_sb.main.DataflowConstProp.diff +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + let mut a = 0; + + // CHECK: {{_.*}} = escape::(move {{_.*}}) -> {{.*}} escape(&a); a = 1; + + // CHECK: {{_.*}} = some_function() -> {{.*}} some_function(); // This should currently not be propagated. + + // CHECK-NOT: [[b]] = const + // CHECK: [[b]] = [[a]]; + // CHECK-NOT: [[b]] = const let b = a; } diff --git a/tests/mir-opt/dataflow-const-prop/repeat.rs b/tests/mir-opt/dataflow-const-prop/repeat.rs index b824481948116..daa8dbaf07655 100644 --- a/tests/mir-opt/dataflow-const-prop/repeat.rs +++ b/tests/mir-opt/dataflow-const-prop/repeat.rs @@ -1,9 +1,21 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR repeat.main.DataflowConstProp.diff +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug x => [[x:_.*]]; + + // CHECK: [[array_lit:_.*]] = [const 42_u32; 8]; + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK: {{_.*}} = const 8_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true + + // CHECK-NOT: [[t:_.*]] = [[array_lit]][_ + // CHECK: [[t:_.*]] = [[array_lit]][2 of 3]; + // CHECK: [[x]] = Add(move [[t]], const 0_u32); let x: u32 = [42; 8][2] + 0; } diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs index 8cbed6fbb624d..39a2b357193ad 100644 --- a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs +++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // The struct has scalar ABI, but is not a scalar type. @@ -7,7 +6,15 @@ struct I32(i32); // EMIT_MIR repr_transparent.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug x => [[x:_.*]]; + // CHECK: debug y => [[y:_.*]]; + + // CHECK: [[x]] = const I32(0_i32); let x = I32(0); + + // CHECK: [[y]] = const I32(0_i32); let y = I32(x.0 + x.0); } diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.rs b/tests/mir-opt/dataflow-const-prop/self_assign.rs index c5866c4a9fd98..a5b232131286f 100644 --- a/tests/mir-opt/dataflow-const-prop/self_assign.rs +++ b/tests/mir-opt/dataflow-const-prop/self_assign.rs @@ -1,13 +1,26 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR self_assign.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + let mut a = 0; + + // CHECK: [[a]] = Add(move {{_.*}}, const 1_i32); a = a + 1; + + // CHECK: [[a]] = move {{_.*}}; a = a; + // CHECK: [[b]] = &[[a]]; let mut b = &a; + + // CHECK: [[b]] = move {{_.*}}; b = b; + + // CHECK: [[a]] = move {{_.*}}; a = *b; } diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs index cfe1458e44be7..7bfbda7a96c61 100644 --- a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs +++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs @@ -1,9 +1,15 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR self_assign_add.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug a => [[a:_.*]]; let mut a = 0; + + // CHECK: [[a]] = const 1_i32; a += 1; + + // CHECK: [[a]] = const 2_i32; a += 1; } diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs index 68aff528695d5..9c610aabe821a 100644 --- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // This attempts to modify `x.1` via a pointer derived from `addr_of_mut!(x.0)`. // According to Miri, that is UB. However, T-opsem has not finalized that @@ -10,11 +9,17 @@ // unit-test: DataflowConstProp // EMIT_MIR sibling_ptr.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug x1 => [[x1:_.*]]; + let mut x: (u8, u8) = (0, 0); unsafe { let p = std::ptr::addr_of_mut!(x.0); *p.add(1) = 1; } + + // CHECK: [[x1]] = ({{_.*}}.1: u8); let x1 = x.1; // should not be propagated } diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.rs b/tests/mir-opt/dataflow-const-prop/slice_len.rs index 86266ef5d4e60..65c87580330fc 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.rs +++ b/tests/mir-opt/dataflow-const-prop/slice_len.rs @@ -1,13 +1,34 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp // compile-flags: -Zmir-enable-passes=+InstSimplify // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR slice_len.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug local => [[local:_.*]]; + // CHECK: debug constant => [[constant:_.*]]; + + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ + // CHECK: {{_.*}} = const 3_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true, + + // CHECK: [[local]] = (*{{_.*}})[1 of 2]; let local = (&[1u32, 2, 3] as &[u32])[1]; + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ const SLICE: &[u32] = &[1, 2, 3]; + // CHECK: {{_.*}} = const 3_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true, + + // CHECK-NOT: [[constant]] = (*{{_.*}})[_ + // CHECK: [[constant]] = (*{{_.*}})[1 of 2]; let constant = SLICE[1]; } diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff index 0f461f515fdd0..c486281d6f8d7 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff @@ -37,16 +37,16 @@ let _8: std::option::Option; let _9: &[f32]; scope 4 { - debug a => _7; - debug b => _8; - debug c => _9; + debug a1 => _7; + debug b1 => _8; + debug c1 => _9; let _11: f32; let _12: std::option::Option; let _13: &[f32]; scope 5 { - debug a => _11; - debug b => _12; - debug c => _13; + debug a2 => _11; + debug b2 => _12; + debug c2 => _13; let _15: SmallStruct; scope 6 { debug ss => _15; @@ -54,16 +54,16 @@ let _20: std::option::Option; let _21: &[f32]; scope 7 { - debug a => _19; - debug b => _20; - debug c => _21; + debug a3 => _19; + debug b3 => _20; + debug c3 => _21; let _23: f32; let _24: std::option::Option; let _25: &[f32]; scope 8 { - debug a => _23; - debug b => _24; - debug c => _25; + debug a4 => _23; + debug b4 => _24; + debug c4 => _25; let _27: BigStruct; scope 9 { debug bs => _27; diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff index 3c40ec8bfb450..7ea53d157334d 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff @@ -37,16 +37,16 @@ let _8: std::option::Option; let _9: &[f32]; scope 4 { - debug a => _7; - debug b => _8; - debug c => _9; + debug a1 => _7; + debug b1 => _8; + debug c1 => _9; let _11: f32; let _12: std::option::Option; let _13: &[f32]; scope 5 { - debug a => _11; - debug b => _12; - debug c => _13; + debug a2 => _11; + debug b2 => _12; + debug c2 => _13; let _15: SmallStruct; scope 6 { debug ss => _15; @@ -54,16 +54,16 @@ let _20: std::option::Option; let _21: &[f32]; scope 7 { - debug a => _19; - debug b => _20; - debug c => _21; + debug a3 => _19; + debug b3 => _20; + debug c3 => _21; let _23: f32; let _24: std::option::Option; let _25: &[f32]; scope 8 { - debug a => _23; - debug b => _24; - debug c => _25; + debug a4 => _23; + debug b4 => _24; + debug c4 => _25; let _27: BigStruct; scope 9 { debug bs => _27; diff --git a/tests/mir-opt/dataflow-const-prop/struct.rs b/tests/mir-opt/dataflow-const-prop/struct.rs index 043981a295484..a7e0f6a987d5a 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.rs +++ b/tests/mir-opt/dataflow-const-prop/struct.rs @@ -1,4 +1,3 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH @@ -12,27 +11,69 @@ struct SmallStruct(f32, Option, &'static [f32]); struct BigStruct(f32, Option, &'static [f32]); // EMIT_MIR struct.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug s => [[s:_.*]]; + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: debug a1 => [[a1:_.*]]; + // CHECK: debug b1 => [[b1:_.*]]; + // CHECK: debug c1 => [[c1:_.*]]; + // CHECK: debug a2 => [[a2:_.*]]; + // CHECK: debug b2 => [[b2:_.*]]; + // CHECK: debug c2 => [[c2:_.*]]; + // CHECK: debug ss => [[ss:_.*]]; + // CHECK: debug a3 => [[a3:_.*]]; + // CHECK: debug b3 => [[b3:_.*]]; + // CHECK: debug c3 => [[c3:_.*]]; + // CHECK: debug a4 => [[a4:_.*]]; + // CHECK: debug b4 => [[b4:_.*]]; + // CHECK: debug c4 => [[c4:_.*]]; + // CHECK: debug bs => [[bs:_.*]]; + + // CHECK: [[s]] = const S(1_i32); let mut s = S(1); + + // CHECK: [[a]] = const 3_i32; let a = s.0 + 2; s.0 = 3; + + // CHECK: [[b]] = const 6_i32; let b = a + s.0; const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]); - let SmallStruct(a, b, c) = SMALL_VAL; + + // CHECK: [[a1]] = const 4f32; + // CHECK: [[b1]] = const Option::::Some(S(1_i32)); + // CHECK: [[c1]] = ({{_.*}}.2: &[f32]); + let SmallStruct(a1, b1, c1) = SMALL_VAL; static SMALL_STAT: &SmallStruct = &SmallStruct(9., None, &[13.]); - let SmallStruct(a, b, c) = *SMALL_STAT; - let ss = SmallStruct(a, b, c); + // CHECK: [[a2]] = const 9f32; + // CHECK: [[b2]] = ((*{{_.*}}).1: std::option::Option); + // CHECK: [[c2]] = ((*{{_.*}}).2: &[f32]); + let SmallStruct(a2, b2, c2) = *SMALL_STAT; + + // CHECK: [[ss]] = SmallStruct(const 9f32, move {{_.*}}, move {{_.*}}); + let ss = SmallStruct(a2, b2, c2); const BIG_VAL: BigStruct = BigStruct(25., None, &[]); - let BigStruct(a, b, c) = BIG_VAL; + + // CHECK: [[a3]] = const 25f32; + // CHECK: [[b3]] = ({{_.*}}.1: std::option::Option); + // CHECK: [[c3]] = ({{_.*}}.2: &[f32]); + let BigStruct(a3, b3, c3) = BIG_VAL; static BIG_STAT: &BigStruct = &BigStruct(82., Some(S(35)), &[45., 72.]); - let BigStruct(a, b, c) = *BIG_STAT; + // CHECK: [[a4]] = const 82f32; + // CHECK: [[b4]] = const Option::::Some(S(35_i32)); + // CHECK: [[c4]] = ((*{{_.*}}).2: &[f32]); + let BigStruct(a4, b4, c4) = *BIG_STAT; // We arbitrarily limit the size of synthetized values to 4 pointers. // `BigStruct` can be read, but we will keep a MIR aggregate for this. - let bs = BigStruct(a, b, c); + // CHECK: [[bs]] = BigStruct(const 82f32, const Option::::Some(S(35_i32)), move {{_.*}}); + let bs = BigStruct(a4, b4, c4); } diff --git a/tests/mir-opt/dataflow-const-prop/terminator.rs b/tests/mir-opt/dataflow-const-prop/terminator.rs index 92a42f22c218f..4472861f132db 100644 --- a/tests/mir-opt/dataflow-const-prop/terminator.rs +++ b/tests/mir-opt/dataflow-const-prop/terminator.rs @@ -1,12 +1,14 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // unit-test: DataflowConstProp fn foo(n: i32) {} // EMIT_MIR terminator.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { let a = 1; // Checks that we propagate into terminators. + // CHECK: {{_.*}} = foo(const 2_i32) -> [return: {{bb.*}}, unwind foo(a + 1); } diff --git a/tests/mir-opt/dataflow-const-prop/tuple.rs b/tests/mir-opt/dataflow-const-prop/tuple.rs index bb706eafe8885..563558da04a5d 100644 --- a/tests/mir-opt/dataflow-const-prop/tuple.rs +++ b/tests/mir-opt/dataflow-const-prop/tuple.rs @@ -1,13 +1,27 @@ -// skip-filecheck // unit-test: DataflowConstProp // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR tuple.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( fn main() { + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: debug c => [[c:_.*]]; + // CHECK: debug d => [[d:_.*]]; + + // CHECK: [[a]] = const (1_i32, 2_i32); let mut a = (1, 2); + + // CHECK: [[b]] = const 6_i32; let b = a.0 + a.1 + 3; + + // CHECK: [[a]] = const (2_i32, 3_i32); a = (2, 3); + + // CHECK: [[c]] = const 11_i32; let c = a.0 + a.1 + b; + // CHECK: [[d]] = (const 6_i32, const (2_i32, 3_i32), const 11_i32); let d = (b, a, c); }