about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorShotaro Yamada <sinkuu@sinkuu.xyz>2017-12-03 17:38:56 +0900
committerShotaro Yamada <sinkuu@sinkuu.xyz>2017-12-03 17:42:52 +0900
commit17d6631c02a297b187d75817b4cfe4d2b3c6c9de (patch)
treec0217ba883351bcf107bac78e310c1644d509449 /src
parent7e251390c782d5b8d94c6e55c83572a3a7a26cb4 (diff)
downloadrust-17d6631c02a297b187d75817b4cfe4d2b3c6c9de.tar.gz
rust-17d6631c02a297b187d75817b4cfe4d2b3c6c9de.zip
Fix MIR CopyPropagation regression
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/transform/copy_prop.rs11
-rw-r--r--src/test/mir-opt/copy_propagation_arg.rs76
2 files changed, 57 insertions, 30 deletions
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 6047b4e174a..95fe99a1bec 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -239,10 +239,13 @@ impl<'tcx> Action<'tcx> {
         //     USE(SRC);
         let src_def_count = src_use_info.def_count_not_including_drop();
         // allow function arguments to be propagated
-        if src_def_count > 1 ||
-            (src_def_count == 0 && mir.local_kind(src_local) != LocalKind::Arg) {
-            debug!("  Can't copy-propagate local: {} defs of src",
-                   src_use_info.def_count_not_including_drop());
+        let is_arg = mir.local_kind(src_local) == LocalKind::Arg;
+        if (is_arg && src_def_count != 0) || (!is_arg && src_def_count != 1) {
+            debug!(
+                "  Can't copy-propagate local: {} defs of src{}",
+                src_def_count,
+                if is_arg { " (argument)" } else { "" },
+            );
             return None
         }
 
diff --git a/src/test/mir-opt/copy_propagation_arg.rs b/src/test/mir-opt/copy_propagation_arg.rs
index 017fac6a6a1..35bb231df5a 100644
--- a/src/test/mir-opt/copy_propagation_arg.rs
+++ b/src/test/mir-opt/copy_propagation_arg.rs
@@ -30,42 +30,43 @@ fn baz(mut x: i32) {
     x = x;
 }
 
+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);
 }
 
 // END RUST SOURCE
 // START rustc.foo.CopyPropagation.before.mir
 // bb0: {
-//     StorageLive(_2);
-//     StorageLive(_3);
+//     ...
 //     _3 = _1;
 //     _2 = const dummy(move _3) -> bb1;
 // }
 // bb1: {
-//     StorageDead(_3);
+//     ...
 //     _1 = move _2;
-//     StorageDead(_2);
-//     _0 = ();
-//     return;
+//     ...
 // }
 // END rustc.foo.CopyPropagation.before.mir
 // START rustc.foo.CopyPropagation.after.mir
 // bb0: {
-//     StorageLive(_2);
-//     nop;
-//     nop;
-//     _2 = const dummy(move _1) -> bb1;
+//     ...
+//     _3 = _1;
+//     _2 = const dummy(move _3) -> bb1;
 // }
 // bb1: {
-//     nop;
+//     ...
 //     _1 = move _2;
-//     StorageDead(_2);
-//     _0 = ();
-//     return;
+//     ...
 // }
 // END rustc.foo.CopyPropagation.after.mir
 // START rustc.bar.CopyPropagation.before.mir
@@ -83,15 +84,14 @@ fn main() {
 // END rustc.bar.CopyPropagation.before.mir
 // START rustc.bar.CopyPropagation.after.mir
 // bb0: {
-//     nop;
-//     nop;
-//     _2 = const dummy(move _1) -> bb1;
+//     ...
+//     _3 = _1;
+//     _2 = const dummy(move _3) -> bb1;
 // }
 // bb1: {
-//     nop;
+//     ...
 //     _1 = const 5u8;
-//     _0 = ();
-//     return;
+//     ...
 // }
 // END rustc.bar.CopyPropagation.after.mir
 // START rustc.baz.CopyPropagation.before.mir
@@ -106,11 +106,35 @@ fn main() {
 // END rustc.baz.CopyPropagation.before.mir
 // START rustc.baz.CopyPropagation.after.mir
 // bb0: {
-//     nop;
-//     nop;
-//     nop;
-//     nop;
-//     _0 = ();
-//     return;
+//     ...
+//     _2 = _1;
+//     _1 = move _2;
+//     ...
 // }
 // END rustc.baz.CopyPropagation.after.mir
+// START rustc.arg_src.CopyPropagation.before.mir
+// bb0: {
+//       ...
+//       _3 = _1;
+//       _2 = move _3;
+//       ...
+//       _1 = const 123i32;
+//       ...
+//       _4 = _2;
+//       _0 = move _4;
+//       ...
+//       return;
+//   }
+// END rustc.arg_src.CopyPropagation.before.mir
+// START rustc.arg_src.CopyPropagation.after.mir
+// bb0: {
+//     ...
+//     _3 = _1;
+//     ...
+//     _1 = const 123i32;
+//     ...
+//     _0 = move _3;
+//     ...
+//     return;
+// }
+// END rustc.arg_src.CopyPropagation.after.mir