Skip to content

Commit ff40897

Browse files
committed
Revert model change and add new test
The change was only needed in the test case, since the way portable simd invokes the intrinsic is still the same My current hypothesis is that the current failure could be an issue with simd_shuffle
1 parent 505700a commit ff40897

File tree

2 files changed

+46
-24
lines changed

2 files changed

+46
-24
lines changed

library/kani/src/models/mod.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,11 @@ mod intrinsics {
6969
}
7070

7171
#[cfg(target_endian = "little")]
72-
unsafe fn simd_bitmask_impl<T, const LANES: usize, const MASK_LEN: usize>(
73-
input: &[T; LANES],
74-
) -> [u8; MASK_LEN]
72+
unsafe fn simd_bitmask_impl<T, const LANES: usize>(input: &[T; LANES]) -> [u8; mask_len(LANES)]
7573
where
7674
T: MaskElement,
7775
{
78-
let mut mask_array = [0; MASK_LEN];
76+
let mut mask_array = [0; mask_len(LANES)];
7977
for lane in (0..input.len()).rev() {
8078
let byte = lane / 8;
8179
let mask = &mut mask_array[byte];
@@ -101,13 +99,14 @@ mod intrinsics {
10199
#[rustc_diagnostic_item = "KaniModelSimdBitmask"]
102100
pub(super) unsafe fn simd_bitmask<T, U, E, const LANES: usize>(input: T) -> U
103101
where
104-
[u8; size_of::<U>()]: Sized,
102+
[u8; mask_len(LANES)]: Sized,
105103
E: MaskElement,
106104
{
107105
// These checks are compiler sanity checks to ensure we are not doing anything invalid.
108-
assert!(
109-
size_of::<U>() >= mask_len(LANES),
110-
"Expected size of return type to be greater or equal to the mask lanes",
106+
assert_eq!(
107+
size_of::<U>(),
108+
size_of::<[u8; mask_len(LANES)]>(),
109+
"Expected size of return type and mask lanes to match",
111110
);
112111
assert_eq!(
113112
size_of::<T>(),
@@ -116,8 +115,8 @@ mod intrinsics {
116115
);
117116

118117
let data = &*(&input as *const T as *const [E; LANES]);
119-
let mask = simd_bitmask_impl::<E, LANES, { size_of::<U>() }>(data);
120-
(&mask as *const [u8; size_of::<U>()] as *const U).read()
118+
let mask = simd_bitmask_impl(data);
119+
(&mask as *const [u8; mask_len(LANES)] as *const U).read()
121120
}
122121

123122
/// Structure used for sanity check our parameters.
@@ -128,7 +127,7 @@ mod intrinsics {
128127
#[cfg(test)]
129128
mod test {
130129
use super::intrinsics as kani_intrinsic;
131-
use std::{fmt::Debug, mem::size_of, simd::*};
130+
use std::{fmt::Debug, simd::*};
132131

133132
extern "platform-intrinsic" {
134133
fn simd_bitmask<T, U>(x: T) -> U;
@@ -138,8 +137,8 @@ mod test {
138137
/// masks with lanes represented using i16.
139138
#[test]
140139
fn test_bitmask_i16() {
141-
check_portable_bitmask::<_, i16, 16>(mask16x16::splat(false));
142-
check_portable_bitmask::<_, i16, 16>(mask16x16::splat(true));
140+
check_portable_bitmask::<_, i16, 16, u16>(mask16x16::splat(false));
141+
check_portable_bitmask::<_, i16, 16, u16>(mask16x16::splat(true));
143142
}
144143

145144
/// Tests that the model correctly fails if an invalid value is given.
@@ -156,23 +155,21 @@ mod test {
156155
/// Tests that the model correctly fails if the size parameter of the mask doesn't match the
157156
/// expected number of bytes in the representation.
158157
#[test]
159-
#[should_panic(
160-
expected = "Expected size of return type to be greater or equal to the mask lanes"
161-
)]
158+
#[should_panic(expected = "Expected size of return type and mask lanes to match")]
162159
fn test_invalid_generics() {
163-
let mask = mask32x32::splat(false);
164-
assert_eq!(unsafe { kani_intrinsic::simd_bitmask::<_, u8, i32, 32>(mask) }, u8::MAX);
160+
let mask = mask32x16::splat(false);
161+
assert_eq!(unsafe { kani_intrinsic::simd_bitmask::<_, u16, i32, 2>(mask) }, u16::MAX);
165162
}
166163

167164
/// Test that the `simd_bitmask` model is equivalent to the intrinsic for a few random values.
168165
/// These values shouldn't be symmetric and ensure that we also handle endianness correctly.
169166
#[test]
170167
fn test_bitmask_i32() {
171-
check_portable_bitmask::<_, i32, 8>(mask32x8::from([
168+
check_portable_bitmask::<_, i32, 8, u8>(mask32x8::from([
172169
true, true, false, true, false, false, false, true,
173170
]));
174171

175-
check_portable_bitmask::<_, i32, 4>(mask32x4::from([true, false, false, true]));
172+
check_portable_bitmask::<_, i32, 4, u8>(mask32x4::from([true, false, false, true]));
176173
}
177174

178175
#[repr(simd)]
@@ -188,14 +185,16 @@ mod test {
188185
}
189186

190187
/// Compare the value returned by our model and the portable simd representation.
191-
fn check_portable_bitmask<T, E, const LANES: usize>(mask: Mask<T, LANES>)
188+
fn check_portable_bitmask<T, E, const LANES: usize, M>(mask: Mask<T, LANES>)
192189
where
193190
T: std::simd::MaskElement,
194191
LaneCount<LANES>: SupportedLaneCount,
195192
E: kani_intrinsic::MaskElement,
193+
[u8; kani_intrinsic::mask_len(LANES)]: Sized,
194+
u64: From<M>,
196195
{
197196
assert_eq!(
198-
unsafe { kani_intrinsic::simd_bitmask::<_, u64, E, LANES>(mask.clone()) },
197+
unsafe { u64::from(kani_intrinsic::simd_bitmask::<_, M, E, LANES>(mask.clone())) },
199198
mask.to_bitmask()
200199
);
201200
}
@@ -206,11 +205,26 @@ mod test {
206205
T: Clone,
207206
U: PartialEq + Debug,
208207
E: kani_intrinsic::MaskElement,
209-
[u8; size_of::<U>()]: Sized,
208+
[u8; kani_intrinsic::mask_len(LANES)]: Sized,
210209
{
211210
assert_eq!(
212211
unsafe { kani_intrinsic::simd_bitmask::<_, U, E, LANES>(mask.clone()) },
213212
unsafe { simd_bitmask::<T, U>(mask) }
214213
);
215214
}
215+
216+
/// Similar to portable simd_harness.
217+
#[test]
218+
fn check_mask_harness() {
219+
// From array doesn't work either. Manually build [false, true, false, true]
220+
let mut mask = mask32x4::splat(false);
221+
mask.set(1, true);
222+
mask.set(3, true);
223+
let bitmask = mask.to_bitmask();
224+
assert_eq!(bitmask, 0b1010);
225+
226+
let kani_mask = unsafe { u64::from(kani_intrinsic::simd_bitmask::<_, u8, u32, 4>(mask.clone())) };
227+
assert_eq!(kani_mask, bitmask);
228+
}
229+
216230
}

tests/kani/SIMD/portable_simd.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! Ensure we have basic support of portable SIMD.
55
#![feature(portable_simd)]
66

7-
use std::simd::{mask32x4, u64x16};
7+
use std::simd::{mask32x4, u32x4, u64x16};
88

99
#[kani::proof]
1010
fn check_sum_any() {
@@ -23,3 +23,11 @@ fn check_mask() {
2323
let bitmask = mask.to_bitmask();
2424
assert_eq!(bitmask, 0b1010);
2525
}
26+
27+
#[kani::proof]
28+
fn check_resize() {
29+
let x = u32x4::from_array([0, 1, 2, 3]);
30+
assert_eq!(x.resize::<8>(9).to_array(), [0, 1, 2, 3, 9, 9, 9, 9]);
31+
assert_eq!(x.resize::<2>(9).to_array(), [0, 1]);
32+
33+
}

0 commit comments

Comments
 (0)