Skip to content

Commit fb48c7d

Browse files
authored
Rollup merge of rust-lang#131871 - RalfJung:x86-32-float, r=workingjubilee
x86-32 float return for 'Rust' ABI: treat all float types consistently This helps with rust-lang#131819: for our own ABI on x86-32, we want to *never* use the float registers. The previous logic only considered F32 and F64, but skipped F16 and F128. So I made the logic just apply to all float types.
2 parents 85be3b2 + a9f6fd1 commit fb48c7d

File tree

1 file changed

+15
-22
lines changed
  • compiler/rustc_ty_utils/src

1 file changed

+15
-22
lines changed

compiler/rustc_ty_utils/src/abi.rs

+15-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::iter;
22

3-
use rustc_abi::Float::*;
43
use rustc_abi::Primitive::{Float, Pointer};
54
use rustc_abi::{Abi, AddressSpace, PointerKind, Scalar, Size};
65
use rustc_hir as hir;
@@ -695,37 +694,31 @@ fn fn_abi_adjust_for_abi<'tcx>(
695694
}
696695

697696
// Avoid returning floats in x87 registers on x86 as loading and storing from x87
698-
// registers will quiet signalling NaNs.
697+
// registers will quiet signalling NaNs. Also avoid using SSE registers since they
698+
// are not always available (depending on target features).
699699
if tcx.sess.target.arch == "x86"
700700
&& arg_idx.is_none()
701701
// Intrinsics themselves are not actual "real" functions, so theres no need to
702702
// change their ABIs.
703703
&& abi != SpecAbi::RustIntrinsic
704704
{
705-
match arg.layout.abi {
706-
// Handle similar to the way arguments with an `Abi::Aggregate` abi are handled
707-
// below, by returning arguments up to the size of a pointer (32 bits on x86)
708-
// cast to an appropriately sized integer.
709-
Abi::Scalar(s) if s.primitive() == Float(F32) => {
710-
// Same size as a pointer, return in a register.
711-
arg.cast_to(Reg::i32());
712-
return;
705+
let has_float = match arg.layout.abi {
706+
Abi::Scalar(s) => matches!(s.primitive(), Float(_)),
707+
Abi::ScalarPair(s1, s2) => {
708+
matches!(s1.primitive(), Float(_)) || matches!(s2.primitive(), Float(_))
713709
}
714-
Abi::Scalar(s) if s.primitive() == Float(F64) => {
715-
// Larger than a pointer, return indirectly.
716-
arg.make_indirect();
717-
return;
718-
}
719-
Abi::ScalarPair(s1, s2)
720-
if matches!(s1.primitive(), Float(F32 | F64))
721-
|| matches!(s2.primitive(), Float(F32 | F64)) =>
722-
{
710+
_ => false, // anyway not passed via registers on x86
711+
};
712+
if has_float {
713+
if arg.layout.size <= Pointer(AddressSpace::DATA).size(cx) {
714+
// Same size or smaller than pointer, return in a register.
715+
arg.cast_to(Reg { kind: RegKind::Integer, size: arg.layout.size });
716+
} else {
723717
// Larger than a pointer, return indirectly.
724718
arg.make_indirect();
725-
return;
726719
}
727-
_ => {}
728-
};
720+
return;
721+
}
729722
}
730723

731724
match arg.layout.abi {

0 commit comments

Comments
 (0)