Skip to content

Commit 2d27088

Browse files
committed
detect when unused bits of a SIMD bitmask are non-0
1 parent 0a46506 commit 2d27088

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

src/shims/intrinsics.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
657657
let val = if mask != 0 { yes } else { no };
658658
this.write_immediate(*val, &dest.into())?;
659659
}
660+
for i in dest_len..dest_len.max(8) {
661+
// If the mask is "padded", ensure that padding is all-zero.
662+
let mask =
663+
mask & (1 << simd_bitmask_index(i, dest_len, this.data_layout().endian));
664+
if mask != 0 {
665+
throw_ub_format!(
666+
"a SIMD bitmask less than 8 bits long must be filled with 0s for the remaining bits"
667+
);
668+
}
669+
}
660670
}
661671
#[rustfmt::skip]
662672
"simd_cast" | "simd_as" => {
@@ -1336,7 +1346,7 @@ fn simd_element_to_bool<'tcx>(elem: ImmTy<'tcx, Tag>) -> InterpResult<'tcx, bool
13361346
}
13371347

13381348
fn simd_bitmask_index(idx: u64, len: u64, endianess: Endian) -> u64 {
1339-
assert!(idx < len);
1349+
assert!(idx < len.max(8));
13401350
match endianess {
13411351
Endian::Little => idx,
13421352
Endian::Big => len.max(8) - 1 - idx, // reverse order of bits
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(platform_intrinsics, repr_simd)]
2+
3+
extern "platform-intrinsic" {
4+
fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T;
5+
}
6+
7+
#[repr(simd)]
8+
#[allow(non_camel_case_types)]
9+
#[derive(Copy, Clone)]
10+
struct i32x2(i32, i32);
11+
12+
fn main() { unsafe {
13+
let x = i32x2(0, 1);
14+
simd_select_bitmask(0b11111111u8, x, x); //~ERROR bitmask less than 8 bits long must be filled with 0s for the remaining bits
15+
} }
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(platform_intrinsics, repr_simd)]
2+
3+
extern "platform-intrinsic" {
4+
fn simd_select<M, T>(m: M, yes: T, no: T) -> T;
5+
}
6+
7+
#[repr(simd)]
8+
#[allow(non_camel_case_types)]
9+
#[derive(Copy, Clone)]
10+
struct i32x2(i32, i32);
11+
12+
fn main() { unsafe {
13+
let x = i32x2(0, 1);
14+
simd_select(x, x, x); //~ERROR must be all-0-bits or all-1-bits
15+
} }

0 commit comments

Comments
 (0)