diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-01-05 23:27:24 -0800 |
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-01-08 18:46:31 -0800 |
| commit | b421a563644dafdb8a5a9c48fe21c4a449da18fa (patch) | |
| tree | ff4482b81cbc881ca12d30f247fef09f30583fed /compiler/rustc_mir_transform/src | |
| parent | 293f8e8941e77c6372abd787fe564e9bf895445e (diff) | |
| download | rust-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.rs | 22 |
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()]; |
