Skip to content

Commit

Permalink
Return f32 and f64 in XMM0 instead of FP0 on i686 Rust calling conven…
Browse files Browse the repository at this point in the history
…tion

i686 already uses SSE to do calculations with f32 and f64, but the C
calling convention uses the x87 stack to return values. The Rust calling
convention does not need to do this, and LLVM makes it easy to use XMM0
instead, which saves move instructions and fixes problems with NaN values.
  • Loading branch information
Günther Brammer committed Sep 17, 2023
1 parent 203c57d commit 2212887
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 14 deletions.
5 changes: 5 additions & 0 deletions compiler/rustc_ty_utils/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ fn fn_abi_new_uncached<'tcx>(
let target = &cx.tcx.sess.target;
let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc");
let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
let x86_32 = target.arch == "x86";
let linux_s390x_gnu_like =
target.os == "linux" && target.arch == "s390x" && target_env_gnu_like;
let linux_sparc64_gnu_like =
Expand Down Expand Up @@ -415,6 +416,10 @@ fn fn_abi_new_uncached<'tcx>(
is_return,
drop_target_pointee,
);
// Use SSE instead of x87 registers for return values when available
if x86_32 && rust_abi && is_return && matches!(scalar.primitive(), F32 | F64) {
attrs.set(ArgAttribute::InReg);
}
attrs
});

Expand Down
7 changes: 0 additions & 7 deletions library/std/src/f32/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,6 @@ fn test_is_sign_negative() {
assert!((-f32::NAN).is_sign_negative());
}

#[allow(unused_macros)]
macro_rules! assert_f32_biteq {
($left : expr, $right : expr) => {
let l: &f32 = &$left;
Expand All @@ -326,9 +325,6 @@ macro_rules! assert_f32_biteq {
};
}

// Ignore test on x87 floating point, these platforms do not guarantee NaN
// payloads are preserved and flush denormals to zero, failing the tests.
#[cfg(not(target_arch = "x86"))]
#[test]
fn test_next_up() {
let tiny = f32::from_bits(1);
Expand Down Expand Up @@ -359,9 +355,6 @@ fn test_next_up() {
assert_f32_biteq!(nan2.next_up(), nan2);
}

// Ignore test on x87 floating point, these platforms do not guarantee NaN
// payloads are preserved and flush denormals to zero, failing the tests.
#[cfg(not(target_arch = "x86"))]
#[test]
fn test_next_down() {
let tiny = f32::from_bits(1);
Expand Down
7 changes: 0 additions & 7 deletions library/std/src/f64/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@ fn test_is_sign_negative() {
assert!((-f64::NAN).is_sign_negative());
}

#[allow(unused_macros)]
macro_rules! assert_f64_biteq {
($left : expr, $right : expr) => {
let l: &f64 = &$left;
Expand All @@ -316,9 +315,6 @@ macro_rules! assert_f64_biteq {
};
}

// Ignore test on x87 floating point, these platforms do not guarantee NaN
// payloads are preserved and flush denormals to zero, failing the tests.
#[cfg(not(target_arch = "x86"))]
#[test]
fn test_next_up() {
let tiny = f64::from_bits(1);
Expand Down Expand Up @@ -348,9 +344,6 @@ fn test_next_up() {
assert_f64_biteq!(nan2.next_up(), nan2);
}

// Ignore test on x87 floating point, these platforms do not guarantee NaN
// payloads are preserved and flush denormals to zero, failing the tests.
#[cfg(not(target_arch = "x86"))]
#[test]
fn test_next_down() {
let tiny = f64::from_bits(1);
Expand Down

0 comments on commit 2212887

Please sign in to comment.