Auto merge of #3393 - eduardosm:x86-pause-without-sse2, r=RalfJung
Allow `llvm.x86.sse2.pause` instrinsic to be called without SSE2 The instrinsic is compiled to a `pause` instruction, which behaves like a no-op when SSE2 is not available. https://www.felixcloutier.com/x86/pause.html
This commit is contained in:
commit
f61f45f233
@ -88,6 +88,19 @@ fn emulate_x86_intrinsic(
|
||||
this.write_immediate(*sub, &this.project_field(dest, 1)?)?;
|
||||
}
|
||||
|
||||
// Used to implement the `_mm_pause` function.
|
||||
// The intrinsic is used to hint the processor that the code is in a spin-loop.
|
||||
// It is compiled down to a `pause` instruction. When SSE2 is not available,
|
||||
// the instruction behaves like a no-op, so it is always safe to call the
|
||||
// intrinsic.
|
||||
"sse2.pause" => {
|
||||
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
// Only exhibit the spin-loop hint behavior when SSE2 is enabled.
|
||||
if this.tcx.sess.unstable_target_features.contains(&Symbol::intern("sse2")) {
|
||||
this.yield_active_thread();
|
||||
}
|
||||
}
|
||||
|
||||
name if name.starts_with("sse.") => {
|
||||
return sse::EvalContextExt::emulate_x86_sse_intrinsic(
|
||||
this, link_name, abi, args, dest,
|
||||
|
@ -580,12 +580,6 @@ enum ShiftOp {
|
||||
this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?;
|
||||
}
|
||||
}
|
||||
// Used to implement the `_mm_pause` function.
|
||||
// The intrinsic is used to hint the processor that the code is in a spin-loop.
|
||||
"pause" => {
|
||||
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.yield_active_thread();
|
||||
}
|
||||
_ => return Ok(EmulateForeignItemResult::NotSupported),
|
||||
}
|
||||
Ok(EmulateForeignItemResult::NeedsJumping)
|
||||
|
@ -0,0 +1,25 @@
|
||||
// Ignore everything except x86 and x86_64
|
||||
// Any new targets that are added to CI should be ignored here.
|
||||
// (We cannot use `cfg`-based tricks here since the `target-feature` flags below only work on x86.)
|
||||
//@ignore-target-aarch64
|
||||
//@ignore-target-arm
|
||||
//@ignore-target-avr
|
||||
//@ignore-target-s390x
|
||||
//@ignore-target-thumbv7em
|
||||
//@ignore-target-wasm32
|
||||
//@compile-flags: -C target-feature=-sse2
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
use std::arch::x86::*;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
fn main() {
|
||||
assert!(!is_x86_feature_detected!("sse2"));
|
||||
|
||||
unsafe {
|
||||
// This is a SSE2 intrinsic, but it behaves as a no-op when SSE2
|
||||
// is not available, so it is always safe to call.
|
||||
_mm_pause();
|
||||
}
|
||||
}
|
@ -54,6 +54,11 @@ unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) {
|
||||
}
|
||||
}
|
||||
|
||||
fn test_mm_pause() {
|
||||
unsafe { _mm_pause() }
|
||||
}
|
||||
test_mm_pause();
|
||||
|
||||
#[target_feature(enable = "sse2")]
|
||||
unsafe fn test_mm_avg_epu8() {
|
||||
let (a, b) = (_mm_set1_epi8(3), _mm_set1_epi8(9));
|
||||
|
Loading…
Reference in New Issue
Block a user