Skip to content

Commit 4d7e68c

Browse files
committed
add shim for _mm512_permutexvar_epi32
1 parent 349e276 commit 4d7e68c

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/tools/miri/src/shims/x86/avx512.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,26 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
9595

9696
pmaddbw(this, left, right, dest)?;
9797
}
98+
// Used to implement the _mm512_permutexvar_epi32 function.
99+
"permvar.si.512" => {
100+
let [left, right] =
101+
this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
102+
103+
let (left, left_len) = this.project_to_simd(left)?;
104+
let (right, right_len) = this.project_to_simd(right)?;
105+
let (dest, dest_len) = this.project_to_simd(dest)?;
106+
107+
assert_eq!(dest_len, left_len);
108+
assert_eq!(dest_len, right_len);
109+
110+
for i in 0..dest_len {
111+
let dest = this.project_index(&dest, i)?;
112+
let right = this.read_scalar(&this.project_index(&right, i)?)?.to_u32()?;
113+
let left = this.project_index(&left, (right & 0b1111).into())?;
114+
115+
this.copy_op(&left, &dest)?;
116+
}
117+
}
98118
_ => return interp_ok(EmulateItemResult::NotSupported),
99119
}
100120
interp_ok(EmulateItemResult::NeedsReturn)

src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,52 @@ unsafe fn test_avx512() {
9797
assert_eq_m512i(r, e);
9898
}
9999
test_mm512_maddubs_epi16();
100+
101+
#[target_feature(enable = "avx512f")]
102+
unsafe fn test_mm512_permutexvar_epi32() {
103+
let a = _mm512_set_epi32(
104+
15, 14, 13, 12, //
105+
11, 10, 9, 8, //
106+
7, 6, 5, 4, //
107+
3, 2, 1, 0, //
108+
);
109+
110+
let idx_identity = _mm512_set_epi32(
111+
15, 14, 13, 12, //
112+
11, 10, 9, 8, //
113+
7, 6, 5, 4, //
114+
3, 2, 1, 0, //
115+
);
116+
let r_id = _mm512_permutexvar_epi32(idx_identity, a);
117+
assert_eq_m512i(r_id, a);
118+
119+
// Test some out-of-bounds indices.
120+
let edge_cases = _mm512_set_epi32(
121+
0,
122+
-1,
123+
-128,
124+
i32::MIN,
125+
15,
126+
16,
127+
128,
128+
i32::MAX,
129+
0,
130+
-1,
131+
-128,
132+
i32::MIN,
133+
15,
134+
16,
135+
128,
136+
i32::MAX,
137+
);
138+
139+
let r = _mm512_permutexvar_epi32(edge_cases, a);
140+
141+
let e = _mm512_set_epi32(0, 15, 0, 0, 15, 0, 0, 15, 0, 15, 0, 0, 15, 0, 0, 15);
142+
143+
assert_eq_m512i(r, e);
144+
}
145+
test_mm512_permutexvar_epi32();
100146
}
101147

102148
// Some of the constants in the tests below are just bit patterns. They should not

0 commit comments

Comments
 (0)