Rollup merge of #137852 - moulins:layout-nonarray-simd-deadcode, r=workingjubilee
Remove layouting dead code for non-array SIMD types. These aren't supported anymore, and are already rejected in type checking.
This commit is contained in:
commit
74e9ca6772
4 changed files with 30 additions and 114 deletions
|
@ -42,8 +42,6 @@ ty_utils_logical_op_not_supported = unsupported operation in generic constants,
|
|||
|
||||
ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants
|
||||
|
||||
ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with more than one array field
|
||||
|
||||
ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop
|
||||
|
||||
ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants
|
||||
|
|
|
@ -82,12 +82,6 @@ pub(crate) struct ZeroLengthSimdType<'tcx> {
|
|||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ty_utils_multiple_array_fields_simd_type)]
|
||||
pub(crate) struct MultipleArrayFieldsSimdType<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ty_utils_oversized_simd_type)]
|
||||
pub(crate) struct OversizedSimdType<'tcx> {
|
||||
|
|
|
@ -28,9 +28,7 @@ use rustc_span::{Symbol, sym};
|
|||
use tracing::{debug, instrument, trace};
|
||||
use {rustc_abi as abi, rustc_hir as hir};
|
||||
|
||||
use crate::errors::{
|
||||
MultipleArrayFieldsSimdType, NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType,
|
||||
};
|
||||
use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType};
|
||||
|
||||
mod invariant;
|
||||
|
||||
|
@ -450,71 +448,26 @@ fn layout_of_uncached<'tcx>(
|
|||
|
||||
// SIMD vector types.
|
||||
ty::Adt(def, args) if def.repr().simd() => {
|
||||
if !def.is_struct() {
|
||||
// Should have yielded E0517 by now.
|
||||
let guar = tcx
|
||||
.dcx()
|
||||
.delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
|
||||
return Err(error(cx, LayoutError::ReferencesError(guar)));
|
||||
}
|
||||
|
||||
let fields = &def.non_enum_variant().fields;
|
||||
|
||||
// Supported SIMD vectors are homogeneous ADTs with at least one field:
|
||||
// Supported SIMD vectors are ADTs with a single array field:
|
||||
//
|
||||
// * #[repr(simd)] struct S(T, T, T, T);
|
||||
// * #[repr(simd)] struct S { x: T, y: T, z: T, w: T }
|
||||
// * #[repr(simd)] struct S([T; 4])
|
||||
//
|
||||
// where T is a primitive scalar (integer/float/pointer).
|
||||
|
||||
// SIMD vectors with zero fields are not supported.
|
||||
// (should be caught by typeck)
|
||||
if fields.is_empty() {
|
||||
tcx.dcx().emit_fatal(ZeroLengthSimdType { ty })
|
||||
}
|
||||
|
||||
// Type of the first ADT field:
|
||||
let f0_ty = fields[FieldIdx::ZERO].ty(tcx, args);
|
||||
|
||||
// Heterogeneous SIMD vectors are not supported:
|
||||
// (should be caught by typeck)
|
||||
for fi in fields {
|
||||
if fi.ty(tcx, args) != f0_ty {
|
||||
let guar = tcx.dcx().delayed_bug(
|
||||
"#[repr(simd)] was applied to an ADT with heterogeneous field type",
|
||||
);
|
||||
return Err(error(cx, LayoutError::ReferencesError(guar)));
|
||||
}
|
||||
}
|
||||
|
||||
// The element type and number of elements of the SIMD vector
|
||||
// are obtained from:
|
||||
//
|
||||
// * the element type and length of the single array field, if
|
||||
// the first field is of array type, or
|
||||
//
|
||||
// * the homogeneous field type and the number of fields.
|
||||
let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() {
|
||||
// First ADT field is an array:
|
||||
|
||||
// SIMD vectors with multiple array fields are not supported:
|
||||
// Can't be caught by typeck with a generic simd type.
|
||||
if def.non_enum_variant().fields.len() != 1 {
|
||||
tcx.dcx().emit_fatal(MultipleArrayFieldsSimdType { ty });
|
||||
}
|
||||
|
||||
// Extract the number of elements from the layout of the array field:
|
||||
let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else {
|
||||
return Err(error(cx, LayoutError::Unknown(ty)));
|
||||
};
|
||||
|
||||
(*e_ty, *count, true)
|
||||
} else {
|
||||
// First ADT field is not an array:
|
||||
(f0_ty, def.non_enum_variant().fields.len() as _, false)
|
||||
let Some(ty::Array(e_ty, e_len)) = def
|
||||
.is_struct()
|
||||
.then(|| &def.variant(FIRST_VARIANT).fields)
|
||||
.filter(|fields| fields.len() == 1)
|
||||
.map(|fields| *fields[FieldIdx::ZERO].ty(tcx, args).kind())
|
||||
else {
|
||||
// Invalid SIMD types should have been caught by typeck by now.
|
||||
let guar = tcx.dcx().delayed_bug("#[repr(simd)] was applied to an invalid ADT");
|
||||
return Err(error(cx, LayoutError::ReferencesError(guar)));
|
||||
};
|
||||
|
||||
let e_len = extract_const_value(cx, ty, e_len)?
|
||||
.try_to_target_usize(tcx)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
|
||||
// SIMD vectors of zero length are not supported.
|
||||
// Additionally, lengths are capped at 2^16 as a fixed maximum backends must
|
||||
// support.
|
||||
|
@ -559,16 +512,12 @@ fn layout_of_uncached<'tcx>(
|
|||
};
|
||||
let size = size.align_to(align.abi);
|
||||
|
||||
// Compute the placement of the vector fields:
|
||||
let fields = if is_array {
|
||||
FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }
|
||||
} else {
|
||||
FieldsShape::Array { stride: e_ly.size, count: e_len }
|
||||
};
|
||||
|
||||
tcx.mk_layout(LayoutData {
|
||||
variants: Variants::Single { index: FIRST_VARIANT },
|
||||
fields,
|
||||
fields: FieldsShape::Arbitrary {
|
||||
offsets: [Size::ZERO].into(),
|
||||
memory_index: [0].into(),
|
||||
},
|
||||
backend_repr: abi,
|
||||
largest_niche: e_ly.largest_niche,
|
||||
uninhabited: false,
|
||||
|
|
|
@ -133,40 +133,22 @@ fn layout_of_simd_ty(
|
|||
env: Arc<TraitEnvironment>,
|
||||
dl: &TargetDataLayout,
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
let fields = db.field_types(id.into());
|
||||
|
||||
// Supported SIMD vectors are homogeneous ADTs with at least one field:
|
||||
// Supported SIMD vectors are homogeneous ADTs with exactly one array field:
|
||||
//
|
||||
// * #[repr(simd)] struct S(T, T, T, T);
|
||||
// * #[repr(simd)] struct S { it: T, y: T, z: T, w: T }
|
||||
// * #[repr(simd)] struct S([T; 4])
|
||||
//
|
||||
// where T is a primitive scalar (integer/float/pointer).
|
||||
|
||||
let f0_ty = match fields.iter().next() {
|
||||
Some(it) => it.1.clone().substitute(Interner, subst),
|
||||
None => return Err(LayoutError::InvalidSimdType),
|
||||
let fields = db.field_types(id.into());
|
||||
let mut fields = fields.iter();
|
||||
let Some(TyKind::Array(e_ty, e_len)) = fields
|
||||
.next()
|
||||
.filter(|_| fields.next().is_none())
|
||||
.map(|f| f.1.clone().substitute(Interner, subst).kind(Interner).clone())
|
||||
else {
|
||||
return Err(LayoutError::InvalidSimdType);
|
||||
};
|
||||
|
||||
// The element type and number of elements of the SIMD vector
|
||||
// are obtained from:
|
||||
//
|
||||
// * the element type and length of the single array field, if
|
||||
// the first field is of array type, or
|
||||
//
|
||||
// * the homogeneous field type and the number of fields.
|
||||
let (e_ty, e_len, is_array) = if let TyKind::Array(e_ty, _) = f0_ty.kind(Interner) {
|
||||
// Extract the number of elements from the layout of the array field:
|
||||
let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields
|
||||
else {
|
||||
return Err(LayoutError::Unknown);
|
||||
};
|
||||
|
||||
(e_ty.clone(), count, true)
|
||||
} else {
|
||||
// First ADT field is not an array:
|
||||
(f0_ty, fields.iter().count() as u64, false)
|
||||
};
|
||||
let e_len = try_const_usize(db, &e_len).ok_or(LayoutError::HasErrorConst)? as u64;
|
||||
|
||||
// Compute the ABI of the element type:
|
||||
let e_ly = db.layout_of_ty(e_ty, env)?;
|
||||
|
@ -182,16 +164,9 @@ fn layout_of_simd_ty(
|
|||
let align = dl.llvmlike_vector_align(size);
|
||||
let size = size.align_to(align.abi);
|
||||
|
||||
// Compute the placement of the vector fields:
|
||||
let fields = if is_array {
|
||||
FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }
|
||||
} else {
|
||||
FieldsShape::Array { stride: e_ly.size, count: e_len }
|
||||
};
|
||||
|
||||
Ok(Arc::new(Layout {
|
||||
variants: Variants::Single { index: struct_variant_idx() },
|
||||
fields,
|
||||
fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() },
|
||||
backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len },
|
||||
largest_niche: e_ly.largest_niche,
|
||||
uninhabited: false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue