@@ -408,16 +408,21 @@ impl TargetDataLayout {
408408 }
409409 }
410410
411+ /// psABI-mandated alignment for a vector type, if any
411412 #[ inline]
412- pub fn vector_align ( & self , vec_size : Size ) -> AbiAndPrefAlign {
413- for & ( size, align) in & self . vector_align {
414- if size == vec_size {
415- return align;
416- }
417- }
418- // Default to natural alignment, which is what LLVM does.
419- // That is, use the size, rounded up to a power of 2.
420- AbiAndPrefAlign :: new ( Align :: from_bytes ( vec_size. bytes ( ) . next_power_of_two ( ) ) . unwrap ( ) )
413+ fn cabi_vector_align ( & self , vec_size : Size ) -> Option < AbiAndPrefAlign > {
414+ self . vector_align
415+ . iter ( )
416+ . find ( |( size, _align) | * size == vec_size)
417+ . map ( |( _size, align) | * align)
418+ }
419+
420+ /// an alignment resembling the one LLVM would pick for a vector
421+ #[ inline]
422+ pub fn llvmlike_vector_align ( & self , vec_size : Size ) -> AbiAndPrefAlign {
423+ self . cabi_vector_align ( vec_size) . unwrap_or ( AbiAndPrefAlign :: new (
424+ Align :: from_bytes ( vec_size. bytes ( ) . next_power_of_two ( ) ) . unwrap ( ) ,
425+ ) )
421426 }
422427}
423428
@@ -810,20 +815,19 @@ impl Align {
810815 self . bits ( ) . try_into ( ) . unwrap ( )
811816 }
812817
813- /// Computes the best alignment possible for the given offset
814- /// (the largest power of two that the offset is a multiple of).
818+ /// Obtain the greatest factor of `size` that is an alignment
819+ /// (the largest power of two the Size is a multiple of).
815820 ///
816- /// N.B., for an offset of `0`, this happens to return `2^64`.
821+ /// Note that all numbers are factors of 0
817822 #[ inline]
818- pub fn max_for_offset ( offset : Size ) -> Align {
819- Align { pow2 : offset . bytes ( ) . trailing_zeros ( ) as u8 }
823+ pub fn max_aligned_factor ( size : Size ) -> Align {
824+ Align { pow2 : size . bytes ( ) . trailing_zeros ( ) as u8 }
820825 }
821826
822- /// Lower the alignment, if necessary, such that the given offset
823- /// is aligned to it (the offset is a multiple of the alignment).
827+ /// Reduces Align to an aligned factor of `size`.
824828 #[ inline]
825- pub fn restrict_for_offset ( self , offset : Size ) -> Align {
826- self . min ( Align :: max_for_offset ( offset ) )
829+ pub fn restrict_for_offset ( self , size : Size ) -> Align {
830+ self . min ( Align :: max_aligned_factor ( size ) )
827831 }
828832}
829833
@@ -1455,37 +1459,38 @@ impl BackendRepr {
14551459 matches ! ( * self , BackendRepr :: Scalar ( s) if s. is_bool( ) )
14561460 }
14571461
1458- /// Returns the fixed alignment of this ABI, if any is mandated.
1459- pub fn inherent_align < C : HasDataLayout > ( & self , cx : & C ) -> Option < AbiAndPrefAlign > {
1460- Some ( match * self {
1461- BackendRepr :: Scalar ( s ) => s . align ( cx ) ,
1462- BackendRepr :: ScalarPair ( s1 , s2 ) => s1 . align ( cx ) . max ( s2 . align ( cx ) ) ,
1463- BackendRepr :: Vector { element , count } => {
1464- cx . data_layout ( ) . vector_align ( element . size ( cx) * count )
1465- }
1466- BackendRepr :: Memory { .. } => return None ,
1467- } )
1462+ /// The psABI alignment for a `Scalar` or `ScalarPair`
1463+ ///
1464+ /// `None` for other variants.
1465+ pub fn scalar_align < C : HasDataLayout > ( & self , cx : & C ) -> Option < Align > {
1466+ match * self {
1467+ BackendRepr :: Scalar ( s ) => Some ( s . align ( cx ) . abi ) ,
1468+ BackendRepr :: ScalarPair ( s1 , s2 ) => Some ( s1 . align ( cx ) . max ( s2 . align ( cx) ) . abi ) ,
1469+ // The align of a Vector can vary in surprising ways
1470+ BackendRepr :: Vector { .. } | BackendRepr :: Memory { .. } => None ,
1471+ }
14681472 }
14691473
1470- /// Returns the fixed size of this ABI, if any is mandated.
1471- pub fn inherent_size < C : HasDataLayout > ( & self , cx : & C ) -> Option < Size > {
1472- Some ( match * self {
1473- BackendRepr :: Scalar ( s) => {
1474- // No padding in scalars.
1475- s. size ( cx)
1476- }
1474+ /// The psABI size for a `Scalar` or `ScalarPair`
1475+ ///
1476+ /// `None` for other variants
1477+ pub fn scalar_size < C : HasDataLayout > ( & self , cx : & C ) -> Option < Size > {
1478+ match * self {
1479+ // No padding in scalars.
1480+ BackendRepr :: Scalar ( s) => Some ( s. size ( cx) ) ,
1481+ // May have some padding between the pair.
14771482 BackendRepr :: ScalarPair ( s1, s2) => {
1478- // May have some padding between the pair.
14791483 let field2_offset = s1. size ( cx) . align_to ( s2. align ( cx) . abi ) ;
1480- ( field2_offset + s2. size ( cx) ) . align_to ( self . inherent_align ( cx) ?. abi )
1484+ let size = ( field2_offset + s2. size ( cx) ) . align_to (
1485+ self . scalar_align ( cx)
1486+ // We absolutely must have an answer here or everything is FUBAR.
1487+ . unwrap ( ) ,
1488+ ) ;
1489+ Some ( size)
14811490 }
1482- BackendRepr :: Vector { element, count } => {
1483- // No padding in vectors, except possibly for trailing padding
1484- // to make the size a multiple of align (e.g. for vectors of size 3).
1485- ( element. size ( cx) * count) . align_to ( self . inherent_align ( cx) ?. abi )
1486- }
1487- BackendRepr :: Memory { .. } => return None ,
1488- } )
1491+ // The size of a Vector can vary in surprising ways
1492+ BackendRepr :: Vector { .. } | BackendRepr :: Memory { .. } => None ,
1493+ }
14891494 }
14901495
14911496 /// Discard validity range information and allow undef.
0 commit comments