summaryrefslogtreecommitdiffstats
path: root/src/test/mir-opt/dest-prop
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/mir-opt/dest-prop')
-rw-r--r--src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff65
-rw-r--r--src/test/mir-opt/dest-prop/branch.rs21
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff26
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff28
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff18
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff28
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.rs39
-rw-r--r--src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff53
-rw-r--r--src/test/mir-opt/dest-prop/cycle.rs15
-rw-r--r--src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff39
-rw-r--r--src/test/mir-opt/dest-prop/simple.rs14
-rw-r--r--src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff41
-rw-r--r--src/test/mir-opt/dest-prop/union.rs16
13 files changed, 403 insertions, 0 deletions
diff --git a/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff
new file mode 100644
index 000000000..8929f2cc7
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff
@@ -0,0 +1,65 @@
+- // MIR for `main` before DestinationPropagation
++ // MIR for `main` after DestinationPropagation
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/branch.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/branch.rs:+1:9: +1:10
+ let mut _3: bool; // in scope 0 at $DIR/branch.rs:+3:16: +3:22
+ let _4: i32; // in scope 0 at $DIR/branch.rs:+6:9: +6:14
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/branch.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/branch.rs:+3:9: +3:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/branch.rs:+3:9: +3:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/branch.rs:+1:9: +1:10
+ _1 = val() -> bb1; // scope 0 at $DIR/branch.rs:+1:13: +1:18
+ // mir::Constant
+ // + span: $DIR/branch.rs:13:13: 13:16
+ // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 1 at $DIR/branch.rs:+3:9: +3:10
+ StorageLive(_3); // scope 1 at $DIR/branch.rs:+3:16: +3:22
+ _3 = cond() -> bb2; // scope 1 at $DIR/branch.rs:+3:16: +3:22
+ // mir::Constant
+ // + span: $DIR/branch.rs:15:16: 15:20
+ // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ switchInt(move _3) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22
+ }
+
+ bb3: {
+ nop; // scope 1 at $DIR/branch.rs:+4:9: +4:10
+ goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6
+ }
+
+ bb4: {
+ StorageLive(_4); // scope 1 at $DIR/branch.rs:+6:9: +6:14
+ _4 = val() -> bb5; // scope 1 at $DIR/branch.rs:+6:9: +6:14
+ // mir::Constant
+ // + span: $DIR/branch.rs:18:9: 18:12
+ // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+ }
+
+ bb5: {
+ StorageDead(_4); // scope 1 at $DIR/branch.rs:+6:14: +6:15
+ nop; // scope 1 at $DIR/branch.rs:+7:9: +7:10
+ goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6
+ }
+
+ bb6: {
+ StorageDead(_3); // scope 1 at $DIR/branch.rs:+8:5: +8:6
+ nop; // scope 0 at $DIR/branch.rs:+0:11: +9:2
+ StorageDead(_2); // scope 1 at $DIR/branch.rs:+9:1: +9:2
+ StorageDead(_1); // scope 0 at $DIR/branch.rs:+9:1: +9:2
+ return; // scope 0 at $DIR/branch.rs:+9:2: +9:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/branch.rs b/src/test/mir-opt/dest-prop/branch.rs
new file mode 100644
index 000000000..fffcf82b3
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/branch.rs
@@ -0,0 +1,21 @@
+//! Tests that assignment in both branches of an `if` are eliminated.
+// compile-flags: -Zunsound-mir-opts
+fn val() -> i32 {
+ 1
+}
+
+fn cond() -> bool {
+ true
+}
+
+// EMIT_MIR branch.main.DestinationPropagation.diff
+fn main() {
+ let x = val();
+
+ let y = if cond() {
+ x
+ } else {
+ val();
+ x
+ };
+}
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff
new file mode 100644
index 000000000..f28bc72df
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff
@@ -0,0 +1,26 @@
+- // MIR for `arg_src` before DestinationPropagation
++ // MIR for `arg_src` after DestinationPropagation
+
+ fn arg_src(_1: i32) -> i32 {
+ debug x => const 123_i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0:17
+ let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30
+ let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+ scope 1 {
+- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
++ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+ }
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
+ nop; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12
+- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
+- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
++ nop; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
new file mode 100644
index 000000000..a8a7e9ab6
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
@@ -0,0 +1,28 @@
+- // MIR for `bar` before DestinationPropagation
++ // MIR for `bar` after DestinationPropagation
+
+ fn bar(_1: u8) -> () {
+ debug x => const 5_u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+ let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
+ let _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+ let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+ StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+ _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+ _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+ // mir::Constant
+ // + span: $DIR/copy_propagation_arg.rs:16:5: 16:10
+ // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13
+ StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
new file mode 100644
index 000000000..ce9be4c27
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
@@ -0,0 +1,18 @@
+- // MIR for `baz` before DestinationPropagation
++ // MIR for `baz` after DestinationPropagation
+
+ fn baz(_1: i32) -> () {
+ debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+ let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:20: +0:20
+ let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+ StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:20: +3:2
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
new file mode 100644
index 000000000..d7a0b950f
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
@@ -0,0 +1,28 @@
+- // MIR for `foo` before DestinationPropagation
++ // MIR for `foo` after DestinationPropagation
+
+ fn foo(_1: u8) -> () {
+ debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+ let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
+ let mut _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+ let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+ StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+ _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+ _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+ // mir::Constant
+ // + span: $DIR/copy_propagation_arg.rs:11:9: 11:14
+ // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17
+ StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.rs b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs
new file mode 100644
index 000000000..a5fb0f640
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs
@@ -0,0 +1,39 @@
+// Check that DestinationPropagation does not propagate an assignment to a function argument
+// (doing so can break usages of the original argument value)
+// compile-flags: -Zunsound-mir-opts
+fn dummy(x: u8) -> u8 {
+ x
+}
+
+// EMIT_MIR copy_propagation_arg.foo.DestinationPropagation.diff
+fn foo(mut x: u8) {
+ // calling `dummy` to make a use of `x` that copyprop cannot eliminate
+ x = dummy(x); // this will assign a local to `x`
+}
+
+// EMIT_MIR copy_propagation_arg.bar.DestinationPropagation.diff
+fn bar(mut x: u8) {
+ dummy(x);
+ x = 5;
+}
+
+// EMIT_MIR copy_propagation_arg.baz.DestinationPropagation.diff
+fn baz(mut x: i32) {
+ // self-assignment to a function argument should be eliminated
+ x = x;
+}
+
+// EMIT_MIR copy_propagation_arg.arg_src.DestinationPropagation.diff
+fn arg_src(mut x: i32) -> i32 {
+ let y = x;
+ x = 123; // Don't propagate this assignment to `y`
+ y
+}
+
+fn main() {
+ // Make sure the function actually gets instantiated.
+ foo(0);
+ bar(0);
+ baz(0);
+ arg_src(0);
+}
diff --git a/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
new file mode 100644
index 000000000..8eeb0d354
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
@@ -0,0 +1,53 @@
+- // MIR for `main` before DestinationPropagation
++ // MIR for `main` after DestinationPropagation
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/cycle.rs:+1:9: +1:14
+ let mut _4: i32; // in scope 0 at $DIR/cycle.rs:+4:9: +4:10
+ let _5: (); // in scope 0 at $DIR/cycle.rs:+6:5: +6:12
+ let mut _6: i32; // in scope 0 at $DIR/cycle.rs:+6:10: +6:11
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/cycle.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10
+ let _3: i32; // in scope 2 at $DIR/cycle.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
+ scope 4 (inlined std::mem::drop::<i32>) { // at $DIR/cycle.rs:14:5: 14:12
+ debug _x => _6; // in scope 4 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:14
+ _1 = val() -> bb1; // scope 0 at $DIR/cycle.rs:+1:17: +1:22
+ // mir::Constant
+ // + span: $DIR/cycle.rs:9:17: 9:20
+ // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageLive(_2); // scope 1 at $DIR/cycle.rs:+2:9: +2:10
+ nop; // scope 1 at $DIR/cycle.rs:+2:13: +2:14
+ StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10
+ nop; // scope 2 at $DIR/cycle.rs:+3:13: +3:14
+ StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+ nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+ nop; // scope 3 at $DIR/cycle.rs:+4:5: +4:10
+ StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+ StorageLive(_5); // scope 3 at $DIR/cycle.rs:+6:5: +6:12
+ StorageLive(_6); // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+ StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12
+ StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13
+ StorageDead(_3); // scope 2 at $DIR/cycle.rs:+7:1: +7:2
+ StorageDead(_2); // scope 1 at $DIR/cycle.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/cycle.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/cycle.rs b/src/test/mir-opt/dest-prop/cycle.rs
new file mode 100644
index 000000000..c9187d408
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/cycle.rs
@@ -0,0 +1,15 @@
+//! Tests that cyclic assignments don't hang DestinationPropagation, and result in reasonable code.
+// compile-flags: -Zunsound-mir-opts
+fn val() -> i32 {
+ 1
+}
+
+// EMIT_MIR cycle.main.DestinationPropagation.diff
+fn main() {
+ let mut x = val();
+ let y = x;
+ let z = y;
+ x = z;
+
+ drop(x);
+}
diff --git a/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
new file mode 100644
index 000000000..a20a172af
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
@@ -0,0 +1,39 @@
+- // MIR for `nrvo` before DestinationPropagation
++ // MIR for `nrvo` after DestinationPropagation
+
+ fn nrvo(_1: for<'r> fn(&'r mut [u8; 1024])) -> [u8; 1024] {
+ debug init => _1; // in scope 0 at $DIR/simple.rs:+0:9: +0:13
+ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/simple.rs:+0:39: +0:49
+ let mut _2: [u8; 1024]; // in scope 0 at $DIR/simple.rs:+1:9: +1:16
+ let _3: (); // in scope 0 at $DIR/simple.rs:+2:5: +2:19
+ let mut _4: for<'r> fn(&'r mut [u8; 1024]); // in scope 0 at $DIR/simple.rs:+2:5: +2:9
+ let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/simple.rs:+2:10: +2:18
+ let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/simple.rs:+2:10: +2:18
+ scope 1 {
+ debug buf => _2; // in scope 1 at $DIR/simple.rs:+1:9: +1:16
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 0 at $DIR/simple.rs:+1:9: +1:16
+ _2 = [const 0_u8; 1024]; // scope 0 at $DIR/simple.rs:+1:19: +1:28
+ StorageLive(_3); // scope 1 at $DIR/simple.rs:+2:5: +2:19
+ StorageLive(_4); // scope 1 at $DIR/simple.rs:+2:5: +2:9
+ _4 = _1; // scope 1 at $DIR/simple.rs:+2:5: +2:9
+ StorageLive(_5); // scope 1 at $DIR/simple.rs:+2:10: +2:18
+ StorageLive(_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18
+ _6 = &mut _2; // scope 1 at $DIR/simple.rs:+2:10: +2:18
+ _5 = &mut (*_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18
+ _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/simple.rs:+2:5: +2:19
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 1 at $DIR/simple.rs:+2:18: +2:19
+ StorageDead(_4); // scope 1 at $DIR/simple.rs:+2:18: +2:19
+ StorageDead(_6); // scope 1 at $DIR/simple.rs:+2:19: +2:20
+ StorageDead(_3); // scope 1 at $DIR/simple.rs:+2:19: +2:20
+ _0 = _2; // scope 1 at $DIR/simple.rs:+3:5: +3:8
+ StorageDead(_2); // scope 0 at $DIR/simple.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/simple.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/simple.rs b/src/test/mir-opt/dest-prop/simple.rs
new file mode 100644
index 000000000..3627d479a
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/simple.rs
@@ -0,0 +1,14 @@
+//! Copy of `nrvo-simple.rs`, to ensure that full dest-prop handles it too.
+// compile-flags: -Zunsound-mir-opts
+// EMIT_MIR simple.nrvo.DestinationPropagation.diff
+fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] {
+ let mut buf = [0; 1024];
+ init(&mut buf);
+ buf
+}
+
+fn main() {
+ let _ = nrvo(|buf| {
+ buf[4] = 4;
+ });
+}
diff --git a/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff
new file mode 100644
index 000000000..accdb0085
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff
@@ -0,0 +1,41 @@
+- // MIR for `main` before DestinationPropagation
++ // MIR for `main` after DestinationPropagation
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/union.rs:+0:11: +0:11
+ let _1: main::Un; // in scope 0 at $DIR/union.rs:+5:9: +5:11
+ let mut _2: u32; // in scope 0 at $DIR/union.rs:+5:23: +5:28
+ let _3: (); // in scope 0 at $DIR/union.rs:+7:5: +7:27
+ let mut _4: u32; // in scope 0 at $DIR/union.rs:+7:10: +7:26
+ scope 1 {
+ debug un => _1; // in scope 1 at $DIR/union.rs:+5:9: +5:11
+ scope 2 {
+ }
+ scope 3 (inlined std::mem::drop::<u32>) { // at $DIR/union.rs:15:5: 15:27
+ debug _x => _4; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/union.rs:+5:9: +5:11
+ StorageLive(_2); // scope 0 at $DIR/union.rs:+5:23: +5:28
+ _2 = val() -> bb1; // scope 0 at $DIR/union.rs:+5:23: +5:28
+ // mir::Constant
+ // + span: $DIR/union.rs:13:23: 13:26
+ // + literal: Const { ty: fn() -> u32 {val}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ nop; // scope 0 at $DIR/union.rs:+5:14: +5:30
+ nop; // scope 0 at $DIR/union.rs:+5:14: +5:30
+ StorageDead(_2); // scope 0 at $DIR/union.rs:+5:29: +5:30
+ StorageLive(_3); // scope 1 at $DIR/union.rs:+7:5: +7:27
+ StorageLive(_4); // scope 1 at $DIR/union.rs:+7:10: +7:26
+ nop; // scope 2 at $DIR/union.rs:+7:19: +7:24
+ StorageDead(_4); // scope 1 at $DIR/union.rs:+7:26: +7:27
+ StorageDead(_3); // scope 1 at $DIR/union.rs:+7:27: +7:28
+ StorageDead(_1); // scope 0 at $DIR/union.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/union.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dest-prop/union.rs b/src/test/mir-opt/dest-prop/union.rs
new file mode 100644
index 000000000..68c834dfb
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/union.rs
@@ -0,0 +1,16 @@
+//! Tests that we can propogate into places that are projections into unions
+// compile-flags: -Zunsound-mir-opts
+fn val() -> u32 {
+ 1
+}
+
+// EMIT_MIR union.main.DestinationPropagation.diff
+fn main() {
+ union Un {
+ us: u32,
+ }
+
+ let un = Un { us: val() };
+
+ drop(unsafe { un.us });
+}