diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index bd6bfe2ef791..3466248b2bf7 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -135,7 +135,7 @@ impl<'tcx> crate::MirPass<'tcx> for GVN { VnState::new(tcx, body, typing_env, &ssa, dominators, &body.local_decls, &arena); for local in body.args_iter().filter(|&local| ssa.is_ssa(local)) { - let opaque = state.new_opaque(body.local_decls[local].ty); + let opaque = state.new_argument(body.local_decls[local].ty); state.assign(local, opaque); } @@ -198,8 +198,9 @@ enum AddressBase { enum Value<'a, 'tcx> { // Root values. /// Used to represent values we know nothing about. - /// The `usize` is a counter incremented by `new_opaque`. Opaque(VnOpaque), + /// The value is a argument. + Argument(VnOpaque), /// Evaluated or unevaluated constant value. Constant { value: Const<'tcx>, @@ -284,7 +285,7 @@ impl<'a, 'tcx> ValueSet<'a, 'tcx> { let value = value(VnOpaque); debug_assert!(match value { - Value::Opaque(_) | Value::Address { .. } => true, + Value::Opaque(_) | Value::Argument(_) | Value::Address { .. } => true, Value::Constant { disambiguator, .. } => disambiguator.is_some(), _ => false, }); @@ -440,6 +441,13 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { index } + #[instrument(level = "trace", skip(self), ret)] + fn new_argument(&mut self, ty: Ty<'tcx>) -> VnIndex { + let index = self.insert_unique(ty, Value::Argument); + self.evaluated[index] = Some(None); + index + } + /// Create a new `Value::Address` distinct from all the others. #[instrument(level = "trace", skip(self), ret)] fn new_pointer(&mut self, place: Place<'tcx>, kind: AddressKind) -> Option { @@ -457,8 +465,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { // Skip the initial `Deref`. projection.next(); AddressBase::Deref(base) - } else { + } else if self.ssa.is_ssa(place.local) { + // Only propagate the pointer of the SSA local. AddressBase::Local(place.local) + } else { + return None; }; // Do not try evaluating inside `Index`, this has been done by `simplify_place_projection`. let projection = @@ -526,10 +537,6 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { self.insert(ty, Value::Aggregate(VariantIdx::ZERO, self.arena.alloc_slice(values))) } - fn insert_deref(&mut self, ty: Ty<'tcx>, value: VnIndex) -> VnIndex { - self.insert(ty, Value::Projection(value, ProjectionElem::Deref)) - } - #[instrument(level = "trace", skip(self), ret)] fn eval_to_const_inner(&mut self, value: VnIndex) -> Option> { use Value::*; @@ -543,7 +550,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { let op = match self.get(value) { _ if ty.is_zst() => ImmTy::uninit(ty).into(), - Opaque(_) => return None, + Opaque(_) | Argument(_) => return None, // Keep runtime check constants as symbolic. RuntimeChecks(..) => return None, @@ -795,7 +802,9 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { // An immutable borrow `_x` always points to the same value for the // lifetime of the borrow, so we can merge all instances of `*_x`. - return Some((projection_ty, self.insert_deref(projection_ty.ty, value))); + let deref = self + .insert(projection_ty.ty, Value::Projection(value, ProjectionElem::Deref)); + return Some((projection_ty, deref)); } else { return None; } @@ -1014,7 +1023,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { let op = self.simplify_operand(op, location)?; Value::Repeat(op, amount) } - Rvalue::Aggregate(..) => return self.simplify_aggregate(lhs, rvalue, location), + Rvalue::Aggregate(..) => return self.simplify_aggregate(rvalue, location), Rvalue::Ref(_, borrow_kind, ref mut place) => { self.simplify_place_projection(place, location); return self.new_pointer(*place, AddressKind::Ref(borrow_kind)); @@ -1125,7 +1134,6 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { fn simplify_aggregate( &mut self, - lhs: &Place<'tcx>, rvalue: &mut Rvalue<'tcx>, location: Location, ) -> Option { @@ -1208,12 +1216,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { } if let Some(value) = self.simplify_aggregate_to_copy(ty, variant_index, &fields) { - // Allow introducing places with non-constant offsets, as those are still better than - // reconstructing an aggregate. But avoid creating `*a = copy (*b)`, as they might be - // aliases resulting in overlapping assignments. - let allow_complex_projection = - lhs.projection[..].iter().all(PlaceElem::is_stable_offset); - if let Some(place) = self.try_as_place(value, location, allow_complex_projection) { + if let Some(place) = self.try_as_place(value, location, true) { self.reused_locals.insert(place.local); *rvalue = Rvalue::Use(Operand::Copy(place)); } @@ -1867,6 +1870,17 @@ impl<'tcx> VnState<'_, '_, 'tcx> { && (allow_complex_projection || proj.is_stable_offset()) && let Some(proj) = self.try_as_place_elem(self.ty(index), proj, loc) { + if proj == PlaceElem::Deref { + // We can introduce a new dereference if the source value cannot be changed in the body. + // Dereferencing an immutable argument always gives the same value in the body. + match self.get(pointer) { + Value::Argument(_) + if let Some(Mutability::Not) = self.ty(pointer).ref_mutability() => {} + _ => { + return None; + } + } + } projection.push(proj); index = pointer; } else { diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index cde4d281f687..f3ccc66cdc95 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -75,8 +75,7 @@ bb0: { StorageLive(_1); -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = (); @@ -144,12 +143,10 @@ StorageDead(_4); _2 = &_3; _1 = &(*_2); -- StorageDead(_2); + StorageDead(_2); - StorageLive(_5); -- _10 = copy (*_1); + nop; -+ nop; -+ _10 = copy (*_2); + _10 = copy (*_1); _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _5 = &raw const (*_11); - StorageLive(_6); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff index 82a14a8b6ec9..9a354fc005ed 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff @@ -37,8 +37,7 @@ bb0: { StorageLive(_1); -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = (); @@ -51,12 +50,10 @@ StorageDead(_4); _2 = &_3; _1 = &(*_2); -- StorageDead(_2); + StorageDead(_2); - StorageLive(_5); -- _10 = copy (*_1); + nop; -+ nop; -+ _10 = copy (*_2); + _10 = copy (*_1); _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _5 = &raw const (*_11); - StorageLive(_6); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index ea5622eb9a2f..f8d781bb706f 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -75,8 +75,7 @@ bb0: { StorageLive(_1); -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = (); @@ -144,12 +143,10 @@ StorageDead(_4); _2 = &_3; _1 = &(*_2); -- StorageDead(_2); + StorageDead(_2); - StorageLive(_5); -- _10 = copy (*_1); + nop; -+ nop; -+ _10 = copy (*_2); + _10 = copy (*_1); _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _5 = &raw const (*_11); - StorageLive(_6); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff index 82a14a8b6ec9..9a354fc005ed 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff @@ -37,8 +37,7 @@ bb0: { StorageLive(_1); -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = (); @@ -51,12 +50,10 @@ StorageDead(_4); _2 = &_3; _1 = &(*_2); -- StorageDead(_2); + StorageDead(_2); - StorageLive(_5); -- _10 = copy (*_1); + nop; -+ nop; -+ _10 = copy (*_2); + _10 = copy (*_1); _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _5 = &raw const (*_11); - StorageLive(_6); diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff index ecd7bdc433cd..a763614dc644 100644 --- a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff @@ -107,18 +107,23 @@ StorageLive(_18); _18 = &(*_1); StorageLive(_19); - StorageLive(_20); +- StorageLive(_20); ++ nop; _20 = copy (*_18); - _19 = opaque::(move _20) -> [return: bb7, unwind unreachable]; +- _19 = opaque::(move _20) -> [return: bb7, unwind unreachable]; ++ _19 = opaque::(copy _20) -> [return: bb7, unwind unreachable]; } bb7: { - StorageDead(_20); +- StorageDead(_20); ++ nop; StorageDead(_19); StorageLive(_21); StorageLive(_22); - _22 = copy (*_18); - _21 = opaque::(move _22) -> [return: bb8, unwind unreachable]; +- _22 = copy (*_18); +- _21 = opaque::(move _22) -> [return: bb8, unwind unreachable]; ++ _22 = copy _20; ++ _21 = opaque::(copy _20) -> [return: bb8, unwind unreachable]; } bb8: { @@ -152,18 +157,23 @@ StorageDead(_28); StorageDead(_27); StorageLive(_29); - StorageLive(_30); +- StorageLive(_30); ++ nop; _30 = copy ((*_3).0: u32); - _29 = opaque::(move _30) -> [return: bb12, unwind unreachable]; +- _29 = opaque::(move _30) -> [return: bb12, unwind unreachable]; ++ _29 = opaque::(copy _30) -> [return: bb12, unwind unreachable]; } bb12: { - StorageDead(_30); +- StorageDead(_30); ++ nop; StorageDead(_29); StorageLive(_31); StorageLive(_32); - _32 = copy ((*_3).0: u32); - _31 = opaque::(move _32) -> [return: bb13, unwind unreachable]; +- _32 = copy ((*_3).0: u32); +- _31 = opaque::(move _32) -> [return: bb13, unwind unreachable]; ++ _32 = copy _30; ++ _31 = opaque::(copy _30) -> [return: bb13, unwind unreachable]; } bb13: { diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff index bbca6bc3c754..ca6fda483642 100644 --- a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff @@ -107,18 +107,23 @@ StorageLive(_18); _18 = &(*_1); StorageLive(_19); - StorageLive(_20); +- StorageLive(_20); ++ nop; _20 = copy (*_18); - _19 = opaque::(move _20) -> [return: bb7, unwind continue]; +- _19 = opaque::(move _20) -> [return: bb7, unwind continue]; ++ _19 = opaque::(copy _20) -> [return: bb7, unwind continue]; } bb7: { - StorageDead(_20); +- StorageDead(_20); ++ nop; StorageDead(_19); StorageLive(_21); StorageLive(_22); - _22 = copy (*_18); - _21 = opaque::(move _22) -> [return: bb8, unwind continue]; +- _22 = copy (*_18); +- _21 = opaque::(move _22) -> [return: bb8, unwind continue]; ++ _22 = copy _20; ++ _21 = opaque::(copy _20) -> [return: bb8, unwind continue]; } bb8: { @@ -152,18 +157,23 @@ StorageDead(_28); StorageDead(_27); StorageLive(_29); - StorageLive(_30); +- StorageLive(_30); ++ nop; _30 = copy ((*_3).0: u32); - _29 = opaque::(move _30) -> [return: bb12, unwind continue]; +- _29 = opaque::(move _30) -> [return: bb12, unwind continue]; ++ _29 = opaque::(copy _30) -> [return: bb12, unwind continue]; } bb12: { - StorageDead(_30); +- StorageDead(_30); ++ nop; StorageDead(_29); StorageLive(_31); StorageLive(_32); - _32 = copy ((*_3).0: u32); - _31 = opaque::(move _32) -> [return: bb13, unwind continue]; +- _32 = copy ((*_3).0: u32); +- _31 = opaque::(move _32) -> [return: bb13, unwind continue]; ++ _32 = copy _30; ++ _31 = opaque::(copy _30) -> [return: bb13, unwind continue]; } bb13: { diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff index a29d3331f380..96920af4dddc 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:618:19: 618:21}; + let mut _9: {closure@$DIR/gvn.rs:629:19: 629:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:618:19: 618:21}; + let mut _13: {closure@$DIR/gvn.rs:629:19: 629:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:618:19: 618:21}; + let _7: {closure@$DIR/gvn.rs:629:19: 629:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:618:19: 618:21}; +- _7 = {closure@$DIR/gvn.rs:629:19: 629:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21}; + nop; StorageLive(_9); - _9 = copy _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = copy _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff index b716fcd4e74b..d32a82322203 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:618:19: 618:21}; + let mut _9: {closure@$DIR/gvn.rs:629:19: 629:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:618:19: 618:21}; + let mut _13: {closure@$DIR/gvn.rs:629:19: 629:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:618:19: 618:21}; + let _7: {closure@$DIR/gvn.rs:629:19: 629:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:618:19: 618:21}; +- _7 = {closure@$DIR/gvn.rs:629:19: 629:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21}; + nop; StorageLive(_9); - _9 = copy _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = copy _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:629:19: 629:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 837e8ac4d9e3..ad2826c3cb04 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -100,14 +100,14 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) { opaque((x * y) - y); opaque((x * y) - y); - // We cannot substitute through an immutable reference. + // We can substitute through an immutable reference. // CHECK: [[ref:_.*]] = &_3; // CHECK: [[deref:_.*]] = copy (*[[ref]]); - // CHECK: [[addref:_.*]] = Add(move [[deref]], copy _1); - // CHECK: opaque::(move [[addref]]) - // CHECK: [[deref2:_.*]] = copy (*[[ref]]); - // CHECK: [[addref2:_.*]] = Add(move [[deref2]], copy _1); - // CHECK: opaque::(move [[addref2]]) + // CHECK: [[addref:_.*]] = Add(copy [[deref]], copy _1); + // CHECK: opaque::(copy [[addref]]) + // CHECK: [[deref2:_.*]] = copy [[deref]]; + // CHECK: [[addref2:_.*]] = copy [[addref]]; + // CHECK: opaque::(copy [[addref]]) let a = &z; opaque(*a + x); opaque(*a + x); @@ -140,15 +140,14 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) { opaque(*d + x); } - // We still cannot substitute again, and never with the earlier computations. // Important: `e` is not `a`! // CHECK: [[ref2:_.*]] = &_3; // CHECK: [[deref2:_.*]] = copy (*[[ref2]]); - // CHECK: [[addref2:_.*]] = Add(move [[deref2]], copy _1); - // CHECK: opaque::(move [[addref2]]) - // CHECK: [[deref3:_.*]] = copy (*[[ref2]]); - // CHECK: [[addref3:_.*]] = Add(move [[deref3]], copy _1); - // CHECK: opaque::(move [[addref3]]) + // CHECK: [[addref2:_.*]] = Add(copy [[deref2]], copy _1); + // CHECK: opaque::(copy [[addref2]]) + // CHECK: [[deref3:_.*]] = copy [[deref2]]; + // CHECK: [[addref3:_.*]] = copy [[addref2]]; + // CHECK: opaque::(copy [[addref2]]) let e = &z; opaque(*e + x); opaque(*e + x); @@ -452,20 +451,21 @@ fn references(mut x: impl Sized) { // CHECK: opaque::<*mut impl Sized>(move [[ref8]]) opaque(&raw mut x); + // FIXME: ReferencePropagation transform this pattern. let r = &mut x; let s = S(r).0; // Obfuscate `r`. Following lines should still reborrow `r`. // CHECK: [[ref9:_.*]] = &mut _1; - // CHECK: [[ref10:_.*]] = &(*[[ref9]]); - // CHECK: opaque::<&impl Sized>(move [[ref10]]) + // COM: CHECK: [[ref10:_.*]] = &(*[[ref9]]); + // COM: CHECK: opaque::<&impl Sized>(move [[ref10]]) opaque(&*s); - // CHECK: [[ref11:_.*]] = &mut (*[[ref9]]); - // CHECK: opaque::<&mut impl Sized>(move [[ref11]]) + // COM: CHECK: [[ref11:_.*]] = &mut (*[[ref9]]); + // COM: CHECK: opaque::<&mut impl Sized>(move [[ref11]]) opaque(&mut *s); - // CHECK: [[ref12:_.*]] = &raw const (*[[ref9]]); - // CHECK: opaque::<*const impl Sized>(move [[ref12]]) + // COM: CHECK: [[ref12:_.*]] = &raw const (*[[ref9]]); + // COM: CHECK: opaque::<*const impl Sized>(move [[ref12]]) opaque(&raw const *s); - // CHECK: [[ref12:_.*]] = &raw mut (*[[ref9]]); - // CHECK: opaque::<*mut impl Sized>(move [[ref12]]) + // COM: CHECK: [[ref12:_.*]] = &raw mut (*[[ref9]]); + // COM: CHECK: opaque::<*mut impl Sized>(move [[ref12]]) opaque(&raw mut *s); } @@ -473,17 +473,21 @@ fn dereferences(t: &mut u32, u: &impl Copy, s: &S) { // CHECK-LABEL: fn dereferences( // Do not reuse dereferences of `&mut`. + // CHECK: bb0: // CHECK: [[st1:_.*]] = copy (*_1); // CHECK: opaque::(move [[st1]]) + // CHECK: bb1: // CHECK: [[st2:_.*]] = copy (*_1); // CHECK: opaque::(move [[st2]]) opaque(*t); opaque(*t); // Do not reuse dereferences of `*const`. + // CHECK: bb2: // CHECK: [[raw:_.*]] = &raw const (*_1); // CHECK: [[st3:_.*]] = copy (*[[raw]]); // CHECK: opaque::(move [[st3]]) + // CHECK: bb3: // CHECK: [[st4:_.*]] = copy (*[[raw]]); // CHECK: opaque::(move [[st4]]) let z = &raw const *t; @@ -491,42 +495,49 @@ fn dereferences(t: &mut u32, u: &impl Copy, s: &S) { unsafe { opaque(*z) }; // Do not reuse dereferences of `*mut`. + // CHECK: bb4: // CHECK: [[ptr:_.*]] = &raw mut (*_1); // CHECK: [[st5:_.*]] = copy (*[[ptr]]); // CHECK: opaque::(move [[st5]]) + // CHECK: bb5: // CHECK: [[st6:_.*]] = copy (*[[ptr]]); // CHECK: opaque::(move [[st6]]) let z = &raw mut *t; unsafe { opaque(*z) }; unsafe { opaque(*z) }; - // Do not reuse dereferences of `&Freeze`. + // CHECK: bb6: // CHECK: [[ref:_.*]] = &(*_1); // CHECK: [[st7:_.*]] = copy (*[[ref]]); - // CHECK: opaque::(move [[st7]]) - // CHECK: [[st8:_.*]] = copy (*[[ref]]); - // CHECK: opaque::(move [[st8]]) + // CHECK: opaque::(copy [[st7]]) + // CHECK: bb7: + // CHECK: [[st8:_.*]] = copy [[st7]]; + // CHECK: opaque::(copy [[st7]]) let z = &*t; opaque(*z); opaque(*z); // Not in reborrows either. + // CHECK: bb8: // CHECK: [[reborrow:_.*]] = &(*[[ref]]); // CHECK: opaque::<&u32>(move [[reborrow]]) opaque(&*z); // `*u` is not Freeze, so we cannot reuse. + // CHECK: bb9: // CHECK: [[st8:_.*]] = copy (*_2); // CHECK: opaque::(move [[st8]]) + // CHECK: bb10: // CHECK: [[st9:_.*]] = copy (*_2); // CHECK: opaque::(move [[st9]]) opaque(*u); opaque(*u); - // `*s` is not Copy, but `(*s).0` is, but we still cannot reuse. + // CHECK: bb11: // CHECK: [[st10:_.*]] = copy ((*_3).0: u32); - // CHECK: opaque::(move [[st10]]) - // CHECK: [[st11:_.*]] = copy ((*_3).0: u32); - // CHECK: opaque::(move [[st11]]) + // CHECK: opaque::(copy [[st10]]) + // CHECK: bb12: + // CHECK: [[st11:_.*]] = copy [[st10]]; + // CHECK: opaque::(copy [[st10]]) opaque(s.0); opaque(s.0); } diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff index e872e011542b..7a479bc55da7 100644 --- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff @@ -758,32 +758,39 @@ StorageLive(_126); _126 = &_3; StorageLive(_127); - StorageLive(_128); - StorageLive(_129); +- StorageLive(_128); +- StorageLive(_129); ++ nop; ++ nop; _129 = copy (*_126); StorageLive(_130); _130 = copy _1; - _128 = Add(move _129, move _130); -+ _128 = Add(move _129, copy _1); ++ _128 = Add(copy _129, copy _1); StorageDead(_130); - StorageDead(_129); - _127 = opaque::(move _128) -> [return: bb35, unwind unreachable]; +- StorageDead(_129); +- _127 = opaque::(move _128) -> [return: bb35, unwind unreachable]; ++ nop; ++ _127 = opaque::(copy _128) -> [return: bb35, unwind unreachable]; } bb35: { - StorageDead(_128); +- StorageDead(_128); ++ nop; StorageDead(_127); StorageLive(_131); StorageLive(_132); StorageLive(_133); - _133 = copy (*_126); +- _133 = copy (*_126); ++ _133 = copy _129; StorageLive(_134); _134 = copy _1; - _132 = Add(move _133, move _134); -+ _132 = Add(move _133, copy _1); ++ _132 = copy _128; StorageDead(_134); StorageDead(_133); - _131 = opaque::(move _132) -> [return: bb36, unwind unreachable]; +- _131 = opaque::(move _132) -> [return: bb36, unwind unreachable]; ++ _131 = opaque::(copy _128) -> [return: bb36, unwind unreachable]; } bb36: { @@ -899,32 +906,39 @@ StorageLive(_163); _163 = &_3; StorageLive(_164); - StorageLive(_165); - StorageLive(_166); +- StorageLive(_165); +- StorageLive(_166); ++ nop; ++ nop; _166 = copy (*_163); StorageLive(_167); _167 = copy _1; - _165 = Add(move _166, move _167); -+ _165 = Add(move _166, copy _1); ++ _165 = Add(copy _166, copy _1); StorageDead(_167); - StorageDead(_166); - _164 = opaque::(move _165) -> [return: bb43, unwind unreachable]; +- StorageDead(_166); +- _164 = opaque::(move _165) -> [return: bb43, unwind unreachable]; ++ nop; ++ _164 = opaque::(copy _165) -> [return: bb43, unwind unreachable]; } bb43: { - StorageDead(_165); +- StorageDead(_165); ++ nop; StorageDead(_164); StorageLive(_168); StorageLive(_169); StorageLive(_170); - _170 = copy (*_163); +- _170 = copy (*_163); ++ _170 = copy _166; StorageLive(_171); _171 = copy _1; - _169 = Add(move _170, move _171); -+ _169 = Add(move _170, copy _1); ++ _169 = copy _165; StorageDead(_171); StorageDead(_170); - _168 = opaque::(move _169) -> [return: bb44, unwind unreachable]; +- _168 = opaque::(move _169) -> [return: bb44, unwind unreachable]; ++ _168 = opaque::(copy _165) -> [return: bb44, unwind unreachable]; } bb44: { diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff index 3996dab27a34..3ca5238663c2 100644 --- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff @@ -758,32 +758,39 @@ StorageLive(_126); _126 = &_3; StorageLive(_127); - StorageLive(_128); - StorageLive(_129); +- StorageLive(_128); +- StorageLive(_129); ++ nop; ++ nop; _129 = copy (*_126); StorageLive(_130); _130 = copy _1; - _128 = Add(move _129, move _130); -+ _128 = Add(move _129, copy _1); ++ _128 = Add(copy _129, copy _1); StorageDead(_130); - StorageDead(_129); - _127 = opaque::(move _128) -> [return: bb35, unwind continue]; +- StorageDead(_129); +- _127 = opaque::(move _128) -> [return: bb35, unwind continue]; ++ nop; ++ _127 = opaque::(copy _128) -> [return: bb35, unwind continue]; } bb35: { - StorageDead(_128); +- StorageDead(_128); ++ nop; StorageDead(_127); StorageLive(_131); StorageLive(_132); StorageLive(_133); - _133 = copy (*_126); +- _133 = copy (*_126); ++ _133 = copy _129; StorageLive(_134); _134 = copy _1; - _132 = Add(move _133, move _134); -+ _132 = Add(move _133, copy _1); ++ _132 = copy _128; StorageDead(_134); StorageDead(_133); - _131 = opaque::(move _132) -> [return: bb36, unwind continue]; +- _131 = opaque::(move _132) -> [return: bb36, unwind continue]; ++ _131 = opaque::(copy _128) -> [return: bb36, unwind continue]; } bb36: { @@ -899,32 +906,39 @@ StorageLive(_163); _163 = &_3; StorageLive(_164); - StorageLive(_165); - StorageLive(_166); +- StorageLive(_165); +- StorageLive(_166); ++ nop; ++ nop; _166 = copy (*_163); StorageLive(_167); _167 = copy _1; - _165 = Add(move _166, move _167); -+ _165 = Add(move _166, copy _1); ++ _165 = Add(copy _166, copy _1); StorageDead(_167); - StorageDead(_166); - _164 = opaque::(move _165) -> [return: bb43, unwind continue]; +- StorageDead(_166); +- _164 = opaque::(move _165) -> [return: bb43, unwind continue]; ++ nop; ++ _164 = opaque::(copy _165) -> [return: bb43, unwind continue]; } bb43: { - StorageDead(_165); +- StorageDead(_165); ++ nop; StorageDead(_164); StorageLive(_168); StorageLive(_169); StorageLive(_170); - _170 = copy (*_163); +- _170 = copy (*_163); ++ _170 = copy _166; StorageLive(_171); _171 = copy _1; - _169 = Add(move _170, move _171); -+ _169 = Add(move _170, copy _1); ++ _169 = copy _165; StorageDead(_171); StorageDead(_170); - _168 = opaque::(move _169) -> [return: bb44, unwind continue]; +- _168 = opaque::(move _169) -> [return: bb44, unwind continue]; ++ _168 = opaque::(copy _165) -> [return: bb44, unwind continue]; } bb44: { diff --git a/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff index eed8cb7d62e7..a44968a43e5d 100644 --- a/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff +++ b/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff @@ -47,7 +47,7 @@ StorageLive(_7); _7 = copy _4; - _0 = AllCopy { a: move _5, b: move _6, c: move _7 }; -+ _0 = copy (*_8); ++ _0 = AllCopy { a: copy _2, b: copy _3, c: copy _4 }; StorageDead(_7); StorageDead(_6); StorageDead(_5); diff --git a/tests/mir-opt/gvn_copy_aggregate.all_copy_mut.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.all_copy_mut.GVN.diff new file mode 100644 index 000000000000..92c9db1b3d79 --- /dev/null +++ b/tests/mir-opt/gvn_copy_aggregate.all_copy_mut.GVN.diff @@ -0,0 +1,61 @@ +- // MIR for `all_copy_mut` before GVN ++ // MIR for `all_copy_mut` after GVN + + fn all_copy_mut(_1: &mut AllCopy) -> AllCopy { + debug mut_v => _1; + let mut _0: AllCopy; + let _2: &AllCopy; + let mut _6: i32; + let mut _7: u64; + let mut _8: [i8; 3]; + scope 1 { + debug v => _2; + let _3: i32; + scope 2 { + debug a => _3; + let _4: u64; + scope 3 { + debug b => _4; + let _5: [i8; 3]; + scope 4 { + debug c => _5; + } + } + } + } + + bb0: { + StorageLive(_2); + _2 = &(*_1); +- StorageLive(_3); ++ nop; + _3 = copy ((*_2).0: i32); +- StorageLive(_4); ++ nop; + _4 = copy ((*_2).1: u64); +- StorageLive(_5); ++ nop; + _5 = copy ((*_2).2: [i8; 3]); + ((*_1).0: i32) = const 0_i32; + StorageLive(_6); + _6 = copy _3; + StorageLive(_7); + _7 = copy _4; + StorageLive(_8); + _8 = copy _5; +- _0 = AllCopy { a: move _6, b: move _7, c: move _8 }; ++ _0 = AllCopy { a: copy _3, b: copy _4, c: copy _5 }; + StorageDead(_8); + StorageDead(_7); + StorageDead(_6); +- StorageDead(_5); +- StorageDead(_4); +- StorageDead(_3); ++ nop; ++ nop; ++ nop; + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/gvn_copy_aggregate.deref_nonssa.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa.GVN.diff index d17213993282..d9707e40c0bd 100644 --- a/tests/mir-opt/gvn_copy_aggregate.deref_nonssa.GVN.diff +++ b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa.GVN.diff @@ -21,9 +21,8 @@ bb0: { StorageLive(_1); - _1 = Single(const 0_u8); -- StorageLive(_2); + _1 = const Single(0_u8); -+ nop; + StorageLive(_2); _2 = &_1; - StorageLive(_3); + nop; @@ -37,12 +36,11 @@ StorageLive(_5); _5 = copy _3; - _0 = Single(move _5); -+ _0 = copy (*_2); ++ _0 = Single(copy _3); StorageDead(_5); - StorageDead(_3); -- StorageDead(_2); -+ nop; + nop; + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff index 64d137bfc26b..0dea89020e85 100644 --- a/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff +++ b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff @@ -7,7 +7,7 @@ let mut _3: &Single; let _4: &Single; let mut _7: Single; - let mut _9: u8; + let mut _8: u8; scope 1 { debug a => _1; let _2: SingleRef<'_>; @@ -19,10 +19,6 @@ let _6: u8; scope 4 { debug c => _6; - let _8: Single; - scope 5 { - debug d => _8; - } } } } @@ -34,24 +30,22 @@ + _1 = const Single(0_u8); StorageLive(_2); - StorageLive(_3); -- StorageLive(_4); -+ nop; + nop; + StorageLive(_4); _4 = &_1; _3 = &(*_4); - _2 = SingleRef::<'_>(move _3); - StorageDead(_3); -- StorageDead(_4); + _2 = SingleRef::<'_>(copy _3); + nop; -+ nop; + StorageDead(_4); StorageLive(_5); - _5 = copy (_2.0: &Single); - StorageLive(_6); - _6 = copy ((*_5).0: u8); + _5 = copy _3; + nop; -+ _6 = copy ((*_4).0: u8); ++ _6 = copy ((*_3).0: u8); StorageLive(_7); - _7 = Single(const 1_u8); - _1 = move _7; @@ -59,12 +53,9 @@ + _1 = const Single(1_u8); StorageDead(_7); StorageLive(_8); - StorageLive(_9); - _9 = copy _6; -- _8 = Single(move _9); -+ _8 = copy (*_4); - StorageDead(_9); - _0 = move _8; + _8 = copy _6; +- _0 = Single(move _8); ++ _0 = Single(copy _6); StorageDead(_8); - StorageDead(_6); + nop; diff --git a/tests/mir-opt/gvn_copy_aggregate.rs b/tests/mir-opt/gvn_copy_aggregate.rs index af1839fd3efc..c96138824154 100644 --- a/tests/mir-opt/gvn_copy_aggregate.rs +++ b/tests/mir-opt/gvn_copy_aggregate.rs @@ -24,13 +24,25 @@ fn all_copy(v: &AllCopy) -> AllCopy { AllCopy { a, b, c } } +// EMIT_MIR gvn_copy_aggregate.all_copy_mut.GVN.diff +fn all_copy_mut(mut_v: &mut AllCopy) -> AllCopy { + // CHECK-LABEL: fn all_copy_mut( + // CHECK: = AllCopy { {{.*}} }; + // CHECK-NOT: _0 = copy ({{.*}}); + let v = &*mut_v; + let a = v.a; + let b = v.b; + let c = v.c; + mut_v.a = 0; + AllCopy { a, b, c } +} + +// Nested references may be modified. // EMIT_MIR gvn_copy_aggregate.all_copy_2.GVN.diff fn all_copy_2(v: &&AllCopy) -> AllCopy { // CHECK-LABEL: fn all_copy_2( // CHECK: bb0: { - // CHECK-NOT: = AllCopy { {{.*}} }; - // CHECK: [[V1:_.*]] = copy (*_1); - // CHECK: _0 = copy (*[[V1]]); + // CHECK: _0 = AllCopy { {{.*}} }; let a = v.a; let b = v.b; let c = v.c; @@ -264,6 +276,8 @@ pub struct Single(u8); // EMIT_MIR gvn_copy_aggregate.deref_nonssa.GVN.diff fn deref_nonssa() -> Single { + // CHECK-LABEL: fn deref_nonssa( + // CHECK: _0 = Single(copy {{.*}}); let mut a = Single(0); let b = &a; let c = (*b).0; @@ -276,11 +290,12 @@ pub struct SingleRef<'a>(&'a Single); // EMIT_MIR gvn_copy_aggregate.deref_nonssa_2.GVN.diff pub fn deref_nonssa_2() -> Single { + // CHECK-LABEL: fn deref_nonssa_2( + // CHECK: _0 = Single(copy {{.*}}); let mut a = Single(0); let r = SingleRef(&a); let b = r.0; let c = (*b).0; a = Single(1); - let d = Single(c); - d + Single(c) } diff --git a/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff b/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff index e5d719cf3ca9..589cfd2a3cf1 100644 --- a/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff +++ b/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff @@ -17,7 +17,7 @@ let mut _15: !; let mut _16: Value; scope 1 { - debug val_alias => _2; + debug val_alias => _3; let mut _5: bool; scope 2 { debug stop => _5; @@ -33,23 +33,16 @@ } bb0: { - StorageLive(_2); -- StorageLive(_3); -+ nop; StorageLive(_4); _4 = &(*_1); - _3 = get::(move _4) -> [return: bb1, unwind unreachable]; + _3 = get::(copy _4) -> [return: bb1, unwind unreachable]; } bb1: { - _2 = &(*_3); StorageDead(_4); -- StorageDead(_3); -+ nop; StorageLive(_5); _5 = const false; -- _8 = discriminant((*_2)); -+ _8 = discriminant((*_3)); + _8 = discriminant((*_3)); switchInt(move _8) -> [0: bb3, otherwise: bb2]; } @@ -59,10 +52,8 @@ bb3: { - StorageLive(_7); -- _7 = copy (((*_2) as V0).0: i32); + nop; -+ _7 = copy (((*_3) as V0).0: i32); - StorageLive(_9); + _7 = copy (((*_3) as V0).0: i32); goto -> bb4; } @@ -73,7 +64,6 @@ - _11 = Value::V0(move _12); + _11 = Value::V0(copy _7); StorageDead(_12); - StorageLive(_13); StorageLive(_14); _14 = copy _5; switchInt(move _14) -> [0: bb6, otherwise: bb5]; @@ -82,20 +72,15 @@ bb5: { _0 = move _11; StorageDead(_14); - StorageDead(_13); StorageDead(_11); - StorageDead(_9); - StorageDead(_7); + nop; StorageDead(_5); - StorageDead(_2); return; } bb6: { - _13 = const (); StorageDead(_14); - StorageDead(_13); _5 = const true; StorageLive(_16); - _16 = Value::V1; @@ -103,7 +88,6 @@ + _16 = const Value::V1; + (*_1) = const Value::V1; StorageDead(_16); - _10 = const (); StorageDead(_11); goto -> bb4; } diff --git a/tests/mir-opt/gvn_loop.rs b/tests/mir-opt/gvn_loop.rs index ce23f7930f1b..d51baf46302f 100644 --- a/tests/mir-opt/gvn_loop.rs +++ b/tests/mir-opt/gvn_loop.rs @@ -1,5 +1,5 @@ //@ test-mir-pass: GVN -//@ compile-flags: -Zdump-mir-exclude-alloc-bytes +//@ compile-flags: -Zdump-mir-exclude-alloc-bytes -Zmir-enable-passes=+ReferencePropagation #![crate_type = "lib"] #![feature(core_intrinsics, rustc_attrs)] diff --git a/tests/mir-opt/gvn_overlapping.copy_overlapping.GVN.diff b/tests/mir-opt/gvn_overlapping.copy_overlapping.GVN.diff index f13c92e4fd01..7b7537bc9b40 100644 --- a/tests/mir-opt/gvn_overlapping.copy_overlapping.GVN.diff +++ b/tests/mir-opt/gvn_overlapping.copy_overlapping.GVN.diff @@ -11,8 +11,7 @@ ((_1 as variant#1).0: u32) = const 0_u32; _3 = &_1; _2 = copy (((*_3) as variant#1).0: u32); -- _1 = Adt::Some(copy _2); -+ _1 = copy (*_3); + _1 = Adt::Some(copy _2); return; } } diff --git a/tests/mir-opt/gvn_overlapping.overlapping.GVN.diff b/tests/mir-opt/gvn_overlapping.overlapping.GVN.diff index fcabcdbcfef2..efebdf53c292 100644 --- a/tests/mir-opt/gvn_overlapping.overlapping.GVN.diff +++ b/tests/mir-opt/gvn_overlapping.overlapping.GVN.diff @@ -3,12 +3,12 @@ fn overlapping(_1: Adt) -> () { let mut _0: (); - let mut _2: *mut Adt; + let mut _2: &mut Adt; let mut _3: u32; let mut _4: &Adt; bb0: { - _2 = &raw mut _1; + _2 = &mut _1; _4 = &(*_2); _3 = copy (((*_4) as variant#1).0: u32); (*_2) = Adt::Some(copy _3); diff --git a/tests/mir-opt/gvn_overlapping.rs b/tests/mir-opt/gvn_overlapping.rs index a41f8ad5fd60..bd93787cb483 100644 --- a/tests/mir-opt/gvn_overlapping.rs +++ b/tests/mir-opt/gvn_overlapping.rs @@ -7,19 +7,19 @@ use std::intrinsics::mir::*; // EMIT_MIR gvn_overlapping.overlapping.GVN.diff /// Check that we do not create overlapping assignments. #[custom_mir(dialect = "runtime")] -fn overlapping(_17: Adt) { +fn overlapping(_1: Adt) { // CHECK-LABEL: fn overlapping( - // CHECK: let mut [[PTR:.*]]: *mut Adt; + // CHECK: let mut [[PTR:.*]]: &mut Adt; // CHECK: (*[[PTR]]) = Adt::Some(copy {{.*}}); mir! { - let _33: *mut Adt; - let _48: u32; - let _73: &Adt; + let _2: &mut Adt; + let _3: u32; + let _4: &Adt; { - _33 = core::ptr::addr_of_mut!(_17); - _73 = &(*_33); - _48 = Field(Variant((*_73), 1), 0); - (*_33) = Adt::Some(_48); + _2 = &mut _1; + _4 = &(*_2); + _3 = Field(Variant((*_4), 1), 0); + (*_2) = Adt::Some(_3); Return() } } @@ -30,18 +30,19 @@ fn overlapping(_17: Adt) { #[custom_mir(dialect = "runtime")] fn stable_projection(_1: (Adt,)) { // CHECK-LABEL: fn stable_projection( - // CHECK: let mut _2: *mut Adt; + // CHECK: let mut _2: &Adt; // CHECK: let mut _4: &Adt; - // CHECK: (_1.0: Adt) = copy (*_4); + // CHECK: (_5.0: Adt) = copy (_1.0: Adt); mir! { - let _2: *mut Adt; + let _2: &Adt; let _3: u32; let _4: &Adt; + let _5: (Adt,); { - _2 = core::ptr::addr_of_mut!(_1.0); + _2 = &_1.0; _4 = &(*_2); _3 = Field(Variant((*_4), 1), 0); - _1.0 = Adt::Some(_3); + _5.0 = Adt::Some(_3); Return() } } diff --git a/tests/mir-opt/gvn_overlapping.stable_projection.GVN.diff b/tests/mir-opt/gvn_overlapping.stable_projection.GVN.diff index 088354565911..b5353b7abde7 100644 --- a/tests/mir-opt/gvn_overlapping.stable_projection.GVN.diff +++ b/tests/mir-opt/gvn_overlapping.stable_projection.GVN.diff @@ -3,16 +3,18 @@ fn stable_projection(_1: (Adt,)) -> () { let mut _0: (); - let mut _2: *mut Adt; + let mut _2: &Adt; let mut _3: u32; let mut _4: &Adt; + let mut _5: (Adt,); bb0: { - _2 = &raw mut (_1.0: Adt); + _2 = &(_1.0: Adt); _4 = &(*_2); - _3 = copy (((*_4) as variant#1).0: u32); -- (_1.0: Adt) = Adt::Some(copy _3); -+ (_1.0: Adt) = copy (*_4); +- _3 = copy (((*_4) as variant#1).0: u32); +- (_5.0: Adt) = Adt::Some(copy _3); ++ _3 = copy (((_1.0: Adt) as variant#1).0: u32); ++ (_5.0: Adt) = copy (_1.0: Adt); return; } } diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.rs b/tests/mir-opt/pre-codegen/deref_nested_borrows.rs index 738cd981ae67..ab700a642900 100644 --- a/tests/mir-opt/pre-codegen/deref_nested_borrows.rs +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.rs @@ -2,9 +2,6 @@ fn src(x: &&u8) -> bool { // CHECK-LABEL: fn src( - // CHECK-NOT: _0 = const true; - // CHECK: _0 = Eq({{.*}}, {{.*}}); - // CHECK-NOT: _0 = const true; let y = **x; unsafe { unknown() }; **x == y diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff index 269af438e37e..a68ff13f26a6 100644 --- a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff @@ -24,12 +24,14 @@ bb1: { StorageLive(_4); - _7 = copy (*_1); - _4 = copy (*_7); +- _7 = copy (*_1); +- _4 = copy (*_7); ++ _7 = copy _6; ++ _4 = copy _2; StorageLive(_5); _5 = copy _2; - _0 = Eq(move _4, move _5); -+ _0 = Eq(move _4, copy _2); ++ _0 = const true; StorageDead(_5); StorageDead(_4); - StorageDead(_2); diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff index 9ce17342a445..fe64d8f97d20 100644 --- a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff @@ -24,12 +24,14 @@ bb1: { StorageLive(_4); - _7 = copy (*_1); - _4 = copy (*_7); +- _7 = copy (*_1); +- _4 = copy (*_7); ++ _7 = copy _6; ++ _4 = copy _2; StorageLive(_5); _5 = copy _2; - _0 = Eq(move _4, move _5); -+ _0 = Eq(move _4, copy _2); ++ _0 = const true; StorageDead(_5); StorageDead(_4); - StorageDead(_2); diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir index 23b1c3f3f43a..13f2eb9874b4 100644 --- a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir @@ -6,8 +6,6 @@ fn src(_1: &&u8) -> bool { let mut _2: &u8; let _3: u8; let _4: (); - let mut _5: &u8; - let mut _6: u8; scope 1 { debug y => _3; } @@ -19,11 +17,7 @@ fn src(_1: &&u8) -> bool { } bb1: { - StorageLive(_6); - _5 = copy (*_1); - _6 = copy (*_5); - _0 = Eq(move _6, copy _3); - StorageDead(_6); + _0 = const true; return; } } diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir index 4c01e9464bf4..7fab6e5511fd 100644 --- a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir @@ -6,8 +6,6 @@ fn src(_1: &&u8) -> bool { let mut _2: &u8; let _3: u8; let _4: (); - let mut _5: &u8; - let mut _6: u8; scope 1 { debug y => _3; } @@ -19,11 +17,7 @@ fn src(_1: &&u8) -> bool { } bb1: { - StorageLive(_6); - _5 = copy (*_1); - _6 = copy (*_5); - _0 = Eq(move _6, copy _3); - StorageDead(_6); + _0 = const true; return; } }