From 10b8ba4ecb19ac2eb7be97a1a1eb1ffae9fec534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 30 Oct 2024 21:11:37 +0800 Subject: [PATCH] Mark `simplify_aggregate_to_copy` mir-opt as unsound Co-authored-by: DianQK --- compiler/rustc_mir_transform/src/gvn.rs | 4 ++- tests/codegen/clone_as_copy.rs | 2 ++ tests/codegen/try_question_mark_nop.rs | 14 +++------ tests/mir-opt/gvn_clone.rs | 2 ++ .../mir-opt/gvn_clone.{impl#0}-clone.GVN.diff | 6 ++-- tests/mir-opt/gvn_copy_aggregate.rs | 2 ++ tests/mir-opt/pre-codegen/clone_as_copy.rs | 2 ++ ..._clone.{impl#0}-clone.PreCodegen.after.mir | 6 +++- .../try_identity.old.PreCodegen.after.mir | 8 ++--- ..._to_slice.PreCodegen.after.panic-abort.mir | 30 +++++++++++-------- ...to_slice.PreCodegen.after.panic-unwind.mir | 30 +++++++++++-------- 11 files changed, 63 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 8a646d8cbfe..274eea9563f 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1082,7 +1082,9 @@ fn simplify_aggregate( } } - if let AggregateTy::Def(_, _) = ty + // unsound: https://github.com/rust-lang/rust/issues/132353 + if tcx.sess.opts.unstable_opts.unsound_mir_opts + && let AggregateTy::Def(_, _) = ty && let Some(value) = self.simplify_aggregate_to_copy(rvalue, location, &fields, variant_index) { diff --git a/tests/codegen/clone_as_copy.rs b/tests/codegen/clone_as_copy.rs index 36a59ae56b7..6ba198297e2 100644 --- a/tests/codegen/clone_as_copy.rs +++ b/tests/codegen/clone_as_copy.rs @@ -1,4 +1,6 @@ //@ revisions: DEBUGINFO NODEBUGINFO +//@ compile-flags: -Zunsound-mir-opts +// FIXME: see //@ compile-flags: -O -Cno-prepopulate-passes //@ [DEBUGINFO] compile-flags: -Cdebuginfo=full diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index 65167f5c5af..bbab0d9eb1d 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -1,10 +1,7 @@ //@ compile-flags: -O -Z merge-functions=disabled --edition=2021 //@ only-x86_64 // FIXME: Remove the `min-llvm-version`. -//@ revisions: NINETEEN TWENTY -//@[NINETEEN] min-llvm-version: 19 -//@[NINETEEN] ignore-llvm-version: 20-99 -//@[TWENTY] min-llvm-version: 20 +//@ min-llvm-version: 19 #![crate_type = "lib"] #![feature(try_blocks)] @@ -16,12 +13,9 @@ #[no_mangle] pub fn option_nop_match_32(x: Option) -> Option { // CHECK: start: - // NINETEEN-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1 - // NINETEEN-NEXT: [[FIRST:%.*]] = select i1 [[TRUNC]], i32 %0 - // NINETEEN-NEXT: insertvalue { i32, i32 } poison, i32 [[FIRST]], 0 - // TWENTY-NEXT: insertvalue { i32, i32 } poison, i32 %0, 0 - // CHECK-NEXT: insertvalue { i32, i32 } - // CHECK-NEXT: ret { i32, i32 } + // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0 + // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1 + // CHECK-NEXT: ret { i32, i32 } [[REG2]] match x { Some(x) => Some(x), None => None, diff --git a/tests/mir-opt/gvn_clone.rs b/tests/mir-opt/gvn_clone.rs index 08938c0e1b4..c16b665fbd3 100644 --- a/tests/mir-opt/gvn_clone.rs +++ b/tests/mir-opt/gvn_clone.rs @@ -1,3 +1,5 @@ +//@ compile-flags: -Zunsound-mir-opts +// FIXME: see //@ test-mir-pass: GVN //@ compile-flags: -Zmir-enable-passes=+InstSimplify-before-inline diff --git a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff index 57b0980a0bd..8d5991872e1 100644 --- a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff +++ b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff @@ -1,7 +1,7 @@ -- // MIR for `::clone` before GVN -+ // MIR for `::clone` after GVN +- // MIR for `::clone` before GVN ++ // MIR for `::clone` after GVN - fn ::clone(_1: &AllCopy) -> AllCopy { + fn ::clone(_1: &AllCopy) -> AllCopy { debug self => _1; let mut _0: AllCopy; let mut _2: i32; diff --git a/tests/mir-opt/gvn_copy_aggregate.rs b/tests/mir-opt/gvn_copy_aggregate.rs index c9473025a15..7c181d1ad37 100644 --- a/tests/mir-opt/gvn_copy_aggregate.rs +++ b/tests/mir-opt/gvn_copy_aggregate.rs @@ -1,3 +1,5 @@ +//@ compile-flags: -Zunsound-mir-opts +// FIXME: see //@ compile-flags: -Cdebuginfo=full // Check if we have transformed the nested clone to the copy in the complete pipeline. diff --git a/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir index 9020cf1ef37..62a9cd9131f 100644 --- a/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir @@ -3,9 +3,13 @@ fn ::clone(_1: &Foo) -> Foo { debug self => _1; let mut _0: Foo; + let mut _2: i32; bb0: { - _0 = copy (*_1); + StorageLive(_2); + _2 = copy ((*_1).0: i32); + _0 = Foo { a: move _2 }; + StorageDead(_2); return; } } diff --git a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir index 889e80d26e1..ac485f485b1 100644 --- a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir @@ -19,14 +19,14 @@ fn old(_1: Result) -> Result { } bb1: { - _3 = copy ((_1 as Ok).0: T); - _0 = copy _1; + _3 = move ((_1 as Ok).0: T); + _0 = Result::::Ok(copy _3); goto -> bb3; } bb2: { - _4 = copy ((_1 as Err).0: E); - _0 = copy _1; + _4 = move ((_1 as Err).0: E); + _0 = Result::::Err(copy _4); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir index 4d964b0afb7..c3091bd4395 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir @@ -7,7 +7,7 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { debug self => _1; scope 2 (inlined Vec::::as_slice) { debug self => _1; - let mut _6: usize; + let mut _7: usize; scope 3 (inlined Vec::::as_ptr) { debug self => _1; let mut _2: &alloc::raw_vec::RawVec; @@ -16,6 +16,7 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { let mut _3: &alloc::raw_vec::RawVecInner; scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { debug self => _3; + let mut _6: std::ptr::NonNull; scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { debug self => _3; let mut _4: std::ptr::NonNull; @@ -31,20 +32,20 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } } scope 10 (inlined Unique::::as_non_null_ptr) { - debug ((self: Unique).0: std::ptr::NonNull) => _4; + debug ((self: Unique).0: std::ptr::NonNull) => _6; debug ((self: Unique).1: std::marker::PhantomData) => const PhantomData::; } } scope 11 (inlined NonNull::::as_ptr) { - debug self => _4; + debug self => _6; } } } } scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { debug data => _5; - debug len => _6; - let _7: *const [u8]; + debug len => _7; + let _8: *const [u8]; scope 13 (inlined core::ub_checks::check_language_ub) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -55,10 +56,10 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } scope 17 (inlined slice_from_raw_parts::) { debug data => _5; - debug len => _6; + debug len => _7; scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { debug data_pointer => _5; - debug metadata => _6; + debug metadata => _7; } } } @@ -70,17 +71,22 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { _2 = &((*_1).0: alloc::raw_vec::RawVec); StorageLive(_3); _3 = &(((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); + StorageLive(_6); + StorageLive(_4); _4 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _5 = copy (_4.0: *const u8); + _6 = NonNull:: { pointer: copy _5 }; + StorageDead(_4); + StorageDead(_6); StorageDead(_3); StorageDead(_2); - StorageLive(_6); - _6 = copy ((*_1).1: usize); StorageLive(_7); - _7 = *const [u8] from (copy _5, copy _6); - _0 = &(*_7); + _7 = copy ((*_1).1: usize); + StorageLive(_8); + _8 = *const [u8] from (copy _5, copy _7); + _0 = &(*_8); + StorageDead(_8); StorageDead(_7); - StorageDead(_6); return; } } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir index 4d964b0afb7..c3091bd4395 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir @@ -7,7 +7,7 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { debug self => _1; scope 2 (inlined Vec::::as_slice) { debug self => _1; - let mut _6: usize; + let mut _7: usize; scope 3 (inlined Vec::::as_ptr) { debug self => _1; let mut _2: &alloc::raw_vec::RawVec; @@ -16,6 +16,7 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { let mut _3: &alloc::raw_vec::RawVecInner; scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { debug self => _3; + let mut _6: std::ptr::NonNull; scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { debug self => _3; let mut _4: std::ptr::NonNull; @@ -31,20 +32,20 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } } scope 10 (inlined Unique::::as_non_null_ptr) { - debug ((self: Unique).0: std::ptr::NonNull) => _4; + debug ((self: Unique).0: std::ptr::NonNull) => _6; debug ((self: Unique).1: std::marker::PhantomData) => const PhantomData::; } } scope 11 (inlined NonNull::::as_ptr) { - debug self => _4; + debug self => _6; } } } } scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { debug data => _5; - debug len => _6; - let _7: *const [u8]; + debug len => _7; + let _8: *const [u8]; scope 13 (inlined core::ub_checks::check_language_ub) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -55,10 +56,10 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } scope 17 (inlined slice_from_raw_parts::) { debug data => _5; - debug len => _6; + debug len => _7; scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { debug data_pointer => _5; - debug metadata => _6; + debug metadata => _7; } } } @@ -70,17 +71,22 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { _2 = &((*_1).0: alloc::raw_vec::RawVec); StorageLive(_3); _3 = &(((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); + StorageLive(_6); + StorageLive(_4); _4 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _5 = copy (_4.0: *const u8); + _6 = NonNull:: { pointer: copy _5 }; + StorageDead(_4); + StorageDead(_6); StorageDead(_3); StorageDead(_2); - StorageLive(_6); - _6 = copy ((*_1).1: usize); StorageLive(_7); - _7 = *const [u8] from (copy _5, copy _6); - _0 = &(*_7); + _7 = copy ((*_1).1: usize); + StorageLive(_8); + _8 = *const [u8] from (copy _5, copy _7); + _0 = &(*_8); + StorageDead(_8); StorageDead(_7); - StorageDead(_6); return; } }