Skip to content

Commit 9f73e62

Browse files
authored
Unrolled build for rust-lang#126184
Rollup merge of rust-lang#126184 - RalfJung:interpret-simd-nonpow2, r=oli-obk interpret: do not ICE on padded non-pow2 SIMD vectors Fixes rust-lang/miri#3458 r? ``@oli-obk``
2 parents d402830 + d5fb825 commit 9f73e62

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

compiler/rustc_const_eval/src/interpret/place.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -499,13 +499,14 @@ where
499499
&self,
500500
mplace: &MPlaceTy<'tcx, M::Provenance>,
501501
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::Provenance>, u64)> {
502-
// Basically we just transmute this place into an array following simd_size_and_type.
503-
// (Transmuting is okay since this is an in-memory place. We also double-check the size
504-
// stays the same.)
502+
// Basically we want to transmute this place into an array following simd_size_and_type.
505503
let (len, e_ty) = mplace.layout.ty.simd_size_and_type(*self.tcx);
506-
let array = Ty::new_array(self.tcx.tcx, e_ty, len);
507-
let layout = self.layout_of(array)?;
508-
let mplace = mplace.transmute(layout, self)?;
504+
// Some SIMD types have padding, so `len` many `e_ty` does not cover the entire place.
505+
// Therefore we cannot transmute, and instead we project at offset 0, which side-steps
506+
// the size check.
507+
let array_layout = self.layout_of(Ty::new_array(self.tcx.tcx, e_ty, len))?;
508+
assert!(array_layout.size <= mplace.layout.size);
509+
let mplace = mplace.offset(Size::ZERO, array_layout, self)?;
509510
Ok((mplace, len))
510511
}
511512

compiler/rustc_const_eval/src/interpret/projection.rs

+2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
8181
ecx: &InterpCx<'tcx, M>,
8282
) -> InterpResult<'tcx, Self> {
8383
assert!(layout.is_sized());
84+
// We sometimes do pointer arithmetic with this function, disregarding the source type.
85+
// So we don't check the sizes here.
8486
self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx)
8587
}
8688

src/tools/miri/tests/pass/intrinsics/portable-simd.rs

+21
Original file line numberDiff line numberDiff line change
@@ -658,11 +658,32 @@ fn simd_masked_loadstore() {
658658
assert_eq!(buf, [2, 3, 4]);
659659
}
660660

661+
fn simd_ops_non_pow2() {
662+
// Just a little smoke test for operations on non-power-of-two vectors.
663+
#[repr(simd, packed)]
664+
#[derive(Copy, Clone)]
665+
pub struct SimdPacked<T, const N: usize>([T; N]);
666+
#[repr(simd)]
667+
#[derive(Copy, Clone)]
668+
pub struct SimdPadded<T, const N: usize>([T; N]);
669+
670+
let x = SimdPacked([1u32; 3]);
671+
let y = SimdPacked([2u32; 3]);
672+
let z = unsafe { intrinsics::simd_add(x, y) };
673+
assert_eq!({ z.0 }, [3u32; 3]);
674+
675+
let x = SimdPadded([1u32; 3]);
676+
let y = SimdPadded([2u32; 3]);
677+
let z = unsafe { intrinsics::simd_add(x, y) };
678+
assert_eq!(z.0, [3u32; 3]);
679+
}
680+
661681
fn main() {
662682
simd_mask();
663683
simd_ops_f32();
664684
simd_ops_f64();
665685
simd_ops_i32();
686+
simd_ops_non_pow2();
666687
simd_cast();
667688
simd_swizzle();
668689
simd_gather_scatter();

0 commit comments

Comments
 (0)