about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2025-01-05 23:27:24 -0800
committerScott McMurray <scottmcm@users.noreply.github.com>2025-01-08 18:46:31 -0800
commitb421a563644dafdb8a5a9c48fe21c4a449da18fa (patch)
treeff4482b81cbc881ca12d30f247fef09f30583fed /compiler/rustc_mir_transform/src
parent293f8e8941e77c6372abd787fe564e9bf895445e (diff)
downloadrust-b421a563644dafdb8a5a9c48fe21c4a449da18fa.tar.gz
rust-b421a563644dafdb8a5a9c48fe21c4a449da18fa.zip
Make the aggregate-then-transmute handling more general
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs22
1 files changed, 9 insertions, 13 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 7c600fc1ceb..71bec38c405 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -1370,12 +1370,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         loop {
             let mut was_updated_this_iteration = false;
 
-            // Transmuting `*const T` <=> `*mut T` is just a pointer cast,
-            // which we might be able to merge with other ones later.
+            // Transmuting between raw pointers is just a pointer cast so long as
+            // they have the same metadata type (like `*const i32` <=> `*mut u64`
+            // or `*mut [i32]` <=> `*const [u64]`), including the common special
+            // case of `*const T` <=> `*mut T`.
             if let Transmute = kind
-                && let ty::RawPtr(from_pointee, _) = from.kind()
-                && let ty::RawPtr(to_pointee, _) = to.kind()
-                && from_pointee == to_pointee
+                && from.is_unsafe_ptr()
+                && to.is_unsafe_ptr()
+                && self.pointers_have_same_metadata(from, to)
             {
                 *kind = PtrToPtr;
                 was_updated_this_iteration = true;
@@ -1400,15 +1402,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             // Aggregate-then-Transmute can just transmute the original field value,
             // so long as the bytes of a value from only from a single field.
             if let Transmute = kind
-                && let Value::Aggregate(
-                    AggregateTy::Def(aggregate_did, aggregate_args),
-                    variant_idx,
-                    field_values,
-                ) = self.get(value)
-                && let aggregate_ty =
-                    self.tcx.type_of(aggregate_did).instantiate(self.tcx, aggregate_args)
+                && let Value::Aggregate(_aggregate_ty, variant_idx, field_values) = self.get(value)
                 && let Some((field_idx, field_ty)) =
-                    self.value_is_all_in_one_field(aggregate_ty, *variant_idx)
+                    self.value_is_all_in_one_field(from, *variant_idx)
             {
                 from = field_ty;
                 value = field_values[field_idx.as_usize()];