summaryrefslogtreecommitdiffstats
path: root/src/test/mir-opt/const_prop
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/mir-opt/const_prop
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/mir-opt/const_prop')
-rw-r--r--src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff32
-rw-r--r--src/test/mir-opt/const_prop/aggregate.rs6
-rw-r--r--src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff38
-rw-r--r--src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff38
-rw-r--r--src/test/mir-opt/const_prop/array_index.rs6
-rw-r--r--src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff54
-rw-r--r--src/test/mir-opt/const_prop/bad_op_div_by_zero.rs6
-rw-r--r--src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff54
-rw-r--r--src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs6
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff56
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff56
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs9
-rw-r--r--src/test/mir-opt/const_prop/boolean_identities.rs10
-rw-r--r--src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff33
-rw-r--r--src/test/mir-opt/const_prop/boxes.main.ConstProp.diff67
-rw-r--r--src/test/mir-opt/const_prop/boxes.rs13
-rw-r--r--src/test/mir-opt/const_prop/cast.main.ConstProp.diff28
-rw-r--r--src/test/mir-opt/const_prop/cast.rs7
-rw-r--r--src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff28
-rw-r--r--src/test/mir-opt/const_prop/checked_add.rs6
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff44
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs9
-rw-r--r--src/test/mir-opt/const_prop/control-flow-simplification.rs20
-rw-r--r--src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff34
-rw-r--r--src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir9
-rw-r--r--src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff52
-rw-r--r--src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff52
-rw-r--r--src/test/mir-opt/const_prop/discriminant.rs12
-rw-r--r--src/test/mir-opt/const_prop/indirect.main.ConstProp.diff33
-rw-r--r--src/test/mir-opt/const_prop/indirect.rs6
-rw-r--r--src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff77
-rw-r--r--src/test/mir-opt/const_prop/invalid_constant.rs42
-rw-r--r--src/test/mir-opt/const_prop/issue-66971.rs17
-rw-r--r--src/test/mir-opt/const_prop/issue-67019.rs12
-rw-r--r--src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff33
-rw-r--r--src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff34
-rw-r--r--src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff37
-rw-r--r--src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff37
-rw-r--r--src/test/mir-opt/const_prop/large_array_index.rs7
-rw-r--r--src/test/mir-opt/const_prop/mult_by_zero.rs10
-rw-r--r--src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff18
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff28
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable.rs8
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff30
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate.rs8
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff36
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs9
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff35
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs14
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff48
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_no_prop.rs12
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff53
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs15
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff68
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff68
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir27
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir27
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.rs15
-rw-r--r--src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff48
-rw-r--r--src/test/mir-opt/const_prop/read_immutable_static.rs8
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff27
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff30
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.rs6
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff26
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff30
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.rs6
-rw-r--r--src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff29
-rw-r--r--src/test/mir-opt/const_prop/reify_fn_ptr.rs5
-rw-r--r--src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff43
-rw-r--r--src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff43
-rw-r--r--src/test/mir-opt/const_prop/repeat.rs7
-rw-r--r--src/test/mir-opt/const_prop/return_place.add.ConstProp.diff21
-rw-r--r--src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir10
-rw-r--r--src/test/mir-opt/const_prop/return_place.rs11
-rw-r--r--src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff35
-rw-r--r--src/test/mir-opt/const_prop/scalar_literal_propagation.rs8
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff53
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff53
-rw-r--r--src/test/mir-opt/const_prop/slice_len.rs6
-rw-r--r--src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff34
-rw-r--r--src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff34
-rw-r--r--src/test/mir-opt/const_prop/switch_int.rs11
-rw-r--r--src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff36
-rw-r--r--src/test/mir-opt/const_prop/tuple_literal_propagation.rs9
84 files changed, 2278 insertions, 0 deletions
diff --git a/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff
new file mode 100644
index 000000000..836443bf4
--- /dev/null
+++ b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff
@@ -0,0 +1,32 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/aggregate.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/aggregate.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+ let mut _3: (i32, i32, i32); // in scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/aggregate.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/aggregate.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+ StorageLive(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ Deinit(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.0: i32) = const 0_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.1: i32) = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.2: i32) = const 2_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+- _2 = (_3.1: i32); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+- _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/aggregate.rs:+1:13: +1:28
++ _2 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:24
++ _1 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:28
+ StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+1:27: +1:28
+ StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+1:28: +1:29
+ nop; // scope 0 at $DIR/aggregate.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/aggregate.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/aggregate.rs b/src/test/mir-opt/const_prop/aggregate.rs
new file mode 100644
index 000000000..7a3b26a73
--- /dev/null
+++ b/src/test/mir-opt/const_prop/aggregate.rs
@@ -0,0 +1,6 @@
+// compile-flags: -O
+
+// EMIT_MIR aggregate.main.ConstProp.diff
+fn main() {
+ let x = (0, 1, 2).1 + 0;
+}
diff --git a/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..bb9abdd10
--- /dev/null
+++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.32bit.diff
@@ -0,0 +1,38 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/array_index.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/array_index.rs:+1:9: +1:10
+ let mut _2: [u32; 4]; // in scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ let _3: usize; // in scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ let mut _4: usize; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ let mut _5: bool; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/array_index.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/array_index.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ _3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ }
+
+ bb1: {
+- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
+ StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
+ nop; // scope 0 at $DIR/array_index.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..bb9abdd10
--- /dev/null
+++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.64bit.diff
@@ -0,0 +1,38 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/array_index.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/array_index.rs:+1:9: +1:10
+ let mut _2: [u32; 4]; // in scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ let _3: usize; // in scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ let mut _4: usize; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ let mut _5: bool; // in scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/array_index.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/array_index.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32]; // scope 0 at $DIR/array_index.rs:+1:18: +1:30
+ StorageLive(_3); // scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ _3 = const 2_usize; // scope 0 at $DIR/array_index.rs:+1:31: +1:32
+ _4 = const 4_usize; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- _5 = Lt(_3, _4); // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _5 = const true; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> bb1; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ }
+
+ bb1: {
+- _1 = _2[_3]; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
++ _1 = const 2_u32; // scope 0 at $DIR/array_index.rs:+1:18: +1:33
+ StorageDead(_3); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
+ StorageDead(_2); // scope 0 at $DIR/array_index.rs:+1:33: +1:34
+ nop; // scope 0 at $DIR/array_index.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/array_index.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/array_index.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/array_index.rs b/src/test/mir-opt/const_prop/array_index.rs
new file mode 100644
index 000000000..2c5254b5d
--- /dev/null
+++ b/src/test/mir-opt/const_prop/array_index.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+// EMIT_MIR array_index.main.ConstProp.diff
+fn main() {
+ let x: u32 = [0, 1, 2, 3][2];
+}
diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
new file mode 100644
index 000000000..45134a3fd
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
@@ -0,0 +1,54 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10
+ let mut _3: i32; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+ let mut _4: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ let mut _5: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ let mut _6: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ let mut _7: bool; // in scope 0 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ scope 1 {
+ debug y => _1; // in scope 1 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11
+ scope 2 {
+ debug _z => _2; // in scope 2 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+1:9: +1:10
+ _1 = const 0_i32; // scope 0 at $DIR/bad_op_div_by_zero.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:9: +2:11
+ StorageLive(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+- _3 = _1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+- assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
++ _4 = const true; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ }
+
+ bb1: {
+- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+- assert(!move _7, "attempt to compute `{} / {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _5 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _6 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _7 = const false; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ assert(!const false, "attempt to compute `{} / {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ }
+
+ bb2: {
+- _2 = Div(const 1_i32, move _3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++ _2 = Div(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+ StorageDead(_3); // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
+ nop; // scope 0 at $DIR/bad_op_div_by_zero.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/bad_op_div_by_zero.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs
new file mode 100644
index 000000000..6f39209b9
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR bad_op_div_by_zero.main.ConstProp.diff
+#[allow(unconditional_panic)]
+fn main() {
+ let y = 0;
+ let _z = 1 / y;
+}
diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff
new file mode 100644
index 000000000..221513042
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff
@@ -0,0 +1,54 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10
+ let mut _3: i32; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+ let mut _4: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ let mut _5: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ let mut _6: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ let mut _7: bool; // in scope 0 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ scope 1 {
+ debug y => _1; // in scope 1 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11
+ scope 2 {
+ debug _z => _2; // in scope 2 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10
+ _1 = const 0_i32; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11
+ StorageLive(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+- _3 = _1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+- _4 = Eq(_3, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+- assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _3 = const 0_i32; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
++ _4 = const true; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ }
+
+ bb1: {
+- _5 = Eq(_3, const -1_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+- _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+- _7 = BitAnd(move _5, move _6); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+- assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _5 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _6 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _7 = const false; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ }
+
+ bb2: {
+- _2 = Rem(const 1_i32, move _3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++ _2 = Rem(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+ StorageDead(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+ nop; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs
new file mode 100644
index 000000000..cc16a4a5a
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR bad_op_mod_by_zero.main.ConstProp.diff
+#[allow(unconditional_panic)]
+fn main() {
+ let y = 0;
+ let _z = 1 % y;
+}
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..553488838
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
@@ -0,0 +1,56 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+0:11: +0:11
+ let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35
+ let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ scope 2 {
+ let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ scope 3 {
+ debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ // mir::Constant
+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
+ // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35
+ StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36
+ StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ }
+
+ bb1: {
+ _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26
+ nop; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6
+ StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6
+ StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..553488838
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
@@ -0,0 +1,56 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+0:11: +0:11
+ let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35
+ let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ scope 2 {
+ let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ scope 3 {
+ debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ // mir::Constant
+ // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
+ // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+ StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35
+ StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36
+ StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
+ StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
+ _7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
++ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ }
+
+ bb1: {
+ _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25
+ StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26
+ nop; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6
+ StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6
+ StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs
new file mode 100644
index 000000000..cf22b06d5
--- /dev/null
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR bad_op_unsafe_oob_for_slices.main.ConstProp.diff
+#[allow(unconditional_panic)]
+fn main() {
+ let a: *const [_] = &[1, 2, 3];
+ unsafe {
+ let _b = (*a)[3];
+ }
+}
diff --git a/src/test/mir-opt/const_prop/boolean_identities.rs b/src/test/mir-opt/const_prop/boolean_identities.rs
new file mode 100644
index 000000000..57164e3e7
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boolean_identities.rs
@@ -0,0 +1,10 @@
+// compile-flags: -O -Zmir-opt-level=4
+
+// EMIT_MIR boolean_identities.test.ConstProp.diff
+pub fn test(x: bool, y: bool) -> bool {
+ (y | true) & (x & false)
+}
+
+fn main() {
+ test(true, false);
+}
diff --git a/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff b/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff
new file mode 100644
index 000000000..0de800917
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff
@@ -0,0 +1,33 @@
+- // MIR for `test` before ConstProp
++ // MIR for `test` after ConstProp
+
+ fn test(_1: bool, _2: bool) -> bool {
+ debug x => _1; // in scope 0 at $DIR/boolean_identities.rs:+0:13: +0:14
+ debug y => _2; // in scope 0 at $DIR/boolean_identities.rs:+0:22: +0:23
+ let mut _0: bool; // return place in scope 0 at $DIR/boolean_identities.rs:+0:34: +0:38
+ let mut _3: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
+ let mut _4: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7
+ let mut _5: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
+ let mut _6: bool; // in scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20
+
+ bb0: {
+ StorageLive(_3); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
+ StorageLive(_4); // scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7
+ _4 = _2; // scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7
+- _3 = BitOr(move _4, const true); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
++ _3 = const true; // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
+ StorageDead(_4); // scope 0 at $DIR/boolean_identities.rs:+1:14: +1:15
+ StorageLive(_5); // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
+ StorageLive(_6); // scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20
+ _6 = _1; // scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20
+- _5 = BitAnd(move _6, const false); // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
++ _5 = const false; // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
+ StorageDead(_6); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
+- _0 = BitAnd(move _3, move _5); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:29
++ _0 = const false; // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:29
+ StorageDead(_5); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
+ StorageDead(_3); // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
+ return; // scope 0 at $DIR/boolean_identities.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
new file mode 100644
index 000000000..f2d4bee1b
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
@@ -0,0 +1,67 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/boxes.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/boxes.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ let mut _3: std::boxed::Box<i32>; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _4: usize; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _5: usize; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _6: *mut u8; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _7: std::boxed::Box<i32>; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _8: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _9: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _10: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ let mut _11: *const i32; // in scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/boxes.rs:+1:9: +1:10
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/boxes.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ StorageLive(_3); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+- _4 = SizeOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+- _5 = AlignOf(i32); // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
++ _4 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
++ _5 = const 4_usize; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
++ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> bb1; // scope 2 at $DIR/boxes.rs:+1:14: +1:22
+ // mir::Constant
+ // + span: $DIR/boxes.rs:12:14: 12:22
+ // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_7); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ _7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ StorageLive(_8); // scope 0 at $DIR/boxes.rs:+1:19: +1:21
+ _8 = (((_7.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:19: +1:21
+ (*_8) = const 42_i32; // scope 0 at $DIR/boxes.rs:+1:19: +1:21
+ StorageDead(_8); // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ _3 = move _7; // scope 0 at $DIR/boxes.rs:+1:14: +1:22
+ StorageDead(_7); // scope 0 at $DIR/boxes.rs:+1:21: +1:22
+ StorageLive(_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ _9 = (((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ _2 = (*_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:22
+ StorageDead(_9); // scope 0 at $DIR/boxes.rs:+1:13: +1:26
+ _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/boxes.rs:+1:13: +1:26
+ StorageDead(_2); // scope 0 at $DIR/boxes.rs:+1:25: +1:26
+ drop(_3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/boxes.rs:+1:26: +1:27
+ }
+
+ bb2: {
+ StorageDead(_3); // scope 0 at $DIR/boxes.rs:+1:26: +1:27
+ nop; // scope 0 at $DIR/boxes.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/boxes.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/boxes.rs:+2:2: +2:2
+ }
+
+ bb3 (cleanup): {
+ resume; // scope 0 at $DIR/boxes.rs:+0:1: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/boxes.rs b/src/test/mir-opt/const_prop/boxes.rs
new file mode 100644
index 000000000..fea666a44
--- /dev/null
+++ b/src/test/mir-opt/const_prop/boxes.rs
@@ -0,0 +1,13 @@
+// compile-flags: -O
+// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32
+// ignore-wasm64
+
+#![feature(box_syntax)]
+
+// Note: this test verifies that we, in fact, do not const prop `box`
+
+// EMIT_MIR boxes.main.ConstProp.diff
+fn main() {
+ let x = *(box 42) + 0;
+}
diff --git a/src/test/mir-opt/const_prop/cast.main.ConstProp.diff b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff
new file mode 100644
index 000000000..5698a612f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff
@@ -0,0 +1,28 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/cast.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/cast.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/cast.rs:+1:9: +1:10
+ let _2: u8; // in scope 1 at $DIR/cast.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/cast.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/cast.rs:+1:9: +1:10
+- _1 = const 42_u8 as u32 (Misc); // scope 0 at $DIR/cast.rs:+1:13: +1:24
++ _1 = const 42_u32; // scope 0 at $DIR/cast.rs:+1:13: +1:24
+ StorageLive(_2); // scope 1 at $DIR/cast.rs:+3:9: +3:10
+- _2 = const 42_u32 as u8 (Misc); // scope 1 at $DIR/cast.rs:+3:13: +3:24
++ _2 = const 42_u8; // scope 1 at $DIR/cast.rs:+3:13: +3:24
+ nop; // scope 0 at $DIR/cast.rs:+0:11: +4:2
+ StorageDead(_2); // scope 1 at $DIR/cast.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/cast.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/cast.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/cast.rs b/src/test/mir-opt/const_prop/cast.rs
new file mode 100644
index 000000000..680cab007
--- /dev/null
+++ b/src/test/mir-opt/const_prop/cast.rs
@@ -0,0 +1,7 @@
+// EMIT_MIR cast.main.ConstProp.diff
+
+fn main() {
+ let x = 42u8 as u32;
+
+ let y = 42u32 as u8;
+}
diff --git a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
new file mode 100644
index 000000000..5e33d0542
--- /dev/null
+++ b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
@@ -0,0 +1,28 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/checked_add.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/checked_add.rs:+1:9: +1:10
+ let mut _2: (u32, bool); // in scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/checked_add.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/checked_add.rs:+1:9: +1:10
+- _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
++ _2 = const (2_u32, false); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+ }
+
+ bb1: {
+- _1 = move (_2.0: u32); // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
++ _1 = const 2_u32; // scope 0 at $DIR/checked_add.rs:+1:18: +1:23
+ nop; // scope 0 at $DIR/checked_add.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/checked_add.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/checked_add.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/checked_add.rs b/src/test/mir-opt/const_prop/checked_add.rs
new file mode 100644
index 000000000..08d59b6fb
--- /dev/null
+++ b/src/test/mir-opt/const_prop/checked_add.rs
@@ -0,0 +1,6 @@
+// compile-flags: -C overflow-checks=on
+
+// EMIT_MIR checked_add.main.ConstProp.diff
+fn main() {
+ let x: u32 = 1 + 1;
+}
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
new file mode 100644
index 000000000..c21b24591
--- /dev/null
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
@@ -0,0 +1,44 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +0:11
+ let _1: usize; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
+ let mut _2: *const i32; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30
+ let _3: &i32; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ let _4: (); // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12
+ let mut _5: usize; // in scope 0 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10
+ StorageLive(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30
+ StorageLive(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ _3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ // mir::Constant
+ // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
+ // + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) }
+ _2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16
+ _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:39
+ StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:38: +2:39
+ StorageDead(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:39: +2:40
+ StorageLive(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12
+ StorageLive(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11
+ _5 = _1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:10: +3:11
+ _4 = read(move _5) -> bb1; // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:5: +3:12
+ // mir::Constant
+ // + span: $DIR/const_prop_fails_gracefully.rs:8:5: 8:9
+ // + literal: Const { ty: fn(usize) {read}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:11: +3:12
+ StorageDead(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:+3:12: +3:13
+ nop; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
new file mode 100644
index 000000000..8bd68527f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
@@ -0,0 +1,9 @@
+#[inline(never)]
+fn read(_: usize) { }
+
+// EMIT_MIR const_prop_fails_gracefully.main.ConstProp.diff
+fn main() {
+ const FOO: &i32 = &1;
+ let x = FOO as *const i32 as usize;
+ read(x);
+}
diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control-flow-simplification.rs
new file mode 100644
index 000000000..aa4ce19f6
--- /dev/null
+++ b/src/test/mir-opt/const_prop/control-flow-simplification.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Zmir-opt-level=1
+
+trait NeedsDrop:Sized{
+ const NEEDS:bool=std::mem::needs_drop::<Self>();
+}
+
+impl<This> NeedsDrop for This{}
+
+// EMIT_MIR control_flow_simplification.hello.ConstProp.diff
+// EMIT_MIR control_flow_simplification.hello.PreCodegen.before.mir
+fn hello<T>(){
+ if <bool>::NEEDS {
+ panic!()
+ }
+}
+
+pub fn main() {
+ hello::<()>();
+ hello::<Vec<()>>();
+}
diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
new file mode 100644
index 000000000..5f4df0d88
--- /dev/null
+++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
@@ -0,0 +1,34 @@
+- // MIR for `hello` before ConstProp
++ // MIR for `hello` after ConstProp
+
+ fn hello() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14
+ let mut _1: bool; // in scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+ let mut _2: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+- _1 = const <bool as NeedsDrop>::NEEDS; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
++ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
++ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ _2 = begin_panic::<&str>(const "explicit panic"); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb2: {
+ nop; // scope 0 at $DIR/control-flow-simplification.rs:+3:6: +3:6
+ StorageDead(_1); // scope 0 at $DIR/control-flow-simplification.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir
new file mode 100644
index 000000000..70f979775
--- /dev/null
+++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir
@@ -0,0 +1,9 @@
+// MIR for `hello` before PreCodegen
+
+fn hello() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14
+
+ bb0: {
+ return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..5b4ecaa80
--- /dev/null
+++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
@@ -0,0 +1,52 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/discriminant.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/discriminant.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ let mut _3: std::option::Option<bool>; // in scope 0 at $DIR/discriminant.rs:+1:34: +1:44
+ let mut _4: isize; // in scope 0 at $DIR/discriminant.rs:+1:21: +1:31
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/discriminant.rs:+1:9: +1:10
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/discriminant.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ StorageLive(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ Deinit(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ discriminant(_3) = 1; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+- _4 = discriminant(_3); // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
++ _4 = const 1_isize; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
++ switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb1: {
+ switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb2: {
+ _2 = const 42_i32; // scope 2 at $DIR/discriminant.rs:+1:47: +1:49
+ goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ }
+
+ bb3: {
+ _2 = const 10_i32; // scope 0 at $DIR/discriminant.rs:+1:59: +1:61
+ goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ }
+
+ bb4: {
+ _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:+1:13: +1:68
+ StorageDead(_2); // scope 0 at $DIR/discriminant.rs:+1:67: +1:68
+ StorageDead(_3); // scope 0 at $DIR/discriminant.rs:+1:68: +1:69
+ nop; // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..5b4ecaa80
--- /dev/null
+++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
@@ -0,0 +1,52 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/discriminant.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/discriminant.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ let mut _3: std::option::Option<bool>; // in scope 0 at $DIR/discriminant.rs:+1:34: +1:44
+ let mut _4: isize; // in scope 0 at $DIR/discriminant.rs:+1:21: +1:31
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/discriminant.rs:+1:9: +1:10
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/discriminant.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ StorageLive(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ Deinit(_3); // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+ discriminant(_3) = 1; // scope 2 at $DIR/discriminant.rs:+1:34: +1:44
+- _4 = discriminant(_3); // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+- switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
++ _4 = const 1_isize; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
++ switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb1: {
+ switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:+1:21: +1:31
+ }
+
+ bb2: {
+ _2 = const 42_i32; // scope 2 at $DIR/discriminant.rs:+1:47: +1:49
+ goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ }
+
+ bb3: {
+ _2 = const 10_i32; // scope 0 at $DIR/discriminant.rs:+1:59: +1:61
+ goto -> bb4; // scope 0 at $DIR/discriminant.rs:+1:13: +1:64
+ }
+
+ bb4: {
+ _1 = Add(move _2, const 0_i32); // scope 0 at $DIR/discriminant.rs:+1:13: +1:68
+ StorageDead(_2); // scope 0 at $DIR/discriminant.rs:+1:67: +1:68
+ StorageDead(_3); // scope 0 at $DIR/discriminant.rs:+1:68: +1:69
+ nop; // scope 0 at $DIR/discriminant.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/discriminant.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/discriminant.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/discriminant.rs b/src/test/mir-opt/const_prop/discriminant.rs
new file mode 100644
index 000000000..67538b3c7
--- /dev/null
+++ b/src/test/mir-opt/const_prop/discriminant.rs
@@ -0,0 +1,12 @@
+// compile-flags: -O
+
+// FIXME(wesleywiser): Ideally, we could const-prop away all of this and just be left with
+// `let x = 42` but that doesn't work because const-prop doesn't support `Operand::Indirect`
+// and `InterpCx::eval_place()` always forces an allocation which creates the `Indirect`.
+// Fixing either of those will allow us to const-prop this away.
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR discriminant.main.ConstProp.diff
+fn main() {
+ let x = (if let Some(true) = Some(true) { 42 } else { 10 }) + 0;
+}
diff --git a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
new file mode 100644
index 000000000..2e1e32545
--- /dev/null
+++ b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
@@ -0,0 +1,33 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/indirect.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/indirect.rs:+1:9: +1:10
+ let mut _2: u8; // in scope 0 at $DIR/indirect.rs:+1:13: +1:25
+ let mut _3: (u8, bool); // in scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/indirect.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/indirect.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/indirect.rs:+1:13: +1:25
+- _2 = const 2_u32 as u8 (Misc); // scope 0 at $DIR/indirect.rs:+1:13: +1:25
+- _3 = CheckedAdd(_2, const 1_u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
++ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:25
++ _3 = const (3_u8, false); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u8, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ }
+
+ bb1: {
+- _1 = move (_3.0: u8); // scope 0 at $DIR/indirect.rs:+1:13: +1:29
++ _1 = const 3_u8; // scope 0 at $DIR/indirect.rs:+1:13: +1:29
+ StorageDead(_2); // scope 0 at $DIR/indirect.rs:+1:28: +1:29
+ nop; // scope 0 at $DIR/indirect.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/indirect.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/indirect.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/indirect.rs b/src/test/mir-opt/const_prop/indirect.rs
new file mode 100644
index 000000000..37217ca81
--- /dev/null
+++ b/src/test/mir-opt/const_prop/indirect.rs
@@ -0,0 +1,6 @@
+// compile-flags: -C overflow-checks=on
+
+// EMIT_MIR indirect.main.ConstProp.diff
+fn main() {
+ let x = (2u32 as u8) + 1;
+}
diff --git a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
new file mode 100644
index 000000000..67a4dc3c0
--- /dev/null
+++ b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
@@ -0,0 +1,77 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/invalid_constant.rs:+0:11: +0:11
+ let _1: char; // in scope 0 at $DIR/invalid_constant.rs:+6:9: +6:22
+ let mut _2: main::InvalidChar; // in scope 0 at $DIR/invalid_constant.rs:+6:34: +6:63
+ let mut _4: E; // in scope 0 at $DIR/invalid_constant.rs:+13:25: +13:59
+ let mut _5: main::InvalidTag; // in scope 0 at $DIR/invalid_constant.rs:+13:34: +13:55
+ let mut _7: Empty; // in scope 0 at $DIR/invalid_constant.rs:+20:35: +20:73
+ let mut _8: main::NoVariants; // in scope 0 at $DIR/invalid_constant.rs:+20:44: +20:65
+ scope 1 {
+ debug _invalid_char => _1; // in scope 1 at $DIR/invalid_constant.rs:+6:9: +6:22
+ let _3: [E; 1]; // in scope 1 at $DIR/invalid_constant.rs:+13:9: +13:21
+ scope 3 {
+ debug _invalid_tag => _3; // in scope 3 at $DIR/invalid_constant.rs:+13:9: +13:21
+ let _6: [Empty; 1]; // in scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31
+ scope 5 {
+ debug _enum_without_variants => _6; // in scope 5 at $DIR/invalid_constant.rs:+20:9: +20:31
+ let _9: main::Str<"���">; // in scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22
+ scope 7 {
+ debug _non_utf8_str => _9; // in scope 7 at $DIR/invalid_constant.rs:+24:9: +24:22
+ }
+ }
+ scope 6 {
+ }
+ }
+ scope 4 {
+ }
+ }
+ scope 2 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/invalid_constant.rs:+6:9: +6:22
+ StorageLive(_2); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63
+ Deinit(_2); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63
+ (_2.0: u32) = const 1114113_u32; // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:63
+- _1 = (_2.1: char); // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:67
++ _1 = const {transmute(0x00110001): char}; // scope 2 at $DIR/invalid_constant.rs:+6:34: +6:67
+ StorageDead(_2); // scope 0 at $DIR/invalid_constant.rs:+6:69: +6:70
+ StorageLive(_3); // scope 1 at $DIR/invalid_constant.rs:+13:9: +13:21
+ StorageLive(_4); // scope 1 at $DIR/invalid_constant.rs:+13:25: +13:59
+ StorageLive(_5); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55
+ Deinit(_5); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55
+ (_5.0: u32) = const 4_u32; // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:55
+- _4 = (_5.1: E); // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:57
+- _3 = [move _4]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60
++ _4 = const Scalar(0x00000004): E; // scope 4 at $DIR/invalid_constant.rs:+13:34: +13:57
++ // mir::Constant
++ // + span: $DIR/invalid_constant.rs:28:34: 28:57
++ // + literal: Const { ty: E, val: Value(Scalar(0x00000004)) }
++ _3 = [const Scalar(0x00000004): E]; // scope 1 at $DIR/invalid_constant.rs:+13:24: +13:60
++ // mir::Constant
++ // + span: $DIR/invalid_constant.rs:28:24: 28:60
++ // + literal: Const { ty: E, val: Value(Scalar(0x00000004)) }
+ StorageDead(_4); // scope 1 at $DIR/invalid_constant.rs:+13:59: +13:60
+ StorageDead(_5); // scope 1 at $DIR/invalid_constant.rs:+13:60: +13:61
+ StorageLive(_6); // scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31
+ StorageLive(_7); // scope 3 at $DIR/invalid_constant.rs:+20:35: +20:73
+ StorageLive(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65
+ Deinit(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65
+ (_8.0: u32) = const 0_u32; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65
+ nop; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:71
+ nop; // scope 3 at $DIR/invalid_constant.rs:+20:34: +20:74
+ StorageDead(_7); // scope 3 at $DIR/invalid_constant.rs:+20:73: +20:74
+ StorageDead(_8); // scope 3 at $DIR/invalid_constant.rs:+20:74: +20:75
+ StorageLive(_9); // scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22
+ nop; // scope 0 at $DIR/invalid_constant.rs:+0:11: +27:2
+ StorageDead(_9); // scope 5 at $DIR/invalid_constant.rs:+27:1: +27:2
+ StorageDead(_6); // scope 3 at $DIR/invalid_constant.rs:+27:1: +27:2
+ StorageDead(_3); // scope 1 at $DIR/invalid_constant.rs:+27:1: +27:2
+ StorageDead(_1); // scope 0 at $DIR/invalid_constant.rs:+27:1: +27:2
+ return; // scope 0 at $DIR/invalid_constant.rs:+27:2: +27:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/invalid_constant.rs b/src/test/mir-opt/const_prop/invalid_constant.rs
new file mode 100644
index 000000000..0337a7ca8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/invalid_constant.rs
@@ -0,0 +1,42 @@
+// Verify that we can pretty print invalid constants.
+
+#![feature(adt_const_params)]
+#![feature(inline_const)]
+#![allow(incomplete_features)]
+
+#[derive(Copy, Clone)]
+#[repr(u32)]
+enum E { A, B, C }
+
+#[derive(Copy, Clone)]
+enum Empty {}
+
+// EMIT_MIR invalid_constant.main.ConstProp.diff
+fn main() {
+ // An invalid char.
+ union InvalidChar {
+ int: u32,
+ chr: char,
+ }
+ let _invalid_char = unsafe { InvalidChar { int: 0x110001 }.chr };
+
+ // An enum with an invalid tag. Regression test for #93688.
+ union InvalidTag {
+ int: u32,
+ e: E,
+ }
+ let _invalid_tag = [unsafe { InvalidTag { int: 4 }.e }];
+
+ // An enum without variants. Regression test for #94073.
+ union NoVariants {
+ int: u32,
+ empty: Empty,
+ }
+ let _enum_without_variants = [unsafe { NoVariants { int: 0 }.empty }];
+
+ // A non-UTF-8 string slice. Regression test for #75763 and #78520.
+ struct Str<const S: &'static str>;
+ let _non_utf8_str: Str::<{
+ unsafe { std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) }
+ }>;
+}
diff --git a/src/test/mir-opt/const_prop/issue-66971.rs b/src/test/mir-opt/const_prop/issue-66971.rs
new file mode 100644
index 000000000..81eccae46
--- /dev/null
+++ b/src/test/mir-opt/const_prop/issue-66971.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Z mir-opt-level=3
+
+// Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected
+// outputs below, after ConstProp this is how _2 would look like with the bug:
+//
+// _2 = (const Scalar(0x00) : (), const 0u8);
+//
+// Which has the wrong type.
+
+fn encode(this: ((), u8, u8)) {
+ assert!(this.2 == 0);
+}
+
+// EMIT_MIR issue_66971.main.ConstProp.diff
+fn main() {
+ encode(((), 0, 0));
+}
diff --git a/src/test/mir-opt/const_prop/issue-67019.rs b/src/test/mir-opt/const_prop/issue-67019.rs
new file mode 100644
index 000000000..c78b8b971
--- /dev/null
+++ b/src/test/mir-opt/const_prop/issue-67019.rs
@@ -0,0 +1,12 @@
+// compile-flags: -Z mir-opt-level=3
+
+// This used to ICE in const-prop
+
+fn test(this: ((u8, u8),)) {
+ assert!((this.0).0 == 1);
+}
+
+// EMIT_MIR issue_67019.main.ConstProp.diff
+fn main() {
+ test(((1, 2),));
+}
diff --git a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
new file mode 100644
index 000000000..b3d5980aa
--- /dev/null
+++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
@@ -0,0 +1,33 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-66971.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
+ let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ let mut _3: (); // in scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
+ StorageLive(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ StorageLive(_3); // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
+ nop; // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
+ Deinit(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ nop; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
+ StorageDead(_3); // scope 0 at $DIR/issue-66971.rs:+1:21: +1:22
+ _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
+ // mir::Constant
+ // + span: $DIR/issue-66971.rs:16:5: 16:11
+ // + literal: Const { ty: fn(((), u8, u8)) {encode}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/issue-66971.rs:+1:22: +1:23
+ StorageDead(_1); // scope 0 at $DIR/issue-66971.rs:+1:23: +1:24
+ nop; // scope 0 at $DIR/issue-66971.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/issue-66971.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
new file mode 100644
index 000000000..8330b5052
--- /dev/null
+++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
@@ -0,0 +1,34 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/issue-67019.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
+ let mut _2: ((u8, u8),); // in scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
+ let mut _3: (u8, u8); // in scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
+ StorageLive(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
+ StorageLive(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ Deinit(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ (_3.0: u8) = const 1_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ (_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ Deinit(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
+- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
++ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
+ StorageDead(_3); // scope 0 at $DIR/issue-67019.rs:+1:18: +1:19
+ _1 = test(move _2) -> bb1; // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
+ // mir::Constant
+ // + span: $DIR/issue-67019.rs:11:5: 11:9
+ // + literal: Const { ty: fn(((u8, u8),)) {test}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_2); // scope 0 at $DIR/issue-67019.rs:+1:19: +1:20
+ StorageDead(_1); // scope 0 at $DIR/issue-67019.rs:+1:20: +1:21
+ nop; // scope 0 at $DIR/issue-67019.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/issue-67019.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..96de39258
--- /dev/null
+++ b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff
@@ -0,0 +1,37 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/large_array_index.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/large_array_index.rs:+2:9: +2:10
+ let mut _2: [u8; 5000]; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ let _3: usize; // in scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ let mut _4: usize; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ let mut _5: bool; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/large_array_index.rs:+2:9: +2:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:+2:9: +2:10
+ StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ }
+
+ bb1: {
+ _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33
+ StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33
+ nop; // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2
+ StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..96de39258
--- /dev/null
+++ b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff
@@ -0,0 +1,37 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/large_array_index.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/large_array_index.rs:+2:9: +2:10
+ let mut _2: [u8; 5000]; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ let _3: usize; // in scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ let mut _4: usize; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ let mut _5: bool; // in scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/large_array_index.rs:+2:9: +2:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/large_array_index.rs:+2:9: +2:10
+ StorageLive(_2); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ _2 = [const 0_u8; 5000]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:29
+ StorageLive(_3); // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ _3 = const 2_usize; // scope 0 at $DIR/large_array_index.rs:+2:30: +2:31
+ _4 = const 5000_usize; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- _5 = Lt(_3, _4); // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ _5 = const true; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> bb1; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ }
+
+ bb1: {
+ _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32
+ StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33
+ StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33
+ nop; // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2
+ StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/large_array_index.rs b/src/test/mir-opt/const_prop/large_array_index.rs
new file mode 100644
index 000000000..48d134376
--- /dev/null
+++ b/src/test/mir-opt/const_prop/large_array_index.rs
@@ -0,0 +1,7 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+// EMIT_MIR large_array_index.main.ConstProp.diff
+fn main() {
+ // check that we don't propagate this, because it's too large
+ let x: u8 = [0_u8; 5000][2];
+}
diff --git a/src/test/mir-opt/const_prop/mult_by_zero.rs b/src/test/mir-opt/const_prop/mult_by_zero.rs
new file mode 100644
index 000000000..b0ecdf181
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mult_by_zero.rs
@@ -0,0 +1,10 @@
+// compile-flags: -O -Zmir-opt-level=4
+
+// EMIT_MIR mult_by_zero.test.ConstProp.diff
+fn test(x : i32) -> i32 {
+ x * 0
+}
+
+fn main() {
+ test(10);
+}
diff --git a/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff b/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff
new file mode 100644
index 000000000..629c8e601
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff
@@ -0,0 +1,18 @@
+- // MIR for `test` before ConstProp
++ // MIR for `test` after ConstProp
+
+ fn test(_1: i32) -> i32 {
+ debug x => _1; // in scope 0 at $DIR/mult_by_zero.rs:+0:9: +0:10
+ let mut _0: i32; // return place in scope 0 at $DIR/mult_by_zero.rs:+0:21: +0:24
+ let mut _2: i32; // in scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
+ _2 = _1; // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
+- _0 = Mul(move _2, const 0_i32); // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8
++ _0 = const 0_i32; // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8
+ StorageDead(_2); // scope 0 at $DIR/mult_by_zero.rs:+1:7: +1:8
+ return; // scope 0 at $DIR/mult_by_zero.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff
new file mode 100644
index 000000000..3bbd6a87f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff
@@ -0,0 +1,28 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/mutable_variable.rs:+1:9: +1:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/mutable_variable.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/mutable_variable.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable.rs:+1:9: +1:14
+ _1 = const 42_i32; // scope 0 at $DIR/mutable_variable.rs:+1:17: +1:19
+ _1 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:+2:5: +2:11
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable.rs:+3:9: +3:10
+- _2 = _1; // scope 1 at $DIR/mutable_variable.rs:+3:13: +3:14
++ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:+3:13: +3:14
+ nop; // scope 0 at $DIR/mutable_variable.rs:+0:11: +4:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/mutable_variable.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable.rs b/src/test/mir-opt/const_prop/mutable_variable.rs
new file mode 100644
index 000000000..801e7a9fc
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable.main.ConstProp.diff
+fn main() {
+ let mut x = 42;
+ x = 99;
+ let y = x;
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
new file mode 100644
index 000000000..fed6a98b9
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
@@ -0,0 +1,30 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
+ let _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
+ (_1.0: i32) = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
+ (_1.1: i32) = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
+ (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+2:5: +2:13
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+- _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
++ _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
+ nop; // scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +4:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs
new file mode 100644
index 000000000..e0b4b77ba
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable_aggregate.main.ConstProp.diff
+fn main() {
+ let mut x = (42, 43);
+ x.1 = 99;
+ let y = x;
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff
new file mode 100644
index 000000000..90eebd8fe
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff
@@ -0,0 +1,36 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14
+ let _2: &mut (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
+ scope 2 {
+ debug z => _2; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
+ let _3: (i32, i32); // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+ scope 3 {
+ debug y => _3; // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25
+ (_1.0: i32) = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25
+ (_1.1: i32) = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+1:17: +1:25
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
+ _2 = &mut _1; // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:13: +2:19
+ ((*_2).1: i32) = const 99_i32; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+3:5: +3:13
+ StorageLive(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+ _3 = _1; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14
+ nop; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+0:11: +5:2
+ StorageDead(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
new file mode 100644
index 000000000..79ac497c7
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs
@@ -0,0 +1,9 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable_aggregate_mut_ref.main.ConstProp.diff
+fn main() {
+ let mut x = (42, 43);
+ let z = &mut x;
+ z.1 = 99;
+ let y = x;
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff
new file mode 100644
index 000000000..c678f7b03
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff
@@ -0,0 +1,35 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:9: +1:14
+ _1 = foo() -> bb1; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+1:29: +1:34
+ // mir::Constant
+ // + span: $DIR/mutable_variable_aggregate_partial_read.rs:5:29: 5:32
+ // + literal: Const { ty: fn() -> (i32, i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+2:5: +2:13
+ (_1.0: i32) = const 42_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+3:5: +3:13
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10
+- _2 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16
++ _2 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16
+ nop; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +5:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
new file mode 100644
index 000000000..9bb62b897
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs
@@ -0,0 +1,14 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable_aggregate_partial_read.main.ConstProp.diff
+fn main() {
+ let mut x: (i32, i32) = foo();
+ x.1 = 99;
+ x.0 = 42;
+ let y = x.1;
+}
+
+#[inline(never)]
+fn foo() -> (i32, i32) {
+ unimplemented!()
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
new file mode 100644
index 000000000..4c2ba9a09
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
@@ -0,0 +1,48 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +0:11
+ let mut _1: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14
+ let _2: (); // in scope 0 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6
+ let mut _3: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ let mut _4: *mut u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14
+ let _5: u32; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10
+ scope 2 {
+ }
+ scope 3 {
+ debug y => _5; // in scope 3 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14
+ _1 = const 42_u32; // scope 0 at $DIR/mutable_variable_no_prop.rs:+1:17: +1:19
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6
+ StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ _4 = const {alloc1: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ // mir::Constant
+ // + span: $DIR/mutable_variable_no_prop.rs:9:13: 9:19
+ // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) }
+ _3 = (*_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19
+ _1 = move _3; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19
+ StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:18: +3:19
+ StorageDead(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:19: +3:20
+ nop; // scope 2 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:+4:5: +4:6
+ StorageLive(_5); // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10
+ _5 = _1; // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:13: +5:14
+ nop; // scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +6:2
+ StorageDead(_5); // scope 1 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:2: +6:2
+ }
+ }
+
+ alloc1 (static: STATIC, size: 4, align: 4) {
+ 2a 00 00 00 │ *...
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs
new file mode 100644
index 000000000..4126fb3c6
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs
@@ -0,0 +1,12 @@
+// compile-flags: -O
+
+static mut STATIC: u32 = 42;
+
+// EMIT_MIR mutable_variable_no_prop.main.ConstProp.diff
+fn main() {
+ let mut x = 42;
+ unsafe {
+ x = STATIC;
+ }
+ let y = x;
+}
diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
new file mode 100644
index 000000000..5328792b3
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
@@ -0,0 +1,53 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
+ let mut _3: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
+ let mut _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ scope 2 {
+ debug x => _2; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ let _4: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ scope 3 {
+ debug y => _4; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ let _5: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+ scope 4 {
+ debug z => _5; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
+ _1 = foo() -> bb1; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:13: +1:18
+ // mir::Constant
+ // + span: $DIR/mutable_variable_unprop_assign.rs:5:13: 5:16
+ // + literal: Const { ty: fn() -> i32 {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ Deinit(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ (_2.0: i32) = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ (_2.1: i32) = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ _3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ (_2.1: i32) = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12
+ StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
+ StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
+ _4 = (_2.1: i32); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
+ StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+ _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
+ nop; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +6:2
+ StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs
new file mode 100644
index 000000000..13f1b3f47
--- /dev/null
+++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs
@@ -0,0 +1,15 @@
+// compile-flags: -O
+
+// EMIT_MIR mutable_variable_unprop_assign.main.ConstProp.diff
+fn main() {
+ let a = foo();
+ let mut x: (i32, i32) = (1, 2);
+ x.1 = a;
+ let y = x.1;
+ let z = x.0; // this could theoretically be allowed, but we can't handle it right now
+}
+
+#[inline(never)]
+fn foo() -> i32 {
+ unimplemented!()
+}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..94aadfaf8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
@@ -0,0 +1,68 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ }
+
+ bb1: {
+- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ }
+
+ bb2: {
+- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+ StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
+ StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..94aadfaf8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
@@ -0,0 +1,68 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ }
+
+ bb1: {
+- _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
++ _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _6 = const 6_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+- _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ _7 = const true; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ }
+
+ bb2: {
+- _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
++ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+ StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
+ StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir
new file mode 100644
index 000000000..75cea8ad2
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after SimplifyLocals
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir
new file mode 100644
index 000000000..75cea8ad2
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after SimplifyLocals
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.rs b/src/test/mir-opt/const_prop/optimizes_into_variable.rs
new file mode 100644
index 000000000..17265b7eb
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.rs
@@ -0,0 +1,15 @@
+// compile-flags: -C overflow-checks=on
+
+struct Point {
+ x: u32,
+ y: u32,
+}
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR optimizes_into_variable.main.ConstProp.diff
+// EMIT_MIR optimizes_into_variable.main.SimplifyLocals.after.mir
+fn main() {
+ let x = 2 + 2;
+ let y = [0, 1, 2, 3, 4, 5][3];
+ let z = (Point { x: 12, y: 42}).y;
+}
diff --git a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
new file mode 100644
index 000000000..89f43d751
--- /dev/null
+++ b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
@@ -0,0 +1,48 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/read_immutable_static.rs:+0:11: +0:11
+ let _1: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:9: +1:10
+ let mut _2: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ let mut _3: &u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ let mut _4: u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ let mut _5: &u8; // in scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/read_immutable_static.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/read_immutable_static.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ StorageLive(_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ _3 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ // mir::Constant
+ // + span: $DIR/read_immutable_static.rs:7:13: 7:16
+ // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
+- _2 = (*_3); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
++ _2 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:16
+ StorageLive(_4); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ StorageLive(_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ _5 = const {alloc1: &u8}; // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+ // mir::Constant
+ // + span: $DIR/read_immutable_static.rs:7:19: 7:22
+ // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
+- _4 = (*_5); // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
+- _1 = Add(move _2, move _4); // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:22
++ _4 = const 2_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:19: +1:22
++ _1 = const 4_u8; // scope 0 at $DIR/read_immutable_static.rs:+1:13: +1:22
+ StorageDead(_4); // scope 0 at $DIR/read_immutable_static.rs:+1:21: +1:22
+ StorageDead(_2); // scope 0 at $DIR/read_immutable_static.rs:+1:21: +1:22
+ StorageDead(_5); // scope 0 at $DIR/read_immutable_static.rs:+1:22: +1:23
+ StorageDead(_3); // scope 0 at $DIR/read_immutable_static.rs:+1:22: +1:23
+ nop; // scope 0 at $DIR/read_immutable_static.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/read_immutable_static.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/read_immutable_static.rs:+2:2: +2:2
+ }
+ }
+
+ alloc1 (static: FOO, size: 1, align: 1) {
+ 02 │ .
+ }
+
diff --git a/src/test/mir-opt/const_prop/read_immutable_static.rs b/src/test/mir-opt/const_prop/read_immutable_static.rs
new file mode 100644
index 000000000..8a5f12c6f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/read_immutable_static.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O
+
+static FOO: u8 = 2;
+
+// EMIT_MIR read_immutable_static.main.ConstProp.diff
+fn main() {
+ let x = FOO + FOO;
+}
diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
new file mode 100644
index 000000000..c8b09220f
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
@@ -0,0 +1,27 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_deref.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ let mut _2: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ let _3: i32; // in scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
+ let mut _4: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ // mir::Constant
+ // + span: $DIR/ref_deref.rs:5:6: 5:10
+ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
+ _2 = _4; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
++ _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ nop; // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/ref_deref.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
new file mode 100644
index 000000000..d141d2cf8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
@@ -0,0 +1,30 @@
+- // MIR for `main` before PromoteTemps
++ // MIR for `main` after PromoteTemps
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_deref.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ let mut _2: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ let _3: i32; // in scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
++ let mut _4: &i32; // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+ StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+- StorageLive(_3); // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
+- _3 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
+- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
++ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
++ // mir::Constant
++ // + span: $DIR/ref_deref.rs:5:6: 5:10
++ // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
++ _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+ _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+- StorageDead(_3); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
+ _0 = const (); // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/ref_deref.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/ref_deref.rs b/src/test/mir-opt/const_prop/ref_deref.rs
new file mode 100644
index 000000000..30ec97663
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR ref_deref.main.PromoteTemps.diff
+// EMIT_MIR ref_deref.main.ConstProp.diff
+
+fn main() {
+ *(&4);
+}
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
new file mode 100644
index 000000000..f0c89caea
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
@@ -0,0 +1,26 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_deref_project.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ let mut _2: &i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ let _3: (i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
+ let mut _4: &(i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ // mir::Constant
+ // + span: $DIR/ref_deref_project.rs:5:6: 5:17
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
+ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ nop; // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/ref_deref_project.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
new file mode 100644
index 000000000..d25540287
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
@@ -0,0 +1,30 @@
+- // MIR for `main` before PromoteTemps
++ // MIR for `main` after PromoteTemps
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_deref_project.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ let mut _2: &i32; // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ let _3: (i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
++ let mut _4: &(i32, i32); // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+ StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+- StorageLive(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
+- _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
+- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
++ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
++ // mir::Constant
++ // + span: $DIR/ref_deref_project.rs:5:6: 5:17
++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
++ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
+ _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
+- StorageDead(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
+ _0 = const (); // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/ref_deref_project.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs
new file mode 100644
index 000000000..c7cc73651
--- /dev/null
+++ b/src/test/mir-opt/const_prop/ref_deref_project.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR ref_deref_project.main.PromoteTemps.diff
+// EMIT_MIR ref_deref_project.main.ConstProp.diff
+
+fn main() {
+ *(&(4, 5).1); // This does not currently propagate (#67862)
+}
diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
new file mode 100644
index 000000000..237a6f94a
--- /dev/null
+++ b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
@@ -0,0 +1,29 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +0:11
+ let mut _1: *const fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41
+ let mut _2: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26
+ let mut _3: fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41
+ StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26
+ StorageLive(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17
+ _3 = main as fn() (Pointer(ReifyFnPointer)); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17
+ // mir::Constant
+ // + span: $DIR/reify_fn_ptr.rs:4:13: 4:17
+ // + literal: Const { ty: fn() {main}, val: Value(<ZST>) }
+ _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26
+ StorageDead(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26
+ _1 = move _2 as *const fn() (PointerFromExposedAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41
+ StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41
+ StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:41: +1:42
+ nop; // scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/reify_fn_ptr.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.rs b/src/test/mir-opt/const_prop/reify_fn_ptr.rs
new file mode 100644
index 000000000..bfe2563ad
--- /dev/null
+++ b/src/test/mir-opt/const_prop/reify_fn_ptr.rs
@@ -0,0 +1,5 @@
+// EMIT_MIR reify_fn_ptr.main.ConstProp.diff
+
+fn main() {
+ let _ = main as usize as *const fn();
+}
diff --git a/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..7c4977996
--- /dev/null
+++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff
@@ -0,0 +1,43 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/repeat.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/repeat.rs:+1:9: +1:10
+ let mut _2: u32; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ let mut _3: [u32; 8]; // in scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ let _4: usize; // in scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ let mut _5: usize; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ let mut _6: bool; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/repeat.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/repeat.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ StorageLive(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ }
+
+ bb1: {
+- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:+1:18: +1:32
++ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:32
+ StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32
+ StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33
+ StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33
+ nop; // scope 0 at $DIR/repeat.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..7c4977996
--- /dev/null
+++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff
@@ -0,0 +1,43 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/repeat.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/repeat.rs:+1:9: +1:10
+ let mut _2: u32; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ let mut _3: [u32; 8]; // in scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ let _4: usize; // in scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ let mut _5: usize; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ let mut _6: bool; // in scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/repeat.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/repeat.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ StorageLive(_3); // scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ _3 = [const 42_u32; 8]; // scope 0 at $DIR/repeat.rs:+1:18: +1:25
+ StorageLive(_4); // scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ _4 = const 2_usize; // scope 0 at $DIR/repeat.rs:+1:26: +1:27
+ _5 = const 8_usize; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- _6 = Lt(_4, _5); // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ _6 = const true; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> bb1; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+ }
+
+ bb1: {
+- _2 = _3[_4]; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
+- _1 = Add(move _2, const 0_u32); // scope 0 at $DIR/repeat.rs:+1:18: +1:32
++ _2 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:28
++ _1 = const 42_u32; // scope 0 at $DIR/repeat.rs:+1:18: +1:32
+ StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32
+ StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33
+ StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33
+ nop; // scope 0 at $DIR/repeat.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/repeat.rs b/src/test/mir-opt/const_prop/repeat.rs
new file mode 100644
index 000000000..36d9b9fc6
--- /dev/null
+++ b/src/test/mir-opt/const_prop/repeat.rs
@@ -0,0 +1,7 @@
+// compile-flags: -O
+
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR repeat.main.ConstProp.diff
+fn main() {
+ let x: u32 = [42; 8][2] + 0;
+}
diff --git a/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff
new file mode 100644
index 000000000..5ebd8a520
--- /dev/null
+++ b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff
@@ -0,0 +1,21 @@
+- // MIR for `add` before ConstProp
++ // MIR for `add` after ConstProp
+
+ fn add() -> u32 {
+ let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16
+ let mut _1: (u32, bool); // in scope 0 at $DIR/return_place.rs:+1:5: +1:10
+
+ bb0: {
+- _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:+1:5: +1:10
+- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:+1:5: +1:10
++ _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:+1:5: +1:10
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:+1:5: +1:10
+ }
+
+ bb1: {
+- _0 = move (_1.0: u32); // scope 0 at $DIR/return_place.rs:+1:5: +1:10
++ _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10
+ return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir b/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir
new file mode 100644
index 000000000..ececd9942
--- /dev/null
+++ b/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir
@@ -0,0 +1,10 @@
+// MIR for `add` before PreCodegen
+
+fn add() -> u32 {
+ let mut _0: u32; // return place in scope 0 at $DIR/return_place.rs:+0:13: +0:16
+
+ bb0: {
+ _0 = const 4_u32; // scope 0 at $DIR/return_place.rs:+1:5: +1:10
+ return; // scope 0 at $DIR/return_place.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/return_place.rs b/src/test/mir-opt/const_prop/return_place.rs
new file mode 100644
index 000000000..06a853696
--- /dev/null
+++ b/src/test/mir-opt/const_prop/return_place.rs
@@ -0,0 +1,11 @@
+// compile-flags: -C overflow-checks=on
+
+// EMIT_MIR return_place.add.ConstProp.diff
+// EMIT_MIR return_place.add.PreCodegen.before.mir
+fn add() -> u32 {
+ 2 + 2
+}
+
+fn main() {
+ add();
+}
diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff
new file mode 100644
index 000000000..5920937e0
--- /dev/null
+++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff
@@ -0,0 +1,35 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10
+ let _2: (); // in scope 0 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
+ let mut _3: u32; // in scope 0 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10
+ _1 = const 1_u32; // scope 0 at $DIR/scalar_literal_propagation.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
+ StorageLive(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
+- _3 = _1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
+- _2 = consume(move _3) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
++ _3 = const 1_u32; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
++ _2 = consume(const 1_u32) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
+ // mir::Constant
+ // + span: $DIR/scalar_literal_propagation.rs:4:5: 4:12
+ // + literal: Const { ty: fn(u32) {consume}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:14: +2:15
+ StorageDead(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:15: +2:16
+ nop; // scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +3:2
+ StorageDead(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/scalar_literal_propagation.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation.rs b/src/test/mir-opt/const_prop/scalar_literal_propagation.rs
new file mode 100644
index 000000000..8724e4d57
--- /dev/null
+++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.rs
@@ -0,0 +1,8 @@
+// EMIT_MIR scalar_literal_propagation.main.ConstProp.diff
+fn main() {
+ let x = 1;
+ consume(x);
+}
+
+#[inline(never)]
+fn consume(_: u32) { }
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
new file mode 100644
index 000000000..0ebfbca21
--- /dev/null
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
@@ -0,0 +1,53 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/slice_len.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _2: &[u32]; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:30
+ let mut _3: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let _4: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let _5: [u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:7: +1:19
+ let _6: usize; // in scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
+ StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ // mir::Constant
+ // + span: $DIR/slice_len.rs:5:6: 5:19
+ // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageLive(_10); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _10 = _3; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19
+ StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageDead(_10); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ }
+
+ bb1: {
+- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageDead(_6); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_4); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_2); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_1); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ nop; // scope 0 at $DIR/slice_len.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/slice_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
new file mode 100644
index 000000000..0ebfbca21
--- /dev/null
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
@@ -0,0 +1,53 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/slice_len.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _2: &[u32]; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:30
+ let mut _3: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let _4: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let _5: [u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:7: +1:19
+ let _6: usize; // in scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30
+ StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ // mir::Constant
+ // + span: $DIR/slice_len.rs:5:6: 5:19
+ // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
+ _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageLive(_10); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _10 = _3; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
+ StorageDead(_3); // scope 0 at $DIR/slice_len.rs:+1:18: +1:19
+ StorageLive(_6); // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ _6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
+ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageDead(_10); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ _8 = const true; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ }
+
+ bb1: {
+- _1 = (*_2)[_6]; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++ _1 = const 2_u32; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+ StorageDead(_6); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_4); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_2); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ StorageDead(_1); // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
+ nop; // scope 0 at $DIR/slice_len.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/slice_len.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/slice_len.rs b/src/test/mir-opt/const_prop/slice_len.rs
new file mode 100644
index 000000000..fa9eafa8b
--- /dev/null
+++ b/src/test/mir-opt/const_prop/slice_len.rs
@@ -0,0 +1,6 @@
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+// EMIT_MIR slice_len.main.ConstProp.diff
+fn main() {
+ (&[1u32, 2, 3] as &[u32])[1];
+}
diff --git a/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff
new file mode 100644
index 000000000..9d7c2784d
--- /dev/null
+++ b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff
@@ -0,0 +1,34 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/switch_int.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+ _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+- switchInt(_1) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
++ switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = foo(const -1_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21
+ // mir::Constant
+ // + span: $DIR/switch_int.rs:9:14: 9:17
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ _0 = foo(const 0_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20
+ // mir::Constant
+ // + span: $DIR/switch_int.rs:8:14: 8:17
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_1); // scope 0 at $DIR/switch_int.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/switch_int.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff b/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff
new file mode 100644
index 000000000..74f9eafe4
--- /dev/null
+++ b/src/test/mir-opt/const_prop/switch_int.main.SimplifyConstCondition-after-const-prop.diff
@@ -0,0 +1,34 @@
+- // MIR for `main` before SimplifyConstCondition-after-const-prop
++ // MIR for `main` after SimplifyConstCondition-after-const-prop
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/switch_int.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+ _1 = const 1_i32; // scope 0 at $DIR/switch_int.rs:+1:11: +1:12
+- switchInt(const 1_i32) -> [1_i32: bb2, otherwise: bb1]; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
++ goto -> bb2; // scope 0 at $DIR/switch_int.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ _0 = foo(const -1_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+3:14: +3:21
+ // mir::Constant
+ // + span: $DIR/switch_int.rs:9:14: 9:17
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ _0 = foo(const 0_i32) -> bb3; // scope 0 at $DIR/switch_int.rs:+2:14: +2:20
+ // mir::Constant
+ // + span: $DIR/switch_int.rs:8:14: 8:17
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ StorageDead(_1); // scope 0 at $DIR/switch_int.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/switch_int.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/switch_int.rs b/src/test/mir-opt/const_prop/switch_int.rs
new file mode 100644
index 000000000..d7319eca1
--- /dev/null
+++ b/src/test/mir-opt/const_prop/switch_int.rs
@@ -0,0 +1,11 @@
+#[inline(never)]
+fn foo(_: i32) { }
+
+// EMIT_MIR switch_int.main.ConstProp.diff
+// EMIT_MIR switch_int.main.SimplifyConstCondition-after-const-prop.diff
+fn main() {
+ match 1 {
+ 1 => foo(0),
+ _ => foo(-1),
+ }
+}
diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff
new file mode 100644
index 000000000..a0603c60d
--- /dev/null
+++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff
@@ -0,0 +1,36 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +0:11
+ let _1: (u32, u32); // in scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10
+ let _2: (); // in scope 0 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15
+ let mut _3: (u32, u32); // in scope 0 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19
+ (_1.0: u32) = const 1_u32; // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19
+ (_1.1: u32) = const 2_u32; // scope 0 at $DIR/tuple_literal_propagation.rs:+1:13: +1:19
+ StorageLive(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15
+ StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14
+- _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14
++ _3 = const (1_u32, 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:13: +3:14
+ _2 = consume(move _3) -> bb1; // scope 1 at $DIR/tuple_literal_propagation.rs:+3:5: +3:15
+ // mir::Constant
+ // + span: $DIR/tuple_literal_propagation.rs:5:5: 5:12
+ // + literal: Const { ty: fn((u32, u32)) {consume}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:14: +3:15
+ StorageDead(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:15: +3:16
+ nop; // scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/tuple_literal_propagation.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.rs b/src/test/mir-opt/const_prop/tuple_literal_propagation.rs
new file mode 100644
index 000000000..e644baec4
--- /dev/null
+++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR tuple_literal_propagation.main.ConstProp.diff
+fn main() {
+ let x = (1, 2);
+
+ consume(x);
+}
+
+#[inline(never)]
+fn consume(_: (u32, u32)) { }