Skip to content

Commit

Permalink
Add an InstCombine for redundant casts
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Feb 20, 2023
1 parent eebdfb5 commit 0e05280
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
9 changes: 9 additions & 0 deletions compiler/rustc_mir_transform/src/instcombine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
_ => {}
}
Expand Down Expand Up @@ -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>,
Expand Down
25 changes: 25 additions & 0 deletions tests/mir-opt/casts.redundant.InstCombine.diff
Original file line number Diff line number Diff line change
@@ -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
}
}

14 changes: 14 additions & 0 deletions tests/mir-opt/casts.redundant.PreCodegen.after.mir
Original file line number Diff line number Diff line change
@@ -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
}
}
15 changes: 15 additions & 0 deletions tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
Original file line number Diff line number Diff line change
@@ -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
}
}
17 changes: 17 additions & 0 deletions tests/mir-opt/casts.rs
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 0e05280

Please sign in to comment.