about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Kimock <kimockb@gmail.com>2023-02-19 15:50:00 -0500
committerBen Kimock <kimockb@gmail.com>2023-02-19 23:14:58 -0500
commit0e05280d75e43da007efd50ce49f4e1e8456bcbd (patch)
tree08cdddb70f0147fbb2a8e87adc88f8f1e01744ba
parenteebdfb55fce148676c24555505aebf648123b2de (diff)
downloadrust-0e05280d75e43da007efd50ce49f4e1e8456bcbd.tar.gz
rust-0e05280d75e43da007efd50ce49f4e1e8456bcbd.zip
Add an InstCombine for redundant casts
-rw-r--r--compiler/rustc_mir_transform/src/instcombine.rs9
-rw-r--r--tests/mir-opt/casts.redundant.InstCombine.diff25
-rw-r--r--tests/mir-opt/casts.redundant.PreCodegen.after.mir14
-rw-r--r--tests/mir-opt/casts.roundtrip.PreCodegen.after.mir15
-rw-r--r--tests/mir-opt/casts.rs17
5 files changed, 80 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs
index 0534e688703..3896f0e57ea 100644
--- a/compiler/rustc_mir_transform/src/instcombine.rs
+++ b/compiler/rustc_mir_transform/src/instcombine.rs
@@ -30,6 +30,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
                         ctx.combine_bool_cmp(&statement.source_info, rvalue);
                         ctx.combine_ref_deref(&statement.source_info, rvalue);
                         ctx.combine_len(&statement.source_info, rvalue);
+                        ctx.combine_cast(&statement.source_info, rvalue);
                     }
                     _ => {}
                 }
@@ -142,6 +143,14 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
         }
     }
 
+    fn combine_cast(&self, _source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+        if let Rvalue::Cast(_kind, operand, ty) = rvalue {
+            if operand.ty(self.local_decls, self.tcx) == *ty {
+                *rvalue = Rvalue::Use(operand.clone());
+            }
+        }
+    }
+
     fn combine_primitive_clone(
         &self,
         terminator: &mut Terminator<'tcx>,
diff --git a/tests/mir-opt/casts.redundant.InstCombine.diff b/tests/mir-opt/casts.redundant.InstCombine.diff
new file mode 100644
index 00000000000..528a8e5a90f
--- /dev/null
+++ b/tests/mir-opt/casts.redundant.InstCombine.diff
@@ -0,0 +1,25 @@
+- // MIR for `redundant` before InstCombine
++ // MIR for `redundant` after InstCombine
+  
+  fn redundant(_1: *const &u8) -> *const &u8 {
+      debug x => _1;                       // in scope 0 at $DIR/casts.rs:+0:30: +0:31
+      let mut _0: *const &u8;              // return place in scope 0 at $DIR/casts.rs:+0:51: +0:64
+      let mut _2: *const &u8;              // in scope 0 at $DIR/casts.rs:+1:5: +1:55
+      let mut _3: *const &u8;              // in scope 0 at $DIR/casts.rs:+1:36: +1:37
+      scope 1 (inlined generic_cast::<&u8, &u8>) { // at $DIR/casts.rs:6:5: 6:38
+          debug x => _3;                   // in scope 1 at $DIR/casts.rs:10:23: 10:24
+      }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/casts.rs:+1:5: +1:55
+          StorageLive(_3);                 // scope 0 at $DIR/casts.rs:+1:36: +1:37
+          _3 = _1;                         // scope 0 at $DIR/casts.rs:+1:36: +1:37
+-         _2 = _3 as *const &u8 (PtrToPtr); // scope 1 at $DIR/casts.rs:11:5: 11:18
++         _2 = _3;                         // scope 1 at $DIR/casts.rs:11:5: 11:18
+          StorageDead(_3);                 // scope 0 at $DIR/casts.rs:+1:37: +1:38
+          _0 = _2;                         // scope 0 at $DIR/casts.rs:+1:5: +1:55
+          StorageDead(_2);                 // scope 0 at $DIR/casts.rs:+2:1: +2:2
+          return;                          // scope 0 at $DIR/casts.rs:+2:2: +2:2
+      }
+  }
+  
diff --git a/tests/mir-opt/casts.redundant.PreCodegen.after.mir b/tests/mir-opt/casts.redundant.PreCodegen.after.mir
new file mode 100644
index 00000000000..21a470ea300
--- /dev/null
+++ b/tests/mir-opt/casts.redundant.PreCodegen.after.mir
@@ -0,0 +1,14 @@
+// MIR for `redundant` after PreCodegen
+
+fn redundant(_1: *const &u8) -> *const &u8 {
+    debug x => _1;                       // in scope 0 at $DIR/casts.rs:+0:30: +0:31
+    let mut _0: *const &u8;              // return place in scope 0 at $DIR/casts.rs:+0:51: +0:64
+    scope 1 (inlined generic_cast::<&u8, &u8>) { // at $DIR/casts.rs:6:5: 6:38
+        debug x => _1;                   // in scope 1 at $DIR/casts.rs:10:23: 10:24
+    }
+
+    bb0: {
+        _0 = _1;                         // scope 0 at $DIR/casts.rs:+1:5: +1:55
+        return;                          // scope 0 at $DIR/casts.rs:+2:2: +2:2
+    }
+}
diff --git a/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir b/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
new file mode 100644
index 00000000000..0c793984ceb
--- /dev/null
+++ b/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
@@ -0,0 +1,15 @@
+// MIR for `roundtrip` after PreCodegen
+
+fn roundtrip(_1: *const u8) -> *const u8 {
+    debug x => _1;                       // in scope 0 at $DIR/casts.rs:+0:18: +0:19
+    let mut _0: *const u8;               // return place in scope 0 at $DIR/casts.rs:+0:35: +0:44
+    let mut _2: *mut u8;                 // in scope 0 at $DIR/casts.rs:+1:5: +1:17
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/casts.rs:+1:5: +1:17
+        _2 = _1 as *mut u8 (PtrToPtr);   // scope 0 at $DIR/casts.rs:+1:5: +1:17
+        _0 = move _2 as *const u8 (Pointer(MutToConstPointer)); // scope 0 at $DIR/casts.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/casts.rs:+1:16: +1:17
+        return;                          // scope 0 at $DIR/casts.rs:+2:2: +2:2
+    }
+}
diff --git a/tests/mir-opt/casts.rs b/tests/mir-opt/casts.rs
new file mode 100644
index 00000000000..259c462da3d
--- /dev/null
+++ b/tests/mir-opt/casts.rs
@@ -0,0 +1,17 @@
+#![crate_type = "lib"]
+
+// EMIT_MIR casts.redundant.InstCombine.diff
+// EMIT_MIR casts.redundant.PreCodegen.after.mir
+pub fn redundant<'a, 'b: 'a>(x: *const &'a u8) -> *const &'a u8 {
+    generic_cast::<&'a u8, &'b u8>(x) as *const &'a u8
+}
+
+#[inline]
+fn generic_cast<T, U>(x: *const T) -> *const U {
+    x as *const U
+}
+
+// EMIT_MIR casts.roundtrip.PreCodegen.after.mir
+pub fn roundtrip(x: *const u8) -> *const u8 {
+    x as *mut u8 as *const u8
+}