|
5 | 5 | use either::{Either, Left, Right}; |
6 | 6 | use rustc_abi::{BackendRepr, HasDataLayout, Size}; |
7 | 7 | use rustc_data_structures::assert_matches; |
8 | | -use rustc_middle::ty::Ty; |
9 | 8 | use rustc_middle::ty::layout::TyAndLayout; |
| 9 | +use rustc_middle::ty::{self, Ty}; |
10 | 10 | use rustc_middle::{bug, mir, span_bug}; |
11 | 11 | use tracing::field::Empty; |
12 | 12 | use tracing::{instrument, trace}; |
@@ -884,18 +884,27 @@ where |
884 | 884 | dest.layout().ty, |
885 | 885 | ); |
886 | 886 | } |
887 | | - // If the source has padding, we want to always do the mem-to-mem copy to ensure consistent |
| 887 | + // If the source has padding, we want to always do a mem-to-mem copy to ensure consistent |
888 | 888 | // padding in the target independent of layout choices. |
889 | 889 | let src_has_padding = match src.layout().backend_repr { |
890 | 890 | BackendRepr::Scalar(_) => false, |
| 891 | + BackendRepr::ScalarPair(left, right) |
| 892 | + if matches!(src.layout().ty.kind(), ty::Ref(..) | ty::RawPtr(..)) => |
| 893 | + { |
| 894 | + // Wide pointers never have padding, so we can avoid calling `size()`. |
| 895 | + debug_assert_eq!(left.size(self) + right.size(self), src.layout().size); |
| 896 | + false |
| 897 | + } |
891 | 898 | BackendRepr::ScalarPair(left, right) => { |
892 | 899 | let left_size = left.size(self); |
893 | 900 | let right_size = right.size(self); |
894 | 901 | // We have padding if the sizes don't add up to the total. |
895 | 902 | left_size + right_size != src.layout().size |
896 | 903 | } |
897 | | - // Everything else can only exist in memory anyway. |
898 | | - _ => true, |
| 904 | + // Everything else can only exist in memory anyway, so it doesn't matter. |
| 905 | + BackendRepr::SimdVector { .. } |
| 906 | + | BackendRepr::ScalableVector { .. } |
| 907 | + | BackendRepr::Memory { .. } => true, |
899 | 908 | }; |
900 | 909 |
|
901 | 910 | let src_val = if src_has_padding { |
|
0 commit comments