Skip to content

Commit 2957e2e

Browse files
author
Daniel Smith
committed
Add comparison operator integer comparisons
1 parent f775ef1 commit 2957e2e

File tree

5 files changed

+149
-1
lines changed

5 files changed

+149
-1
lines changed

crates/core_arch/src/x86/avx512f.rs

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,47 @@ pub unsafe fn _mm512_mask_cmpneq_epu64_mask(m: __mmask8, a: __m512i, b: __m512i)
220220
_mm512_cmpneq_epu64_mask(a, b) & m
221221
}
222222

223+
/// Compare packed unsigned 64-bit integers in a and b based on the comparison operand specified by op.
224+
///
225+
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=727,1063,4909,1062,1062,1063&text=_mm512_mask_cmp_epu64)
226+
#[inline]
227+
#[target_feature(enable = "avx512f")]
228+
#[rustc_args_required_const(2)]
229+
#[cfg_attr(test, assert_instr(vpcmp, op = 0))]
230+
pub unsafe fn _mm512_cmp_epu64_mask(a: __m512i, b: __m512i, op: _MM_CMPINT_ENUM) -> __mmask8 {
231+
let neg_one = -1;
232+
macro_rules! call {
233+
($imm3:expr) => {
234+
vpcmpuq(a.as_i64x8(), b.as_i64x8(), $imm3, neg_one)
235+
};
236+
}
237+
let r = constify_imm3!(op, call);
238+
transmute(r)
239+
}
240+
241+
/// Compare packed unsigned 64-bit integers in a and b based on the comparison operand specified by op,
242+
/// using zeromask m (elements are zeroed out when the corresponding mask bit is not set).
243+
///
244+
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=727,1063,4909,1062,1062,1063&text=_mm512_mask_cmp_epu64)
245+
#[inline]
246+
#[target_feature(enable = "avx512f")]
247+
#[rustc_args_required_const(3)]
248+
#[cfg_attr(test, assert_instr(vpcmp, op = 0))]
249+
pub unsafe fn _mm512_mask_cmp_epu64_mask(
250+
m: __mmask8,
251+
a: __m512i,
252+
b: __m512i,
253+
op: _MM_CMPINT_ENUM,
254+
) -> __mmask8 {
255+
macro_rules! call {
256+
($imm3:expr) => {
257+
vpcmpuq(a.as_i64x8(), b.as_i64x8(), $imm3, m as i8)
258+
};
259+
}
260+
let r = constify_imm3!(op, call);
261+
transmute(r)
262+
}
263+
223264
/// Compare packed signed 64-bit integers in a and b for less-than, and store the results in a mask vector.
224265
///
225266
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=727,1063,4909,1062,1062&text=_mm512_cmplt_epi64)
@@ -335,7 +376,7 @@ pub unsafe fn _mm512_cmpneq_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 {
335376
simd_bitmask::<__m512i, _>(simd_ne(a.as_i64x8(), b.as_i64x8()))
336377
}
337378

338-
///Compare packed signed 64-bit integers in a and b for inequality, and store the results in a mask vector k
379+
/// Compare packed signed 64-bit integers in a and b for inequality, and store the results in a mask vector k
339380
/// using zeromask m (elements are zeroed out when the corresponding mask bit is not set).
340381
///
341382
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=727,1063,4909,1062,1062,1063&text=_mm512_mask_cmpneq_epi64)
@@ -346,6 +387,72 @@ pub unsafe fn _mm512_mask_cmpneq_epi64_mask(m: __mmask8, a: __m512i, b: __m512i)
346387
_mm512_cmpneq_epi64_mask(a, b) & m
347388
}
348389

390+
/// Compare packed signed 64-bit integers in a and b based on the comparison operand specified by op.
391+
///
392+
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=727,1063,4909,1062,1062,1063&text=_mm512_mask_cmp_epi64)
393+
#[inline]
394+
#[target_feature(enable = "avx512f")]
395+
#[rustc_args_required_const(2)]
396+
#[cfg_attr(test, assert_instr(vpcmp, op = 0))]
397+
pub unsafe fn _mm512_cmp_epi64_mask(a: __m512i, b: __m512i, op: _MM_CMPINT_ENUM) -> __mmask8 {
398+
let neg_one = -1;
399+
macro_rules! call {
400+
($imm3:expr) => {
401+
vpcmpq(a.as_i64x8(), b.as_i64x8(), $imm3, neg_one)
402+
};
403+
}
404+
let r = constify_imm3!(op, call);
405+
transmute(r)
406+
}
407+
408+
/// Compare packed signed 64-bit integers in a and b based on the comparison operand specified by op,
409+
/// using zeromask m (elements are zeroed out when the corresponding mask bit is not set).
410+
///
411+
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=727,1063,4909,1062,1062,1063&text=_mm512_mask_cmp_epi64)
412+
#[inline]
413+
#[target_feature(enable = "avx512f")]
414+
#[rustc_args_required_const(3)]
415+
#[cfg_attr(test, assert_instr(vpcmp, op = 0))]
416+
pub unsafe fn _mm512_mask_cmp_epi64_mask(
417+
m: __mmask8,
418+
a: __m512i,
419+
b: __m512i,
420+
op: _MM_CMPINT_ENUM,
421+
) -> __mmask8 {
422+
macro_rules! call {
423+
($imm3:expr) => {
424+
vpcmpq(a.as_i64x8(), b.as_i64x8(), $imm3, m as i8)
425+
};
426+
}
427+
let r = constify_imm3!(op, call);
428+
transmute(r)
429+
}
430+
431+
/// Equal
432+
pub const _MM_CMPINT_EQ: _MM_CMPINT_ENUM = 0x00;
433+
/// Less-than
434+
pub const _MM_CMPINT_LT: _MM_CMPINT_ENUM = 0x01;
435+
/// Less-than-or-equal
436+
pub const _MM_CMPINT_LE: _MM_CMPINT_ENUM = 0x02;
437+
/// False
438+
pub const _MM_CMPINT_FALSE: _MM_CMPINT_ENUM = 0x03;
439+
/// Not-equal
440+
pub const _MM_CMPINT_NE: _MM_CMPINT_ENUM = 0x04;
441+
/// Not less-than
442+
pub const _MM_CMPINT_NLT: _MM_CMPINT_ENUM = 0x05;
443+
/// Not less-than-or-equal
444+
pub const _MM_CMPINT_NLE: _MM_CMPINT_ENUM = 0x06;
445+
/// True
446+
pub const _MM_CMPINT_TRUE: _MM_CMPINT_ENUM = 0x07;
447+
448+
#[allow(improper_ctypes)]
449+
extern "C" {
450+
#[link_name = "llvm.x86.avx512.mask.ucmp.q.512"]
451+
fn vpcmpuq(a: i64x8, b: i64x8, op: i32, m: i8) -> i8;
452+
#[link_name = "llvm.x86.avx512.mask.cmp.q.512"]
453+
fn vpcmpq(a: i64x8, b: i64x8, op: i32, m: i8) -> i8;
454+
}
455+
349456
#[cfg(test)]
350457
mod tests {
351458
use std;

crates/core_arch/src/x86/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,9 @@ pub type __mmask16 = u16;
350350
#[allow(non_camel_case_types)]
351351
pub type __mmask8 = u8;
352352

353+
/// The `_MM_CMPINT_ENUM` type used to specify comparison operations in AVX-512 intrinsics.
354+
pub type _MM_CMPINT_ENUM = i32;
355+
353356
#[cfg(test)]
354357
mod test;
355358
#[cfg(test)]

crates/core_arch/src/x86_64/avx512f.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,23 @@ mod tests {
153153
assert_eq!(r, 0b00110010);
154154
}
155155

156+
#[simd_test(enable = "avx512f")]
157+
unsafe fn test_mm512_cmp_epu64_mask() {
158+
let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100);
159+
let b = _mm512_set1_epi64(-1);
160+
let m = _mm512_cmp_epu64_mask(a, b, _MM_CMPINT_LT);
161+
assert_eq!(m, 0b11001111);
162+
}
163+
164+
#[simd_test(enable = "avx512f")]
165+
unsafe fn test_mm512_mask_cmp_epu64_mask() {
166+
let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100);
167+
let b = _mm512_set1_epi64(-1);
168+
let mask = 0b01111010;
169+
let r = _mm512_mask_cmp_epu64_mask(mask, a, b, _MM_CMPINT_LT);
170+
assert_eq!(r, 0b01001010);
171+
}
172+
156173
#[simd_test(enable = "avx512f")]
157174
unsafe fn test_mm512_cmplt_epi64_mask() {
158175
let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100);
@@ -257,6 +274,23 @@ mod tests {
257274
assert_eq!(r, 0b00110010)
258275
}
259276

277+
#[simd_test(enable = "avx512f")]
278+
unsafe fn test_mm512_cmp_epi64_mask() {
279+
let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100);
280+
let b = _mm512_set1_epi64(-1);
281+
let m = _mm512_cmp_epi64_mask(a, b, _MM_CMPINT_LT);
282+
assert_eq!(m, 0b00000101);
283+
}
284+
285+
#[simd_test(enable = "avx512f")]
286+
unsafe fn test_mm512_mask_cmp_epi64_mask() {
287+
let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100);
288+
let b = _mm512_set1_epi64(-1);
289+
let mask = 0b01100110;
290+
let r = _mm512_mask_cmp_epi64_mask(mask, a, b, _MM_CMPINT_LT);
291+
assert_eq!(r, 0b00000100);
292+
}
293+
260294
#[simd_test(enable = "avx512f")]
261295
unsafe fn test_mm512_set_epi64() {
262296
let r = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7);

crates/stdarch-verify/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ fn to_type(t: &syn::Type) -> proc_macro2::TokenStream {
147147
"__m512i" => quote! { &M512I },
148148
"__mmask8" => quote! { &MMASK8 },
149149
"__mmask16" => quote! { &MMASK16 },
150+
"_MM_CMPINT_ENUM" => quote! { &MM_CMPINT_ENUM },
150151
"__m64" => quote! { &M64 },
151152
"bool" => quote! { &BOOL },
152153
"f32" => quote! { &F32 },

crates/stdarch-verify/tests/x86-intel.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static M512I: Type = Type::M512I;
5555
static M512D: Type = Type::M512D;
5656
static MMASK8: Type = Type::MMASK8;
5757
static MMASK16: Type = Type::MMASK16;
58+
static MM_CMPINT_ENUM: Type = Type::MM_CMPINT_ENUM;
5859

5960
static TUPLE: Type = Type::Tuple;
6061
static CPUID: Type = Type::CpuidResult;
@@ -79,6 +80,7 @@ enum Type {
7980
M512I,
8081
MMASK8,
8182
MMASK16,
83+
MM_CMPINT_ENUM,
8284
Tuple,
8385
CpuidResult,
8486
Never,
@@ -657,6 +659,7 @@ fn equate(t: &Type, intel: &str, intrinsic: &str, is_const: bool) -> Result<(),
657659

658660
(&Type::MMASK8, "__mmask8") => {}
659661
(&Type::MMASK16, "__mmask16") => {}
662+
(&Type::MM_CMPINT_ENUM, "const _MM_CMPINT_ENUM") => require_const()?,
660663

661664
// This is a macro (?) in C which seems to mutate its arguments, but
662665
// that means that we're taking pointers to arguments in rust

0 commit comments

Comments
 (0)