Skip to content

Commit 816e303

Browse files
authored
Merge pull request #1925 from sayantn/make-const
Make X86 intrinsics `const`
2 parents 3ef10b0 + 539894b commit 816e303

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+11137
-6924
lines changed

crates/core_arch/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@
3434
aarch64_unstable_target_feature,
3535
bigint_helper_methods,
3636
funnel_shifts,
37-
avx10_target_feature
37+
avx10_target_feature,
38+
const_trait_impl,
39+
const_cmp,
40+
const_eval_select
3841
)]
3942
#![cfg_attr(test, feature(test, abi_vectorcall, stdarch_internal))]
4043
#![deny(clippy::missing_inline_in_public_items)]

crates/core_arch/src/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
#[macro_use]
66
mod macros;
77

8+
#[cfg(test)]
9+
mod test;
10+
#[cfg(test)]
11+
use test::assert_eq_const;
12+
813
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", doc))]
914
mod riscv_shared;
1015

crates/core_arch/src/simd.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
#![allow(non_camel_case_types)]
44

55
#[inline(always)]
6-
pub(crate) unsafe fn simd_imax<T: Copy>(a: T, b: T) -> T {
6+
#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
7+
pub(crate) const unsafe fn simd_imax<T: Copy>(a: T, b: T) -> T {
78
let mask: T = crate::intrinsics::simd::simd_gt(a, b);
89
crate::intrinsics::simd::simd_select(mask, a, b)
910
}
1011

1112
#[inline(always)]
12-
pub(crate) unsafe fn simd_imin<T: Copy>(a: T, b: T) -> T {
13+
#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
14+
pub(crate) const unsafe fn simd_imin<T: Copy>(a: T, b: T) -> T {
1315
let mask: T = crate::intrinsics::simd::simd_lt(a, b);
1416
crate::intrinsics::simd::simd_select(mask, a, b)
1517
}
@@ -35,7 +37,8 @@ macro_rules! simd_ty {
3537
}
3638
// FIXME: Workaround rust@60637
3739
#[inline(always)]
38-
pub(crate) fn splat(value: $elem_type) -> Self {
40+
#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
41+
pub(crate) const fn splat(value: $elem_type) -> Self {
3942
#[derive(Copy, Clone)]
4043
#[repr(simd)]
4144
struct JustOne([$elem_type; 1]);
@@ -50,12 +53,12 @@ macro_rules! simd_ty {
5053
/// Use for testing only.
5154
// FIXME: Workaround rust@60637
5255
#[inline(always)]
53-
pub(crate) fn extract(&self, index: usize) -> $elem_type {
56+
pub(crate) const fn extract(&self, index: usize) -> $elem_type {
5457
self.as_array()[index]
5558
}
5659

5760
#[inline]
58-
pub(crate) fn as_array(&self) -> &[$elem_type; $len] {
61+
pub(crate) const fn as_array(&self) -> &[$elem_type; $len] {
5962
let simd_ptr: *const Self = self;
6063
let array_ptr: *const [$elem_type; $len] = simd_ptr.cast();
6164
// SAFETY: We can always read the prefix of a simd type as an array.
@@ -65,7 +68,8 @@ macro_rules! simd_ty {
6568
}
6669
}
6770

68-
impl core::cmp::PartialEq for $id {
71+
#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
72+
const impl core::cmp::PartialEq for $id {
6973
#[inline]
7074
fn eq(&self, other: &Self) -> bool {
7175
self.as_array() == other.as_array()
@@ -101,7 +105,8 @@ macro_rules! simd_m_ty {
101105

102106
// FIXME: Workaround rust@60637
103107
#[inline(always)]
104-
pub(crate) fn splat(value: bool) -> Self {
108+
#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
109+
pub(crate) const fn splat(value: bool) -> Self {
105110
#[derive(Copy, Clone)]
106111
#[repr(simd)]
107112
struct JustOne([$elem_type; 1]);
@@ -112,7 +117,7 @@ macro_rules! simd_m_ty {
112117
}
113118

114119
#[inline]
115-
pub(crate) fn as_array(&self) -> &[$elem_type; $len] {
120+
pub(crate) const fn as_array(&self) -> &[$elem_type; $len] {
116121
let simd_ptr: *const Self = self;
117122
let array_ptr: *const [$elem_type; $len] = simd_ptr.cast();
118123
// SAFETY: We can always read the prefix of a simd type as an array.
@@ -122,7 +127,8 @@ macro_rules! simd_m_ty {
122127
}
123128
}
124129

125-
impl core::cmp::PartialEq for $id {
130+
#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
131+
const impl core::cmp::PartialEq for $id {
126132
#[inline]
127133
fn eq(&self, other: &Self) -> bool {
128134
self.as_array() == other.as_array()

crates/core_arch/src/test.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use crate::fmt::Debug;
2+
3+
#[track_caller]
4+
#[allow(unused)]
5+
pub(crate) fn assert_eq_rt<T: PartialEq + Debug>(a: &T, b: &T) {
6+
std::assert_eq!(a, b)
7+
}
8+
9+
#[allow(unused)]
10+
macro_rules! assert_eq_const {
11+
($a:expr, $b:expr $(,)?) => {{
12+
#[inline(always)]
13+
#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
14+
const fn assert_eq_ct<T: [const] PartialEq>(a: &T, b: &T) {
15+
assert!(a == b, concat!("`", stringify!($a), "` != `", stringify!($b), "`"));
16+
}
17+
18+
$crate::intrinsics::const_eval_select((&$a, &$b), assert_eq_ct, $crate::core_arch::test::assert_eq_rt);
19+
}};
20+
($a:expr, $b:expr, $($t:tt)+) => {
21+
::std::assert_eq!($a, $b, $($t)+)
22+
};
23+
}
24+
25+
pub(crate) use assert_eq_const;

crates/core_arch/src/x86/abm.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ use stdarch_test::assert_instr;
2929
#[target_feature(enable = "lzcnt")]
3030
#[cfg_attr(test, assert_instr(lzcnt))]
3131
#[stable(feature = "simd_x86", since = "1.27.0")]
32-
pub fn _lzcnt_u32(x: u32) -> u32 {
32+
#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
33+
pub const fn _lzcnt_u32(x: u32) -> u32 {
3334
x.leading_zeros()
3435
}
3536

@@ -40,23 +41,25 @@ pub fn _lzcnt_u32(x: u32) -> u32 {
4041
#[target_feature(enable = "popcnt")]
4142
#[cfg_attr(test, assert_instr(popcnt))]
4243
#[stable(feature = "simd_x86", since = "1.27.0")]
43-
pub fn _popcnt32(x: i32) -> i32 {
44+
#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
45+
pub const fn _popcnt32(x: i32) -> i32 {
4446
x.count_ones() as i32
4547
}
4648

4749
#[cfg(test)]
4850
mod tests {
51+
use crate::core_arch::assert_eq_const as assert_eq;
4952
use stdarch_test::simd_test;
5053

5154
use crate::core_arch::x86::*;
5255

5356
#[simd_test(enable = "lzcnt")]
54-
unsafe fn test_lzcnt_u32() {
57+
const unsafe fn test_lzcnt_u32() {
5558
assert_eq!(_lzcnt_u32(0b0101_1010), 25);
5659
}
5760

5861
#[simd_test(enable = "popcnt")]
59-
unsafe fn test_popcnt32() {
62+
const unsafe fn test_popcnt32() {
6063
assert_eq!(_popcnt32(0b0101_1010), 4);
6164
}
6265
}

0 commit comments

Comments
 (0)