Convert moves of references to copies in RefProp

This commit is contained in:
Ben Kimock
2025-06-07 19:46:25 -04:00
parent a1531335fe
commit 9aa8cfaf2f
28 changed files with 194 additions and 88 deletions

View File

@@ -79,6 +79,7 @@ impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
#[instrument(level = "trace", skip(self, tcx, body))]
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!(def_id = ?body.source.def_id());
move_to_copy_pointers(tcx, body);
while propagate_ssa(tcx, body) {}
}
@@ -87,11 +88,43 @@ impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
}
}
/// The SSA analysis done by [`SsaLocals`] treats [`Operand::Move`] as a read, even though in
/// general [`Operand::Move`] represents pass-by-pointer where the callee can overwrite the
/// pointee (Miri always considers the place deinitialized). CopyProp has a similar trick to
/// turn [`Operand::Move`] into [`Operand::Copy`] when required for an optimization, but in this
/// pass we just turn all moves of pointers into copies because pointers should be by-value anyway.
fn move_to_copy_pointers<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mut visitor = MoveToCopyVisitor { tcx, local_decls: &body.local_decls };
for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
visitor.visit_basic_block_data(bb, data);
}
struct MoveToCopyVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
local_decls: &'a IndexVec<Local, LocalDecl<'tcx>>,
}
impl<'a, 'tcx> MutVisitor<'tcx> for MoveToCopyVisitor<'a, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
if let Operand::Move(place) = *operand {
if place.ty(self.local_decls, self.tcx).ty.is_any_ptr() {
*operand = Operand::Copy(place);
}
}
self.super_operand(operand, loc);
}
}
}
fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
let typing_env = body.typing_env(tcx);
let ssa = SsaLocals::new(tcx, body, typing_env);
let mut replacer = compute_replacement(tcx, body, &ssa);
let mut replacer = compute_replacement(tcx, body, ssa);
debug!(?replacer.targets);
debug!(?replacer.allowed_replacements);
debug!(?replacer.storage_to_remove);
@@ -119,7 +152,7 @@ enum Value<'tcx> {
fn compute_replacement<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
ssa: &SsaLocals,
ssa: SsaLocals,
) -> Replacer<'tcx> {
let always_live_locals = always_storage_live_locals(body);
@@ -138,7 +171,7 @@ fn compute_replacement<'tcx>(
// reborrowed references.
let mut storage_to_remove = DenseBitSet::new_empty(body.local_decls.len());
let fully_replaceable_locals = fully_replaceable_locals(ssa);
let fully_replaceable_locals = fully_replaceable_locals(&ssa);
// Returns true iff we can use `place` as a pointee.
//

View File

@@ -55,7 +55,7 @@ struct WithSliceTail(f64, [i32]);
fn index_custom(custom: &WithSliceTail, index: usize) -> &i32 {
// CHECK: bb0:
// CHECK: [[PTR:_.+]] = &raw const (fake) ((*_1).1: [i32]);
// CHECK: [[LEN:_.+]] = PtrMetadata(move [[PTR]]);
// CHECK: [[LEN:_.+]] = PtrMetadata(copy [[PTR]]);
// CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
// CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,

View File

@@ -112,7 +112,7 @@
StorageDead(_17);
StorageDead(_16);
StorageDead(_14);
_3 = ShallowInitBox(move _13, ());
_3 = ShallowInitBox(copy _13, ());
StorageDead(_13);
StorageDead(_12);
StorageDead(_11);

View File

@@ -112,7 +112,7 @@
StorageDead(_17);
StorageDead(_16);
StorageDead(_14);
_3 = ShallowInitBox(move _13, ());
_3 = ShallowInitBox(copy _13, ());
StorageDead(_13);
StorageDead(_12);
StorageDead(_11);

View File

@@ -103,7 +103,7 @@
StorageDead(_6);
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
_3 = move _4 as *mut u8 (PtrToPtr);
_3 = copy _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);

View File

@@ -46,7 +46,7 @@
StorageDead(_6);
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
_3 = move _4 as *mut u8 (PtrToPtr);
_3 = copy _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);

View File

@@ -103,7 +103,7 @@
StorageDead(_6);
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
_3 = move _4 as *mut u8 (PtrToPtr);
_3 = copy _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);

View File

@@ -46,7 +46,7 @@
StorageDead(_6);
_4 = copy _5 as *mut [u8] (Transmute);
StorageDead(_5);
_3 = move _4 as *mut u8 (PtrToPtr);
_3 = copy _4 as *mut u8 (PtrToPtr);
StorageDead(_4);
StorageDead(_3);
- StorageDead(_1);

View File

@@ -30,7 +30,7 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
StorageDead(_3);
StorageLive(_5);
_5 = &mut (*_1)[_2];
_0 = Option::<&mut u32>::Some(move _5);
_0 = Option::<&mut u32>::Some(copy _5);
StorageDead(_5);
goto -> bb3;
}

View File

@@ -30,7 +30,7 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
StorageDead(_3);
StorageLive(_5);
_5 = &mut (*_1)[_2];
_0 = Option::<&mut u32>::Some(move _5);
_0 = Option::<&mut u32>::Some(copy _5);
StorageDead(_5);
goto -> bb3;
}

View File

@@ -143,7 +143,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
_4 = &raw const (*_1);
StorageLive(_5);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: move _5 };
_6 = NonNull::<T> { pointer: copy _5 };
StorageDead(_5);
StorageLive(_9);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
@@ -155,7 +155,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
_7 = copy _4 as *mut T (PtrToPtr);
_8 = Offset(copy _7, copy _3);
StorageDead(_7);
_9 = move _8 as *const T (PtrToPtr);
_9 = copy _8 as *const T (PtrToPtr);
StorageDead(_8);
goto -> bb3;
}
@@ -202,7 +202,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
_17 = copy _14 as *mut T (Transmute);
StorageLive(_18);
_18 = copy _16 as *mut T (Transmute);
_19 = Eq(move _17, move _18);
_19 = Eq(copy _17, copy _18);
StorageDead(_18);
StorageDead(_17);
switchInt(move _19) -> [0: bb6, otherwise: bb7];
@@ -214,9 +214,9 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
StorageLive(_21);
StorageLive(_20);
_20 = copy _14 as *const T (Transmute);
_21 = Offset(move _20, const 1_usize);
_21 = Offset(copy _20, const 1_usize);
StorageDead(_20);
_22 = NonNull::<T> { pointer: move _21 };
_22 = NonNull::<T> { pointer: copy _21 };
StorageDead(_21);
_11 = move _22;
StorageDead(_22);
@@ -282,7 +282,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
StorageDead(_23);
StorageDead(_15);
StorageDead(_14);
_28 = move ((_27 as Some).0: &T);
_28 = copy ((_27 as Some).0: &T);
StorageDead(_27);
_29 = copy _13;
_30 = AddWithOverflow(copy _13, const 1_usize);

View File

@@ -70,7 +70,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
_4 = &raw const (*_1);
StorageLive(_5);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: move _5 };
_6 = NonNull::<T> { pointer: copy _5 };
StorageDead(_5);
StorageLive(_9);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
@@ -82,7 +82,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
_7 = copy _4 as *mut T (PtrToPtr);
_8 = Offset(copy _7, copy _3);
StorageDead(_7);
_9 = move _8 as *const T (PtrToPtr);
_9 = copy _8 as *const T (PtrToPtr);
StorageDead(_8);
goto -> bb3;
}
@@ -95,7 +95,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
bb3: {
StorageLive(_10);
_10 = copy _9;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _10, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10);
StorageDead(_9);
StorageDead(_4);

View File

@@ -110,7 +110,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_4 = &raw const (*_1);
StorageLive(_5);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: move _5 };
_6 = NonNull::<T> { pointer: copy _5 };
StorageDead(_5);
StorageLive(_9);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
@@ -122,7 +122,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_7 = copy _4 as *mut T (PtrToPtr);
_8 = Offset(copy _7, copy _3);
StorageDead(_7);
_9 = move _8 as *const T (PtrToPtr);
_9 = copy _8 as *const T (PtrToPtr);
StorageDead(_8);
goto -> bb3;
}
@@ -164,7 +164,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_16 = copy _13 as *mut T (Transmute);
StorageLive(_17);
_17 = copy _15 as *mut T (Transmute);
_18 = Eq(move _16, move _17);
_18 = Eq(copy _16, copy _17);
StorageDead(_17);
StorageDead(_16);
switchInt(move _18) -> [0: bb6, otherwise: bb7];
@@ -176,9 +176,9 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
StorageLive(_20);
StorageLive(_19);
_19 = copy _13 as *const T (Transmute);
_20 = Offset(move _19, const 1_usize);
_20 = Offset(copy _19, const 1_usize);
StorageDead(_19);
_21 = NonNull::<T> { pointer: move _20 };
_21 = NonNull::<T> { pointer: copy _20 };
StorageDead(_20);
_11 = move _21;
StorageDead(_21);

View File

@@ -110,7 +110,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_4 = &raw const (*_1);
StorageLive(_5);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: move _5 };
_6 = NonNull::<T> { pointer: copy _5 };
StorageDead(_5);
StorageLive(_9);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
@@ -122,7 +122,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_7 = copy _4 as *mut T (PtrToPtr);
_8 = Offset(copy _7, copy _3);
StorageDead(_7);
_9 = move _8 as *const T (PtrToPtr);
_9 = copy _8 as *const T (PtrToPtr);
StorageDead(_8);
goto -> bb3;
}
@@ -164,7 +164,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_16 = copy _13 as *mut T (Transmute);
StorageLive(_17);
_17 = copy _15 as *mut T (Transmute);
_18 = Eq(move _16, move _17);
_18 = Eq(copy _16, copy _17);
StorageDead(_17);
StorageDead(_16);
switchInt(move _18) -> [0: bb6, otherwise: bb7];
@@ -176,9 +176,9 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
StorageLive(_20);
StorageLive(_19);
_19 = copy _13 as *const T (Transmute);
_20 = Offset(move _19, const 1_usize);
_20 = Offset(copy _19, const 1_usize);
StorageDead(_19);
_21 = NonNull::<T> { pointer: move _20 };
_21 = NonNull::<T> { pointer: copy _20 };
StorageDead(_20);
_11 = move _21;
StorageDead(_21);

View File

@@ -70,7 +70,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_4 = &raw const (*_1);
StorageLive(_5);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: move _5 };
_6 = NonNull::<T> { pointer: copy _5 };
StorageDead(_5);
StorageLive(_9);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
@@ -82,7 +82,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_7 = copy _4 as *mut T (PtrToPtr);
_8 = Offset(copy _7, copy _3);
StorageDead(_7);
_9 = move _8 as *const T (PtrToPtr);
_9 = copy _8 as *const T (PtrToPtr);
StorageDead(_8);
goto -> bb3;
}
@@ -95,7 +95,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb3: {
StorageLive(_10);
_10 = copy _9;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _10, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10);
StorageDead(_9);
StorageDead(_4);

View File

@@ -70,7 +70,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_4 = &raw const (*_1);
StorageLive(_5);
_5 = copy _4 as *const T (PtrToPtr);
_6 = NonNull::<T> { pointer: move _5 };
_6 = NonNull::<T> { pointer: copy _5 };
StorageDead(_5);
StorageLive(_9);
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
@@ -82,7 +82,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_7 = copy _4 as *mut T (PtrToPtr);
_8 = Offset(copy _7, copy _3);
StorageDead(_7);
_9 = move _8 as *const T (PtrToPtr);
_9 = copy _8 as *const T (PtrToPtr);
StorageDead(_8);
goto -> bb3;
}
@@ -95,7 +95,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb3: {
StorageLive(_10);
_10 = copy _9;
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
_11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _10, _marker: const ZeroSized: PhantomData<&T> };
StorageDead(_10);
StorageDead(_9);
StorageDead(_4);

View File

@@ -39,7 +39,7 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
bb1: {
StorageLive(_2);
_2 = copy ((*_1).1: *const T);
_3 = move _2 as std::ptr::NonNull<T> (Transmute);
_3 = copy _2 as std::ptr::NonNull<T> (Transmute);
StorageDead(_2);
StorageLive(_5);
StorageLive(_4);
@@ -48,7 +48,7 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
StorageDead(_4);
StorageLive(_6);
_6 = copy _3 as *mut T (Transmute);
_0 = Eq(move _5, move _6);
_0 = Eq(copy _5, copy _6);
StorageDead(_6);
StorageDead(_5);
goto -> bb3;

View File

@@ -39,7 +39,7 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
bb1: {
StorageLive(_2);
_2 = copy ((*_1).1: *const T);
_3 = move _2 as std::ptr::NonNull<T> (Transmute);
_3 = copy _2 as std::ptr::NonNull<T> (Transmute);
StorageDead(_2);
StorageLive(_5);
StorageLive(_4);
@@ -48,7 +48,7 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
StorageDead(_4);
StorageLive(_6);
_6 = copy _3 as *mut T (Transmute);
_0 = Eq(move _5, move _6);
_0 = Eq(copy _5, copy _6);
StorageDead(_6);
StorageDead(_5);
goto -> bb3;

View File

@@ -72,7 +72,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
_5 = copy _2 as *mut T (Transmute);
StorageLive(_6);
_6 = copy _4 as *mut T (Transmute);
_7 = Eq(move _5, move _6);
_7 = Eq(copy _5, copy _6);
StorageDead(_6);
StorageDead(_5);
switchInt(move _7) -> [0: bb2, otherwise: bb3];
@@ -84,9 +84,9 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
StorageLive(_9);
StorageLive(_8);
_8 = copy _2 as *const T (Transmute);
_9 = Offset(move _8, const 1_usize);
_9 = Offset(copy _8, const 1_usize);
StorageDead(_8);
_10 = NonNull::<T> { pointer: move _9 };
_10 = NonNull::<T> { pointer: copy _9 };
StorageDead(_9);
((*_1).0: std::ptr::NonNull<T>) = move _10;
StorageDead(_10);

View File

@@ -72,7 +72,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
_5 = copy _2 as *mut T (Transmute);
StorageLive(_6);
_6 = copy _4 as *mut T (Transmute);
_7 = Eq(move _5, move _6);
_7 = Eq(copy _5, copy _6);
StorageDead(_6);
StorageDead(_5);
switchInt(move _7) -> [0: bb2, otherwise: bb3];
@@ -84,9 +84,9 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
StorageLive(_9);
StorageLive(_8);
_8 = copy _2 as *const T (Transmute);
_9 = Offset(move _8, const 1_usize);
_9 = Offset(copy _8, const 1_usize);
StorageDead(_8);
_10 = NonNull::<T> { pointer: move _9 };
_10 = NonNull::<T> { pointer: copy _9 };
StorageDead(_9);
((*_1).0: std::ptr::NonNull<T>) = move _10;
StorageDead(_10);

View File

@@ -99,7 +99,8 @@
_13 = &(*_26);
StorageLive(_15);
_15 = RangeFull;
_12 = <[i32; 10] as Index<RangeFull>>::index(move _13, move _15) -> [return: bb5, unwind continue];
- _12 = <[i32; 10] as Index<RangeFull>>::index(move _13, move _15) -> [return: bb5, unwind continue];
+ _12 = <[i32; 10] as Index<RangeFull>>::index(copy _13, move _15) -> [return: bb5, unwind continue];
}
bb5: {

View File

@@ -218,8 +218,9 @@
- StorageLive(_14);
- _14 = &_11;
- _13 = &(*_14);
- _12 = move _13;
+ _13 = &_11;
_12 = move _13;
+ _12 = copy _13;
StorageDead(_13);
- StorageDead(_14);
StorageLive(_15);
@@ -252,7 +253,8 @@
StorageLive(_23);
StorageLive(_24);
_24 = copy _21;
_23 = opaque::<&&usize>(move _24) -> [return: bb3, unwind continue];
- _23 = opaque::<&&usize>(move _24) -> [return: bb3, unwind continue];
+ _23 = opaque::<&&usize>(copy _24) -> [return: bb3, unwind continue];
}
bb3: {
@@ -276,7 +278,8 @@
StorageLive(_30);
StorageLive(_31);
_31 = copy _28;
_30 = opaque::<*mut &usize>(move _31) -> [return: bb4, unwind continue];
- _30 = opaque::<*mut &usize>(move _31) -> [return: bb4, unwind continue];
+ _30 = opaque::<*mut &usize>(copy _31) -> [return: bb4, unwind continue];
}
bb4: {
@@ -299,7 +302,8 @@
StorageLive(_36);
StorageLive(_37);
_37 = copy _34;
_36 = opaque::<&usize>(move _37) -> [return: bb5, unwind continue];
- _36 = opaque::<&usize>(move _37) -> [return: bb5, unwind continue];
+ _36 = opaque::<&usize>(copy _37) -> [return: bb5, unwind continue];
}
bb5: {
@@ -328,7 +332,8 @@
StorageLive(_45);
StorageLive(_46);
_46 = copy _44;
_45 = opaque::<&usize>(move _46) -> [return: bb6, unwind continue];
- _45 = opaque::<&usize>(move _46) -> [return: bb6, unwind continue];
+ _45 = opaque::<&usize>(copy _46) -> [return: bb6, unwind continue];
}
bb6: {
@@ -368,8 +373,9 @@
- StorageLive(_55);
- _55 = &(*_1);
- _54 = &(*_55);
- _2 = move _54;
+ _54 = &(*_1);
_2 = move _54;
+ _2 = copy _54;
StorageDead(_54);
- StorageDead(_55);
StorageLive(_56);

View File

@@ -233,7 +233,8 @@
_12 = &raw const _10;
StorageLive(_13);
_13 = &raw const _11;
_12 = move _13;
- _12 = move _13;
+ _12 = copy _13;
StorageDead(_13);
StorageLive(_14);
_14 = copy (*_12);
@@ -265,7 +266,8 @@
StorageLive(_22);
StorageLive(_23);
_23 = copy _20;
_22 = opaque::<&*const usize>(move _23) -> [return: bb3, unwind continue];
- _22 = opaque::<&*const usize>(move _23) -> [return: bb3, unwind continue];
+ _22 = opaque::<&*const usize>(copy _23) -> [return: bb3, unwind continue];
}
bb3: {
@@ -289,7 +291,8 @@
StorageLive(_29);
StorageLive(_30);
_30 = copy _27;
_29 = opaque::<*mut *const usize>(move _30) -> [return: bb4, unwind continue];
- _29 = opaque::<*mut *const usize>(move _30) -> [return: bb4, unwind continue];
+ _29 = opaque::<*mut *const usize>(copy _30) -> [return: bb4, unwind continue];
}
bb4: {
@@ -312,7 +315,8 @@
StorageLive(_35);
StorageLive(_36);
_36 = copy _33;
_35 = opaque::<*const usize>(move _36) -> [return: bb5, unwind continue];
- _35 = opaque::<*const usize>(move _36) -> [return: bb5, unwind continue];
+ _35 = opaque::<*const usize>(copy _36) -> [return: bb5, unwind continue];
}
bb5: {
@@ -341,7 +345,8 @@
StorageLive(_44);
StorageLive(_45);
_45 = copy _43;
_44 = opaque::<*const usize>(move _45) -> [return: bb6, unwind continue];
- _44 = opaque::<*const usize>(move _45) -> [return: bb6, unwind continue];
+ _44 = opaque::<*const usize>(copy _45) -> [return: bb6, unwind continue];
}
bb6: {
@@ -379,7 +384,8 @@
_52 = &raw const (*_2);
StorageLive(_53);
_53 = &raw const (*_1);
_2 = move _53;
- _2 = move _53;
+ _2 = copy _53;
StorageDead(_53);
StorageLive(_54);
_54 = copy (*_52);

View File

@@ -218,8 +218,9 @@
- StorageLive(_14);
- _14 = &mut _11;
- _13 = &mut (*_14);
- _12 = move _13;
+ _13 = &mut _11;
_12 = move _13;
+ _12 = copy _13;
StorageDead(_13);
- StorageDead(_14);
StorageLive(_15);
@@ -251,7 +252,8 @@
StorageLive(_23);
StorageLive(_24);
_24 = copy _21;
_23 = opaque::<&&mut usize>(move _24) -> [return: bb3, unwind continue];
- _23 = opaque::<&&mut usize>(move _24) -> [return: bb3, unwind continue];
+ _23 = opaque::<&&mut usize>(copy _24) -> [return: bb3, unwind continue];
}
bb3: {
@@ -275,7 +277,8 @@
StorageLive(_30);
StorageLive(_31);
_31 = copy _28;
_30 = opaque::<*mut &mut usize>(move _31) -> [return: bb4, unwind continue];
- _30 = opaque::<*mut &mut usize>(move _31) -> [return: bb4, unwind continue];
+ _30 = opaque::<*mut &mut usize>(copy _31) -> [return: bb4, unwind continue];
}
bb4: {
@@ -296,8 +299,10 @@
_35 = copy (*_34);
StorageLive(_36);
StorageLive(_37);
_37 = move _34;
_36 = opaque::<&mut usize>(move _37) -> [return: bb5, unwind continue];
- _37 = move _34;
- _36 = opaque::<&mut usize>(move _37) -> [return: bb5, unwind continue];
+ _37 = copy _34;
+ _36 = opaque::<&mut usize>(copy _37) -> [return: bb5, unwind continue];
}
bb5: {
@@ -316,15 +321,19 @@
StorageLive(_41);
_41 = copy (*_40);
StorageLive(_42);
_42 = move _40;
- _42 = move _40;
+ _42 = copy _40;
StorageLive(_43);
_43 = copy (*_42);
StorageLive(_44);
_44 = move _42;
- _44 = move _42;
+ _44 = copy _42;
StorageLive(_45);
StorageLive(_46);
_46 = move _44;
_45 = opaque::<&mut usize>(move _46) -> [return: bb6, unwind continue];
- _46 = move _44;
- _45 = opaque::<&mut usize>(move _46) -> [return: bb6, unwind continue];
+ _46 = copy _44;
+ _45 = opaque::<&mut usize>(copy _46) -> [return: bb6, unwind continue];
}
bb6: {
@@ -364,8 +373,9 @@
- StorageLive(_55);
- _55 = &mut (*_1);
- _54 = &mut (*_55);
- _2 = move _54;
+ _54 = &mut (*_1);
_2 = move _54;
+ _2 = copy _54;
StorageDead(_54);
- StorageDead(_55);
StorageLive(_56);

View File

@@ -214,7 +214,8 @@
_12 = &raw mut _10;
StorageLive(_13);
_13 = &raw mut _11;
_12 = move _13;
- _12 = move _13;
+ _12 = copy _13;
StorageDead(_13);
StorageLive(_14);
_14 = copy (*_12);
@@ -245,7 +246,8 @@
StorageLive(_22);
StorageLive(_23);
_23 = copy _20;
_22 = opaque::<&*mut usize>(move _23) -> [return: bb3, unwind continue];
- _22 = opaque::<&*mut usize>(move _23) -> [return: bb3, unwind continue];
+ _22 = opaque::<&*mut usize>(copy _23) -> [return: bb3, unwind continue];
}
bb3: {
@@ -269,7 +271,8 @@
StorageLive(_29);
StorageLive(_30);
_30 = copy _27;
_29 = opaque::<*mut *mut usize>(move _30) -> [return: bb4, unwind continue];
- _29 = opaque::<*mut *mut usize>(move _30) -> [return: bb4, unwind continue];
+ _29 = opaque::<*mut *mut usize>(copy _30) -> [return: bb4, unwind continue];
}
bb4: {
@@ -291,7 +294,8 @@
StorageLive(_35);
StorageLive(_36);
_36 = copy _33;
_35 = opaque::<*mut usize>(move _36) -> [return: bb5, unwind continue];
- _35 = opaque::<*mut usize>(move _36) -> [return: bb5, unwind continue];
+ _35 = opaque::<*mut usize>(copy _36) -> [return: bb5, unwind continue];
}
bb5: {
@@ -318,7 +322,8 @@
StorageLive(_44);
StorageLive(_45);
_45 = copy _43;
_44 = opaque::<*mut usize>(move _45) -> [return: bb6, unwind continue];
- _44 = opaque::<*mut usize>(move _45) -> [return: bb6, unwind continue];
+ _44 = opaque::<*mut usize>(copy _45) -> [return: bb6, unwind continue];
}
bb6: {
@@ -356,7 +361,8 @@
_52 = &raw mut (*_2);
StorageLive(_53);
_53 = &raw mut (*_1);
_2 = move _53;
- _2 = move _53;
+ _2 = copy _53;
StorageDead(_53);
StorageLive(_54);
_54 = copy (*_52);

View File

@@ -30,7 +30,7 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
// CHECK: [[a2:_.*]] = const 7_usize;
// CHECK: [[b:_.*]] = &[[a]];
// CHECK: [[btmp:_.*]] = &[[a2]];
// CHECK: [[b]] = move [[btmp]];
// CHECK: [[b]] = copy [[btmp]];
// CHECK: [[c:_.*]] = copy (*[[b]]);
let a = 5_usize;
@@ -122,7 +122,7 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
// CHECK: bb7: {
// CHECK: [[a:_.*]] = &(*_2);
// CHECK: [[tmp:_.*]] = &(*_1);
// CHECK: _2 = move [[tmp]];
// CHECK: _2 = copy [[tmp]];
// CHECK: [[b:_.*]] = copy (*[[a]]);
let a = &*multiple;
@@ -186,7 +186,7 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
// CHECK: [[a2:_.*]] = const 7_usize;
// CHECK: [[b:_.*]] = &mut [[a]];
// CHECK: [[btmp:_.*]] = &mut [[a2]];
// CHECK: [[b]] = move [[btmp]];
// CHECK: [[b]] = copy [[btmp]];
// CHECK: [[c:_.*]] = copy (*[[b]]);
let mut a = 5_usize;
@@ -247,9 +247,9 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
// CHECK: [[a:_.*]] = const 7_usize;
// CHECK: [[b1:_.*]] = &mut [[a]];
// CHECK: [[c:_.*]] = copy (*[[b1]]);
// CHECK: [[b2:_.*]] = move [[b1]];
// CHECK: [[b2:_.*]] = copy [[b1]];
// CHECK: [[c2:_.*]] = copy (*[[b2]]);
// CHECK: [[b3:_.*]] = move [[b2]];
// CHECK: [[b3:_.*]] = copy [[b2]];
let mut a = 7_usize;
let b1 = &mut a;
@@ -278,7 +278,7 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m
// CHECK: bb7: {
// CHECK: [[a:_.*]] = &mut (*_2);
// CHECK: [[tmp:_.*]] = &mut (*_1);
// CHECK: _2 = move [[tmp]];
// CHECK: _2 = copy [[tmp]];
// CHECK: [[b:_.*]] = copy (*[[a]]);
let a = &mut *multiple;
@@ -343,7 +343,7 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
// CHECK: [[a2:_.*]] = const 7_usize;
// CHECK: [[b:_.*]] = &raw const [[a]];
// CHECK: [[btmp:_.*]] = &raw const [[a2]];
// CHECK: [[b]] = move [[btmp]];
// CHECK: [[b]] = copy [[btmp]];
// CHECK: [[c:_.*]] = copy (*[[b]]);
let a = 5_usize;
@@ -435,7 +435,7 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con
// CHECK: bb7: {
// CHECK: [[a:_.*]] = &raw const (*_2);
// CHECK: [[tmp:_.*]] = &raw const (*_1);
// CHECK: _2 = move [[tmp]];
// CHECK: _2 = copy [[tmp]];
// CHECK: [[b:_.*]] = copy (*[[a]]);
let a = &raw const *multiple;
@@ -514,7 +514,7 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T)
// CHECK: [[a2:_.*]] = const 7_usize;
// CHECK: [[b:_.*]] = &raw mut [[a]];
// CHECK: [[btmp:_.*]] = &raw mut [[a2]];
// CHECK: [[b]] = move [[btmp]];
// CHECK: [[b]] = copy [[btmp]];
// CHECK: [[c:_.*]] = copy (*[[b]]);
let mut a = 5_usize;
@@ -606,7 +606,7 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T)
// CHECK: bb7: {
// CHECK: [[a:_.*]] = &raw mut (*_2);
// CHECK: [[tmp:_.*]] = &raw mut (*_1);
// CHECK: _2 = move [[tmp]];
// CHECK: _2 = copy [[tmp]];
// CHECK: [[b:_.*]] = copy (*[[a]]);
let a = &raw mut *multiple;

View File

@@ -0,0 +1,44 @@
//@ test-mir-pass: ReferencePropagation
#![feature(custom_mir, core_intrinsics)]
#![allow(internal_features)]
#![crate_type = "lib"]
use std::intrinsics::mir::*;
#[inline(never)]
fn opaque(_: impl Sized, _: impl Sized) {}
#[custom_mir(dialect = "runtime")]
pub fn fn0() {
// CHECK-LABEL: fn0
// CHECK: _9 = opaque::<&u8, &u64>(copy (_2.1: &u8), copy _6) -> [return: bb1, unwind unreachable];
mir! {
let _1: (u8, u8);
let _2: (u64, &u8);
let _3: (u8, &&u64);
let _4: u64;
let _5: &u64;
let _6: &u64;
let _7: &u64;
let _8: u64;
let n: ();
{
_3.0 = 0;
_1 = (0, _3.0);
_4 = 0;
_2.1 = &_1.0;
_8 = 0;
_5 = &_8;
_5 = &_4;
_6 = _5;
_7 = _6;
_3.1 = &_6;
Call(n = opaque(_2.1, Move(_6)), ReturnTo(bb1), UnwindUnreachable())
}
bb1 = {
_2.0 = *_7;
Return()
}
}
}

View File

@@ -31,7 +31,7 @@ fn main() -> () {
StorageLive(_2);
StorageLive(_3);
_3 = &raw const _1;
_2 = move _3 as *const ! (PtrToPtr);
_2 = copy _3 as *const ! (PtrToPtr);
StorageDead(_3);
StorageDead(_2);
StorageDead(_1);
@@ -40,7 +40,7 @@ fn main() -> () {
StorageLive(_5);
StorageLive(_6);
_6 = &raw const _4;
_5 = move _6 as *const ! (PtrToPtr);
_5 = copy _6 as *const ! (PtrToPtr);
StorageDead(_6);
StorageDead(_5);
StorageDead(_4);