Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2212887

Browse files
author
Günther Brammer
committedSep 17, 2023
Return f32 and f64 in XMM0 instead of FP0 on i686 Rust calling convention
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.
1 parent 203c57d commit 2212887

File tree

3 files changed

+5
-14
lines changed

3 files changed

+5
-14
lines changed
 

‎compiler/rustc_ty_utils/src/abi.rs

+5
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ fn fn_abi_new_uncached<'tcx>(
371371
let target = &cx.tcx.sess.target;
372372
let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc");
373373
let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
374+
let x86_32 = target.arch == "x86";
374375
let linux_s390x_gnu_like =
375376
target.os == "linux" && target.arch == "s390x" && target_env_gnu_like;
376377
let linux_sparc64_gnu_like =
@@ -415,6 +416,10 @@ fn fn_abi_new_uncached<'tcx>(
415416
is_return,
416417
drop_target_pointee,
417418
);
419+
// Use SSE instead of x87 registers for return values when available
420+
if x86_32 && rust_abi && is_return && matches!(scalar.primitive(), F32 | F64) {
421+
attrs.set(ArgAttribute::InReg);
422+
}
418423
attrs
419424
});
420425

‎library/std/src/f32/tests.rs

-7
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ fn test_is_sign_negative() {
315315
assert!((-f32::NAN).is_sign_negative());
316316
}
317317

318-
#[allow(unused_macros)]
319318
macro_rules! assert_f32_biteq {
320319
($left : expr, $right : expr) => {
321320
let l: &f32 = &$left;
@@ -326,9 +325,6 @@ macro_rules! assert_f32_biteq {
326325
};
327326
}
328327

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

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

‎library/std/src/f64/tests.rs

-7
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ fn test_is_sign_negative() {
305305
assert!((-f64::NAN).is_sign_negative());
306306
}
307307

308-
#[allow(unused_macros)]
309308
macro_rules! assert_f64_biteq {
310309
($left : expr, $right : expr) => {
311310
let l: &f64 = &$left;
@@ -316,9 +315,6 @@ macro_rules! assert_f64_biteq {
316315
};
317316
}
318317

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

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

0 commit comments

Comments
 (0)
Failed to load comments.