diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index d7fe7801fb082..0cfb9bd6d7940 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -2,7 +2,6 @@ use either::Either; use rustc_abi::{BackendRepr, Endian}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, Round}; -use rustc_data_structures::assert_matches; use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo}; use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign}; use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty}; @@ -829,7 +828,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { vector_layout: TyAndLayout<'tcx>, alignment: SimdAlign, ) -> InterpResult<'tcx> { - assert_matches!(vector_layout.backend_repr, BackendRepr::SimdVector { .. }); + // Packed SIMD types with non-power-of-two element counts use BackendRepr::Memory + // instead of BackendRepr::SimdVector. We need to handle both cases. + // FIXME: remove the BackendRepr::Memory case when SIMD vectors are always passed as BackendRepr::SimdVector. + assert!(vector_layout.ty.is_simd(), "check_simd_ptr_alignment called on non-SIMD type"); + match vector_layout.backend_repr { + BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => {} + _ => { + span_bug!( + self.cur_span(), + "SIMD type has unexpected backend_repr: {:?}", + vector_layout.backend_repr + ); + } + } let align = match alignment { ty::SimdAlign::Unaligned => { diff --git a/tests/ui/consts/const-eval/simd/simd-packed-non-pow2.rs b/tests/ui/consts/const-eval/simd/simd-packed-non-pow2.rs new file mode 100644 index 0000000000000..f09e52e9298bb --- /dev/null +++ b/tests/ui/consts/const-eval/simd/simd-packed-non-pow2.rs @@ -0,0 +1,18 @@ +//@ check-pass +// Fixes #151537 +#![feature(portable_simd, core_intrinsics)] +use std::intrinsics::simd::SimdAlign; +use std::{ptr::null, simd::prelude::*}; + +const _: () = { + let c = Simd::from_array([0; 3]); + unsafe { + core::intrinsics::simd::simd_masked_store::<_, _, _, { SimdAlign::Element }>( + c, + null::(), + c, + ) + }; +}; + +fn main() {}