1
Fork 0

compiler: BackendRepr::inherent_{size,align} -> scalar_{size,align}

This pair of fn was introduced to perform invariant checks for scalars.
Their current behavior doesn't mesh as well with checking SIMD types,
so change the name of the fn to reflect their actual use-case and
refactor the corresponding checks.

Also simplify the returns from Option<AbiAndPrefAlign> to Option<Align>,
because every site was mapping away the "preferred" alignment anyways.
This commit is contained in:
Jubilee Young 2025-02-18 18:53:15 -08:00
parent efff15afea
commit 5c474fd99b
3 changed files with 78 additions and 63 deletions

View file

@ -69,31 +69,30 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
}
fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) {
// Verify the ABI mandated alignment and size.
let align = layout.backend_repr.inherent_align(cx).map(|align| align.abi);
let size = layout.backend_repr.inherent_size(cx);
let Some((align, size)) = align.zip(size) else {
assert_matches!(
layout.layout.backend_repr(),
BackendRepr::Memory { .. },
"ABI unexpectedly missing alignment and/or size in {layout:#?}"
// Verify the ABI-mandated alignment and size for scalars.
let align = layout.backend_repr.scalar_align(cx);
let size = layout.backend_repr.scalar_size(cx);
if let Some(align) = align {
assert_eq!(
layout.layout.align().abi,
align,
"alignment mismatch between ABI and layout in {layout:#?}"
);
return;
};
assert_eq!(
layout.layout.align().abi,
align,
"alignment mismatch between ABI and layout in {layout:#?}"
);
assert_eq!(
layout.layout.size(),
size,
"size mismatch between ABI and layout in {layout:#?}"
);
}
if let Some(size) = size {
assert_eq!(
layout.layout.size(),
size,
"size mismatch between ABI and layout in {layout:#?}"
);
}
// Verify per-ABI invariants
match layout.layout.backend_repr() {
BackendRepr::Scalar(_) => {
// These must always be present for `Scalar` types.
let align = align.unwrap();
let size = size.unwrap();
// Check that this matches the underlying field.
let inner = skip_newtypes(cx, layout);
assert!(
@ -235,9 +234,15 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
"`ScalarPair` second field with bad ABI in {inner:#?}",
);
}
BackendRepr::Vector { element, .. } => {
assert!(align >= element.align(cx).abi); // just sanity-checking `vector_align`.
// FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair.
BackendRepr::Vector { element, count } => {
let align = layout.align.abi;
let size = layout.size;
let element_align = element.align(cx).abi;
let element_size = element.size(cx);
// Currently, vectors must always be aligned to at least their elements:
assert!(align >= element_align);
// And the size has to be element * count plus alignment padding, of course
assert!(size == (element_size * count).align_to(align));
}
BackendRepr::Memory { .. } => {} // Nothing to check.
}