diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index daf868559bcae..de53ebfcd0ee2 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -1079,7 +1079,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
         }
 
-        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/library/Cargo.lock b/library/Cargo.lock
index 59b76d8d4427d..268367cd9c144 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -1,6 +1,6 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
+version = 4
 
 [[package]]
 name = "addr2line"
@@ -158,9 +158,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.159"
+version = "0.2.161"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
 dependencies = [
  "rustc-std-workspace-core",
 ]
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index f2669326065d5..5f8dcde189bcf 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -39,7 +39,7 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
 addr2line = { version = "0.22.0", optional = true, default-features = false }
 
 [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
-libc = { version = "0.2.156", default-features = false, features = [
+libc = { version = "0.2.161", default-features = false, features = [
     'rustc-dep-of-std',
 ], public = true }
 
diff --git a/library/std/src/sys/thread_local/native/mod.rs b/library/std/src/sys/thread_local/native/mod.rs
index f498dee0899f9..a5dffe3c45883 100644
--- a/library/std/src/sys/thread_local/native/mod.rs
+++ b/library/std/src/sys/thread_local/native/mod.rs
@@ -49,20 +49,21 @@ pub use lazy::Storage as LazyStorage;
 #[unstable(feature = "thread_local_internals", issue = "none")]
 #[rustc_macro_transparency = "semitransparent"]
 pub macro thread_local_inner {
-    // used to generate the `LocalKey` value for const-initialized thread locals
+    // NOTE: we cannot import `LocalKey`, `LazyStorage` or `EagerStorage` with a `use` because that
+    // can shadow user provided type or type alias with a matching name. Please update the shadowing
+    // test in `tests/thread.rs` if these types are renamed.
+
+    // Used to generate the `LocalKey` value for const-initialized thread locals.
     (@key $t:ty, const $init:expr) => {{
         const __INIT: $t = $init;
 
         unsafe {
-            use $crate::mem::needs_drop;
-            use $crate::thread::LocalKey;
-            use $crate::thread::local_impl::EagerStorage;
-
-            LocalKey::new(const {
-                if needs_drop::<$t>() {
+            $crate::thread::LocalKey::new(const {
+                if $crate::mem::needs_drop::<$t>() {
                     |_| {
                         #[thread_local]
-                        static VAL: EagerStorage<$t> = EagerStorage::new(__INIT);
+                        static VAL: $crate::thread::local_impl::EagerStorage<$t>
+                            = $crate::thread::local_impl::EagerStorage::new(__INIT);
                         VAL.get()
                     }
                 } else {
@@ -84,21 +85,19 @@ pub macro thread_local_inner {
         }
 
         unsafe {
-            use $crate::mem::needs_drop;
-            use $crate::thread::LocalKey;
-            use $crate::thread::local_impl::LazyStorage;
-
-            LocalKey::new(const {
-                if needs_drop::<$t>() {
+            $crate::thread::LocalKey::new(const {
+                if $crate::mem::needs_drop::<$t>() {
                     |init| {
                         #[thread_local]
-                        static VAL: LazyStorage<$t, ()> = LazyStorage::new();
+                        static VAL: $crate::thread::local_impl::LazyStorage<$t, ()>
+                            = $crate::thread::local_impl::LazyStorage::new();
                         VAL.get_or_init(init, __init)
                     }
                 } else {
                     |init| {
                         #[thread_local]
-                        static VAL: LazyStorage<$t, !> = LazyStorage::new();
+                        static VAL: $crate::thread::local_impl::LazyStorage<$t, !>
+                            = $crate::thread::local_impl::LazyStorage::new();
                         VAL.get_or_init(init, __init)
                     }
                 }
diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs
index 26ce3322a16e3..f5a2aaa6c6a3f 100644
--- a/library/std/src/sys/thread_local/os.rs
+++ b/library/std/src/sys/thread_local/os.rs
@@ -15,19 +15,24 @@ pub macro thread_local_inner {
         $crate::thread::local_impl::thread_local_inner!(@key $t, { const INIT_EXPR: $t = $init; INIT_EXPR })
     },
 
-    // used to generate the `LocalKey` value for `thread_local!`
+    // NOTE: we cannot import `Storage` or `LocalKey` with a `use` because that can shadow user
+    // provided type or type alias with a matching name. Please update the shadowing test in
+    // `tests/thread.rs` if these types are renamed.
+
+    // used to generate the `LocalKey` value for `thread_local!`.
     (@key $t:ty, $init:expr) => {{
         #[inline]
         fn __init() -> $t { $init }
 
+        // NOTE: this cannot import `LocalKey` or `Storage` with a `use` because that can shadow
+        // user provided type or type alias with a matching name. Please update the shadowing test
+        // in `tests/thread.rs` if these types are renamed.
         unsafe {
-            use $crate::thread::LocalKey;
-            use $crate::thread::local_impl::Storage;
-
             // Inlining does not work on windows-gnu due to linking errors around
             // dllimports. See https://github.com/rust-lang/rust/issues/109797.
-            LocalKey::new(#[cfg_attr(windows, inline(never))] |init| {
-                static VAL: Storage<$t> = Storage::new();
+            $crate::thread::LocalKey::new(#[cfg_attr(windows, inline(never))] |init| {
+                static VAL: $crate::thread::local_impl::Storage<$t>
+                    = $crate::thread::local_impl::Storage::new();
                 VAL.get(init, __init)
             })
         }
diff --git a/library/std/tests/thread.rs b/library/std/tests/thread.rs
index 83574176186a4..1bb17d149fa10 100644
--- a/library/std/tests/thread.rs
+++ b/library/std/tests/thread.rs
@@ -38,6 +38,29 @@ fn thread_local_containing_const_statements() {
     assert_eq!(REFCELL.take(), 1);
 }
 
+#[test]
+fn thread_local_hygeiene() {
+    // Previously `thread_local_inner!` had use imports for `LocalKey`, `Storage`, `EagerStorage`
+    // and `LazyStorage`. The use imports will shadow a user-provided type or type alias if the
+    // user-provided type or type alias has the same name. Make sure that this does not happen. See
+    // <https://github.com/rust-lang/rust/issues/131863>.
+    //
+    // NOTE: if the internal implementation details change (i.e. get renamed), this test should be
+    // updated.
+
+    #![allow(dead_code)]
+    type LocalKey = ();
+    type Storage = ();
+    type LazyStorage = ();
+    type EagerStorage = ();
+    thread_local! {
+        static A: LocalKey = const { () };
+        static B: Storage = const { () };
+        static C: LazyStorage = const { () };
+        static D: EagerStorage = const { () };
+    }
+}
+
 #[test]
 // Include an ignore list on purpose, so that new platforms don't miss it
 #[cfg_attr(
diff --git a/tests/codegen/clone_as_copy.rs b/tests/codegen/clone_as_copy.rs
index 36a59ae56b72b..6ba198297e226 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 <https://github.com/rust-lang/rust/issues/132353>
 //@ 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 65167f5c5af97..bbab0d9eb1dbf 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 @@ use std::ptr::NonNull;
 #[no_mangle]
 pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
     // 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 08938c0e1b427..c16b665fbd39c 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 <https://github.com/rust-lang/rust/issues/132353>
 //@ 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 57b0980a0bd17..8d5991872e180 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 `<impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone` before GVN
-+ // MIR for `<impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone` after GVN
+- // MIR for `<impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone` before GVN
++ // MIR for `<impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone` after GVN
   
-  fn <impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone(_1: &AllCopy) -> AllCopy {
+  fn <impl at $DIR/gvn_clone.rs:14:10: 14:15>::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 c9473025a15f2..7c181d1ad3784 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 <https://github.com/rust-lang/rust/issues/132353.
 //@ test-mir-pass: GVN
 //@ compile-flags: -Cpanic=abort
 
diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.rs b/tests/mir-opt/pre-codegen/clone_as_copy.rs
index f5ff1854d387d..ae4661e93fd4a 100644
--- a/tests/mir-opt/pre-codegen/clone_as_copy.rs
+++ b/tests/mir-opt/pre-codegen/clone_as_copy.rs
@@ -1,3 +1,5 @@
+//@ compile-flags: -Zunsound-mir-opts
+// FIXME: see <https://github.com/rust-lang/rust/issues/132353>
 //@ 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 9020cf1ef37f2..62a9cd9131f0b 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 <impl at $DIR/no_inlined_clone.rs:9:10: 9:15>::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 889e80d26e1cc..ac485f485b1cc 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<T, E>) -> Result<T, E> {
     }
 
     bb1: {
-        _3 = copy ((_1 as Ok).0: T);
-        _0 = copy _1;
+        _3 = move ((_1 as Ok).0: T);
+        _0 = Result::<T, E>::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::<T, E>::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 4d964b0afb78c..c3091bd439576 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>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _6: usize;
+            let mut _7: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
                 let mut _2: &alloc::raw_vec::RawVec<u8>;
@@ -16,6 +16,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                     let mut _3: &alloc::raw_vec::RawVecInner;
                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
                         debug self => _3;
+                        let mut _6: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
                             debug self => _3;
                             let mut _4: std::ptr::NonNull<u8>;
@@ -31,20 +32,20 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                                 }
                             }
                             scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
                                 debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
                         scope 11 (inlined NonNull::<u8>::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>) -> &[u8] {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
                     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>) -> &[u8] {
         _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
         StorageLive(_3);
         _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
+        StorageLive(_6);
+        StorageLive(_4);
         _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
         _5 = copy (_4.0: *const u8);
+        _6 = NonNull::<u8> { 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 4d964b0afb78c..c3091bd439576 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>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _6: usize;
+            let mut _7: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
                 let mut _2: &alloc::raw_vec::RawVec<u8>;
@@ -16,6 +16,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                     let mut _3: &alloc::raw_vec::RawVecInner;
                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
                         debug self => _3;
+                        let mut _6: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
                             debug self => _3;
                             let mut _4: std::ptr::NonNull<u8>;
@@ -31,20 +32,20 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                                 }
                             }
                             scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
                                 debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
                         scope 11 (inlined NonNull::<u8>::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>) -> &[u8] {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
                     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>) -> &[u8] {
         _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
         StorageLive(_3);
         _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
+        StorageLive(_6);
+        StorageLive(_4);
         _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
         _5 = copy (_4.0: *const u8);
+        _6 = NonNull::<u8> { 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/simplify_aggregate_to_copy_miscompile.foo.GVN.diff b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff
new file mode 100644
index 0000000000000..22d4277ee4515
--- /dev/null
+++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff
@@ -0,0 +1,72 @@
+- // MIR for `foo` before GVN
++ // MIR for `foo` after GVN
+  
+  fn foo(_1: &mut Option<i32>) -> Option<i32> {
+      debug v => _1;
+      let mut _0: std::option::Option<i32>;
+      let mut _2: &std::option::Option<i32>;
+      let mut _3: &std::option::Option<i32>;
+      let _4: &&mut std::option::Option<i32>;
+      let mut _5: isize;
+      let mut _7: !;
+      let mut _8: std::option::Option<i32>;
+      let mut _9: i32;
+      let mut _10: !;
+      let mut _11: &mut std::option::Option<i32>;
+      scope 1 {
+          debug col => _6;
+          let _6: i32;
+      }
+  
+      bb0: {
+-         StorageLive(_2);
++         nop;
+          StorageLive(_3);
+          StorageLive(_4);
+          _4 = &_1;
+-         _11 = deref_copy (*_4);
+-         _3 = &(*_11);
++         _11 = copy _1;
++         _3 = &(*_1);
+          _2 = get(move _3) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_3);
+          _5 = discriminant((*_2));
+          switchInt(move _5) -> [1: bb2, otherwise: bb3];
+      }
+  
+      bb2: {
+-         StorageLive(_6);
++         nop;
+          _6 = copy (((*_2) as Some).0: i32);
+          StorageLive(_8);
+-         _8 = Option::<i32>::None;
+-         (*_1) = move _8;
++         _8 = const Option::<i32>::None;
++         (*_1) = const Option::<i32>::None;
+          StorageDead(_8);
+          StorageLive(_9);
+          _9 = copy _6;
+-         _0 = Option::<i32>::Some(move _9);
++         _0 = copy (*_2);
+          StorageDead(_9);
+-         StorageDead(_6);
++         nop;
+          StorageDead(_4);
+-         StorageDead(_2);
++         nop;
+          return;
+      }
+  
+      bb3: {
+          StorageLive(_10);
+          unreachable;
+      }
++ }
++ 
++ ALLOC0 (size: 8, align: 4) {
++     00 00 00 00 __ __ __ __                         │ ....░░░░
+  }
+  
diff --git a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs
new file mode 100644
index 0000000000000..47721b768be79
--- /dev/null
+++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs
@@ -0,0 +1,32 @@
+//! The `simplify_aggregate_to_copy` mir-opt introduced in
+//! <https://github.com/rust-lang/rust/pull/128299> caused a miscompile because the initial
+//! implementation
+//!
+//! > introduce[d] new dereferences without checking for aliasing
+//!
+//! This test demonstrates the behavior, and should be adjusted or removed when fixing and relanding
+//! the mir-opt.
+#![crate_type = "lib"]
+// skip-filecheck
+//@ compile-flags: -O -Zunsound-mir-opts
+//@ test-mir-pass: GVN
+#![allow(internal_features)]
+#![feature(rustc_attrs, core_intrinsics)]
+
+// EMIT_MIR simplify_aggregate_to_copy_miscompile.foo.GVN.diff
+#[no_mangle]
+fn foo(v: &mut Option<i32>) -> Option<i32> {
+    if let &Some(col) = get(&v) {
+        *v = None;
+        return Some(col);
+    } else {
+        unsafe { std::intrinsics::unreachable() }
+    }
+}
+
+#[no_mangle]
+#[inline(never)]
+#[rustc_nounwind]
+fn get(v: &Option<i32>) -> &Option<i32> {
+    v
+}
diff --git a/tests/ui/mir/clone-canonicalization-miscompile-132353.rs b/tests/ui/mir/clone-canonicalization-miscompile-132353.rs
new file mode 100644
index 0000000000000..ba740c10f9060
--- /dev/null
+++ b/tests/ui/mir/clone-canonicalization-miscompile-132353.rs
@@ -0,0 +1,25 @@
+//! The mir-opt added in <https://github.com/rust-lang/rust/pull/128299> unfortunately seems to lead
+//! to a miscompile (reported in <https://github.com/rust-lang/rust/issues/132353>, minimization
+//! reproduced in this test file).
+//@ revisions: release debug
+// Note: it's not strictly cargo's release profile, but any non-zero opt-level was sufficient to
+// reproduce the miscompile.
+//@[release] compile-flags: -C opt-level=1
+//@[debug] compile-flags: -C opt-level=0
+//@ run-pass
+
+fn pop_min(mut score2head: Vec<Option<usize>>) -> Option<usize> {
+    loop {
+        if let Some(col) = score2head[0] {
+            score2head[0] = None;
+            return Some(col);
+        }
+    }
+}
+
+fn main() {
+    let min = pop_min(vec![Some(1)]);
+    println!("min: {:?}", min);
+    // panic happened on 1.83.0 beta in release mode but not debug mode.
+    let _ = min.unwrap();
+}