Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Do not apply the optimization if we deref a mutable ref
  • Loading branch information
simonvandel committed Oct 27, 2020
1 parent 2a71e45 commit c19620c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 12 deletions.
44 changes: 32 additions & 12 deletions compiler/rustc_mir/src/transform/instcombine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,18 @@ impl OptimizationFinder<'b, 'tcx> {
return None;
}

self.optimizations
.unneeded_deref
.insert(location, *place_taken_address_of);
return Some(());
if place_derefs_non_mutable_ref(
place_taken_address_of,
self.body,
self.tcx,
) {
self.optimizations
.unneeded_deref
.insert(location, *place_taken_address_of);
return Some(());
}

return None;
}

// We found an assignment of `local_being_deref` that is not an immutable ref, e.g the following sequence
Expand Down Expand Up @@ -258,17 +266,29 @@ impl OptimizationFinder<'b, 'tcx> {
}
}

/// Returns whether this place derefences a type `&_`
fn place_derefs_non_mutable_ref<'tcx>(
place: &Place<'tcx>,
body: &Body<'tcx>,
tcx: TyCtxt<'tcx>,
) -> bool {
if let PlaceRef { local, projection: &[ref proj_base @ .., ProjectionElem::Deref] } =
place.as_ref()
{
let ty = Place::ty_from(local, proj_base, body, tcx).ty;
// The dereferenced place must have type `&_`.
if let ty::Ref(_, _, Mutability::Not) = ty.kind() {
return true;
}
}
return false;
}

impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
if let Rvalue::Ref(_, _, place) = rvalue {
if let PlaceRef { local, projection: &[ref proj_base @ .., ProjectionElem::Deref] } =
place.as_ref()
{
// The dereferenced place must have type `&_`.
let ty = Place::ty_from(local, proj_base, self.body, self.tcx).ty;
if let ty::Ref(_, _, Mutability::Not) = ty.kind() {
self.optimizations.and_stars.insert(location);
}
if place_derefs_non_mutable_ref(place, self.body, self.tcx) {
self.optimizations.and_stars.insert(location);
}
}

Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/mir/issue-78192.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// run-pass
// compile-flags: -Z unsound_mir_opts

#[allow(unused_assignments)]
fn main() {
let a = 1u32;
let b = 2u32;

let mut c: *const u32 = &a;
let d: &u32 = &b;

let x = unsafe { &*c };
c = d;
let z = *x;

assert_eq!(1, z);
}

0 comments on commit c19620c

Please sign in to comment.