Skip to content

Deprecate functions that use _mm_setcsr or _mm_getcsr internally #1471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ case ${TARGET} in
i686-* | i586-*)
export RUSTFLAGS="${RUSTFLAGS} -C relocation-model=static -Z plt=yes"
;;
# Some x86_64 targets enable by default more features beyond SSE2,
# which cause some instruction assertion checks to fail.
x86_64-*)
export RUSTFLAGS="${RUSTFLAGS} -C target-feature=-sse3"
;;
#Unoptimized build uses fast-isel which breaks with msa
mips-* | mipsel-*)
export RUSTFLAGS="${RUSTFLAGS} -C llvm-args=-fast-isel=false"
Expand Down
11 changes: 11 additions & 0 deletions crates/assert-instr-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ pub fn assert_instr(

let instr = &invoc.instr;
let name = &func.sig.ident;
let maybe_allow_deprecated = if func
.attrs
.iter()
.any(|attr| attr.path.is_ident("deprecated"))
{
quote! { #[allow(deprecated)] }
} else {
quote! {}
};

// Disable assert_instr for x86 targets compiled with avx enabled, which
// causes LLVM to generate different intrinsics that the ones we are
Expand Down Expand Up @@ -135,6 +144,7 @@ pub fn assert_instr(
let to_test = if disable_dedup_guard {
quote! {
#attrs
#maybe_allow_deprecated
#[no_mangle]
#[inline(never)]
pub unsafe extern #abi fn #shim_name(#(#inputs),*) #ret {
Expand All @@ -147,6 +157,7 @@ pub fn assert_instr(
const #shim_name_ptr : *const u8 = #shim_name_str.as_ptr();

#attrs
#maybe_allow_deprecated
#[no_mangle]
#[inline(never)]
pub unsafe extern #abi fn #shim_name(#(#inputs),*) #ret {
Expand Down
50 changes: 46 additions & 4 deletions crates/core_arch/src/x86/sse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,8 +790,7 @@ pub unsafe fn _mm_ucomineq_ss(a: __m128, b: __m128) -> i32 {
///
/// The result is rounded according to the current rounding mode. If the result
/// cannot be represented as a 32 bit integer the result will be `0x8000_0000`
/// (`i32::MIN`) or an invalid operation floating point exception if
/// unmasked (see [`_mm_setcsr`](fn._mm_setcsr.html)).
/// (`i32::MIN`).
///
/// This corresponds to the `CVTSS2SI` instruction (with 32 bit output).
///
Expand Down Expand Up @@ -821,8 +820,7 @@ pub unsafe fn _mm_cvt_ss2si(a: __m128) -> i32 {
///
/// The result is rounded always using truncation (round towards zero). If the
/// result cannot be represented as a 32 bit integer the result will be
/// `0x8000_0000` (`i32::MIN`) or an invalid operation floating point
/// exception if unmasked (see [`_mm_setcsr`](fn._mm_setcsr.html)).
/// `0x8000_0000` (`i32::MIN`).
///
/// This corresponds to the `CVTTSS2SI` instruction (with 32 bit output).
///
Expand Down Expand Up @@ -1615,9 +1613,14 @@ pub const _MM_FLUSH_ZERO_OFF: u32 = 0x0000;
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_GET_EXCEPTION_MASK)
#[inline]
#[allow(deprecated)] // Deprecated function implemented on top of deprecated function
#[allow(non_snake_case)]
#[target_feature(enable = "sse")]
#[stable(feature = "simd_x86", since = "1.27.0")]
#[deprecated(
since = "1.73.0",
note = "see `_mm_getcsr` documentation - use inline assembly instead"
)]
pub unsafe fn _MM_GET_EXCEPTION_MASK() -> u32 {
_mm_getcsr() & _MM_MASK_MASK
}
Expand All @@ -1626,9 +1629,14 @@ pub unsafe fn _MM_GET_EXCEPTION_MASK() -> u32 {
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_GET_EXCEPTION_STATE)
#[inline]
#[allow(deprecated)] // Deprecated function implemented on top of deprecated function
#[allow(non_snake_case)]
#[target_feature(enable = "sse")]
#[stable(feature = "simd_x86", since = "1.27.0")]
#[deprecated(
since = "1.73.0",
note = "see `_mm_getcsr` documentation - use inline assembly instead"
)]
pub unsafe fn _MM_GET_EXCEPTION_STATE() -> u32 {
_mm_getcsr() & _MM_EXCEPT_MASK
}
Expand All @@ -1637,9 +1645,14 @@ pub unsafe fn _MM_GET_EXCEPTION_STATE() -> u32 {
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_GET_FLUSH_ZERO_MODE)
#[inline]
#[allow(deprecated)] // Deprecated function implemented on top of deprecated function
#[allow(non_snake_case)]
#[target_feature(enable = "sse")]
#[stable(feature = "simd_x86", since = "1.27.0")]
#[deprecated(
since = "1.73.0",
note = "see `_mm_getcsr` documentation - use inline assembly instead"
)]
pub unsafe fn _MM_GET_FLUSH_ZERO_MODE() -> u32 {
_mm_getcsr() & _MM_FLUSH_ZERO_MASK
}
Expand All @@ -1648,9 +1661,14 @@ pub unsafe fn _MM_GET_FLUSH_ZERO_MODE() -> u32 {
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_GET_ROUNDING_MODE)
#[inline]
#[allow(deprecated)] // Deprecated function implemented on top of deprecated function
#[allow(non_snake_case)]
#[target_feature(enable = "sse")]
#[stable(feature = "simd_x86", since = "1.27.0")]
#[deprecated(
since = "1.73.0",
note = "see `_mm_getcsr` documentation - use inline assembly instead"
)]
pub unsafe fn _MM_GET_ROUNDING_MODE() -> u32 {
_mm_getcsr() & _MM_ROUND_MASK
}
Expand All @@ -1659,9 +1677,14 @@ pub unsafe fn _MM_GET_ROUNDING_MODE() -> u32 {
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_SET_EXCEPTION_MASK)
#[inline]
#[allow(deprecated)] // Deprecated function implemented on top of deprecated function
#[allow(non_snake_case)]
#[target_feature(enable = "sse")]
#[stable(feature = "simd_x86", since = "1.27.0")]
#[deprecated(
since = "1.73.0",
note = "see `_mm_setcsr` documentation - use inline assembly instead"
)]
pub unsafe fn _MM_SET_EXCEPTION_MASK(x: u32) {
_mm_setcsr((_mm_getcsr() & !_MM_MASK_MASK) | x)
}
Expand All @@ -1670,9 +1693,14 @@ pub unsafe fn _MM_SET_EXCEPTION_MASK(x: u32) {
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_SET_EXCEPTION_STATE)
#[inline]
#[allow(deprecated)] // Deprecated function implemented on top of deprecated function
#[allow(non_snake_case)]
#[target_feature(enable = "sse")]
#[stable(feature = "simd_x86", since = "1.27.0")]
#[deprecated(
since = "1.73.0",
note = "see `_mm_setcsr` documentation - use inline assembly instead"
)]
pub unsafe fn _MM_SET_EXCEPTION_STATE(x: u32) {
_mm_setcsr((_mm_getcsr() & !_MM_EXCEPT_MASK) | x)
}
Expand All @@ -1681,9 +1709,14 @@ pub unsafe fn _MM_SET_EXCEPTION_STATE(x: u32) {
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_SET_FLUSH_ZERO_MODE)
#[inline]
#[allow(deprecated)] // Deprecated function implemented on top of deprecated function
#[allow(non_snake_case)]
#[target_feature(enable = "sse")]
#[stable(feature = "simd_x86", since = "1.27.0")]
#[deprecated(
since = "1.73.0",
note = "see `_mm_setcsr` documentation - use inline assembly instead"
)]
pub unsafe fn _MM_SET_FLUSH_ZERO_MODE(x: u32) {
let val = (_mm_getcsr() & !_MM_FLUSH_ZERO_MASK) | x;
// println!("setting csr={:x}", val);
Expand All @@ -1694,9 +1727,14 @@ pub unsafe fn _MM_SET_FLUSH_ZERO_MODE(x: u32) {
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_SET_ROUNDING_MODE)
#[inline]
#[allow(deprecated)] // Deprecated function implemented on top of deprecated function
#[allow(non_snake_case)]
#[target_feature(enable = "sse")]
#[stable(feature = "simd_x86", since = "1.27.0")]
#[deprecated(
since = "1.73.0",
note = "see `_mm_setcsr` documentation - use inline assembly instead"
)]
pub unsafe fn _MM_SET_ROUNDING_MODE(x: u32) {
_mm_setcsr((_mm_getcsr() & !_MM_ROUND_MASK) | x)
}
Expand Down Expand Up @@ -2804,6 +2842,7 @@ mod tests {
}
}

#[allow(deprecated)] // FIXME: This test uses deprecated CSR access functions
#[simd_test(enable = "sse")]
unsafe fn test_mm_comieq_ss_vs_ucomieq_ss() {
// If one of the arguments is a quiet NaN `comieq_ss` should signal an
Expand Down Expand Up @@ -3228,6 +3267,7 @@ mod tests {
_mm_sfence();
}

#[allow(deprecated)] // FIXME: This tests functions that are immediate UB
#[simd_test(enable = "sse")]
unsafe fn test_mm_getcsr_setcsr_1() {
let saved_csr = _mm_getcsr();
Expand All @@ -3244,6 +3284,7 @@ mod tests {
assert_eq_m128(r, exp); // first component is a denormalized f32
}

#[allow(deprecated)] // FIXME: This tests functions that are immediate UB
#[simd_test(enable = "sse")]
unsafe fn test_mm_getcsr_setcsr_2() {
// Same as _mm_setcsr_1 test, but with opposite flag value.
Expand All @@ -3262,6 +3303,7 @@ mod tests {
assert_eq_m128(r, exp); // first component is a denormalized f32
}

#[allow(deprecated)] // FIXME: This tests functions that are immediate UB
#[simd_test(enable = "sse")]
unsafe fn test_mm_getcsr_setcsr_underflow() {
_MM_SET_EXCEPTION_STATE(0);
Expand Down
2 changes: 2 additions & 0 deletions crates/core_arch/src/x86/sse41.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,7 @@ mod tests {
assert_eq_m128(r, e);
}

#[allow(deprecated)] // FIXME: This test uses deprecated CSR access functions
#[simd_test(enable = "sse4.1")]
unsafe fn test_mm_round_sd() {
let a = _mm_setr_pd(1.5, 3.5);
Expand All @@ -1680,6 +1681,7 @@ mod tests {
assert_eq_m128d(r, e);
}

#[allow(deprecated)] // FIXME: This test uses deprecated CSR access functions
#[simd_test(enable = "sse4.1")]
unsafe fn test_mm_round_ss() {
let a = _mm_setr_ps(1.5, 3.5, 7.5, 15.5);
Expand Down