Skip to content

Commit 4d9b827

Browse files
committed
Change float to integer tests to have an apfloat fallback
1 parent 6a64122 commit 4d9b827

File tree

6 files changed

+122
-27
lines changed

6 files changed

+122
-27
lines changed

Diff for: README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,12 @@ These builtins are needed to support `f16` and `f128`, which are in the process
239239
- [x] extendhfsf2.c
240240
- [x] extendhftf2.c
241241
- [x] extendsftf2.c
242-
- [ ] fixtfdi.c
243-
- [ ] fixtfsi.c
244-
- [ ] fixtfti.c
245-
- [ ] fixunstfdi.c
246-
- [ ] fixunstfsi.c
247-
- [ ] fixunstfti.c
242+
- [x] fixtfdi.c
243+
- [x] fixtfsi.c
244+
- [x] fixtfti.c
245+
- [x] fixunstfdi.c
246+
- [x] fixunstfsi.c
247+
- [x] fixunstfti.c
248248
- [ ] floatditf.c
249249
- [ ] floatsitf.c
250250
- [ ] floatunditf.c

Diff for: build.rs

-10
Original file line numberDiff line numberDiff line change
@@ -533,12 +533,6 @@ mod c {
533533
if (target_arch == "aarch64" || target_arch == "arm64ec") && consider_float_intrinsics {
534534
sources.extend(&[
535535
("__comparetf2", "comparetf2.c"),
536-
("__fixtfdi", "fixtfdi.c"),
537-
("__fixtfsi", "fixtfsi.c"),
538-
("__fixtfti", "fixtfti.c"),
539-
("__fixunstfdi", "fixunstfdi.c"),
540-
("__fixunstfsi", "fixunstfsi.c"),
541-
("__fixunstfti", "fixunstfti.c"),
542536
("__floatditf", "floatditf.c"),
543537
("__floatsitf", "floatsitf.c"),
544538
("__floatunditf", "floatunditf.c"),
@@ -561,9 +555,7 @@ mod c {
561555
if target_arch == "mips64" {
562556
sources.extend(&[
563557
("__netf2", "comparetf2.c"),
564-
("__fixtfsi", "fixtfsi.c"),
565558
("__floatsitf", "floatsitf.c"),
566-
("__fixunstfsi", "fixunstfsi.c"),
567559
("__floatunsitf", "floatunsitf.c"),
568560
("__fe_getround", "fp_mode.c"),
569561
]);
@@ -572,9 +564,7 @@ mod c {
572564
if target_arch == "loongarch64" {
573565
sources.extend(&[
574566
("__netf2", "comparetf2.c"),
575-
("__fixtfsi", "fixtfsi.c"),
576567
("__floatsitf", "floatsitf.c"),
577-
("__fixunstfsi", "fixunstfsi.c"),
578568
("__floatunsitf", "floatunsitf.c"),
579569
("__fe_getround", "fp_mode.c"),
580570
]);

Diff for: src/float/conv.rs

+30
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,21 @@ intrinsics! {
261261
pub extern "C" fn __fixunsdfti(f: f64) -> u128 {
262262
float_to_unsigned_int(f)
263263
}
264+
265+
#[cfg(not(feature = "no-f16-f128"))]
266+
pub extern "C" fn __fixunstfsi(f: f128) -> u32 {
267+
float_to_unsigned_int(f)
268+
}
269+
270+
#[cfg(not(feature = "no-f16-f128"))]
271+
pub extern "C" fn __fixunstfdi(f: f128) -> u64 {
272+
float_to_unsigned_int(f)
273+
}
274+
275+
#[cfg(not(feature = "no-f16-f128"))]
276+
pub extern "C" fn __fixunstfti(f: f128) -> u128 {
277+
float_to_unsigned_int(f)
278+
}
264279
}
265280

266281
// Conversions from floats to signed integers.
@@ -294,4 +309,19 @@ intrinsics! {
294309
pub extern "C" fn __fixdfti(f: f64) -> i128 {
295310
float_to_signed_int(f)
296311
}
312+
313+
#[cfg(not(feature = "no-f16-f128"))]
314+
pub extern "C" fn __fixtfsi(f: f128) -> i32 {
315+
float_to_signed_int(f)
316+
}
317+
318+
#[cfg(not(feature = "no-f16-f128"))]
319+
pub extern "C" fn __fixtfdi(f: f128) -> i64 {
320+
float_to_signed_int(f)
321+
}
322+
323+
#[cfg(not(feature = "no-f16-f128"))]
324+
pub extern "C" fn __fixtfti(f: f128) -> i128 {
325+
float_to_signed_int(f)
326+
}
297327
}

Diff for: testcrate/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ no-f16-f128 = ["compiler_builtins/no-f16-f128"]
3434
mem = ["compiler_builtins/mem"]
3535
mangled-names = ["compiler_builtins/mangled-names"]
3636
# Skip tests that rely on f128 symbols being available on the system
37-
no-sys-f128 = []
37+
no-sys-f128 = ["no-sys-f128-int-convert"]
38+
# Some platforms have some f128 functions but everything except integer conversions
39+
no-sys-f128-int-convert = []

Diff for: testcrate/build.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
use std::env;
1+
use std::{collections::HashSet, env};
2+
3+
/// Features to enable
4+
#[derive(Debug, PartialEq, Eq, Hash)]
5+
enum Feature {
6+
NoSysF128,
7+
NoSysF128IntConvert,
8+
}
29

310
fn main() {
411
let target = env::var("TARGET").unwrap();
12+
let mut features = HashSet::new();
513

614
// These platforms do not have f128 symbols available in their system libraries, so
715
// skip related tests.
@@ -21,7 +29,24 @@ fn main() {
2129
// <https://github.com/rust-lang/compiler-builtins/pull/606#issuecomment-2105657287>.
2230
|| target.starts_with("powerpc64-")
2331
{
24-
println!("cargo:warning=using apfloat fallback for f128");
25-
println!("cargo:rustc-cfg=feature=\"no-sys-f128\"");
32+
features.insert(Feature::NoSysF128);
33+
features.insert(Feature::NoSysF128IntConvert);
34+
}
35+
36+
if target.starts_with("i586") || target.starts_with("i686") {
37+
// 32-bit x86 seems to not have `__fixunstfti`, but does have everything else
38+
features.insert(Feature::NoSysF128IntConvert);
39+
}
40+
41+
for feature in features {
42+
let (name, warning) = match feature {
43+
Feature::NoSysF128 => ("no-sys-f128", "using apfloat fallback for f128"),
44+
Feature::NoSysF128IntConvert => (
45+
"no-sys-f128-int-convert",
46+
"using apfloat fallback for f128 to int conversions",
47+
),
48+
};
49+
println!("cargo:warning={warning}");
50+
println!("cargo:rustc-cfg=feature=\"{name}\"");
2651
}
2752
}

Diff for: testcrate/tests/conv.rs

+55-7
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,39 @@ mod f_to_i {
100100
use super::*;
101101

102102
macro_rules! f_to_i {
103-
($x:ident, $($f:ty, $fn:ident);*;) => {
103+
($x:ident, $f_ty:ty, $apfloat_ty:ident, $sys_available:meta, $($i_ty:ty, $fn:ident);*;) => {
104104
$(
105105
// it is undefined behavior in the first place to do conversions with NaNs
106-
if !$x.is_nan() {
107-
let conv0 = $x as $f;
108-
let conv1: $f = $fn($x);
106+
if !apfloat_fallback!(
107+
$f_ty, $apfloat_ty, $sys_available, |x: FloatTy| x.is_nan() => no_convert, $x
108+
) {
109+
let conv0 = apfloat_fallback!(
110+
$f_ty, $apfloat_ty, $sys_available,
111+
// Use an `as` cast when the builtin is available on the system.
112+
|x| x as $i_ty;
113+
// When the builtin is not available, we need to use a different conversion
114+
// method (since apfloat doesn't support `as` casting).
115+
|x: $f_ty| {
116+
use compiler_builtins::int::MinInt;
117+
118+
let apf = FloatTy::from_bits(x.to_bits().into());
119+
let bits: usize = <$i_ty>::BITS.try_into().unwrap();
120+
121+
let err_fn = || panic!(
122+
"Unable to convert value {x:?} to type {}:", stringify!($i_ty)
123+
);
124+
125+
if <$i_ty>::SIGNED {
126+
<$i_ty>::try_from(apf.to_i128(bits).value).ok().unwrap_or_else(err_fn)
127+
} else {
128+
<$i_ty>::try_from(apf.to_u128(bits).value).ok().unwrap_or_else(err_fn)
129+
}
130+
},
131+
$x
132+
);
133+
let conv1: $i_ty = $fn($x);
109134
if conv0 != conv1 {
110-
panic!("{}({}): std: {}, builtins: {}", stringify!($fn), $x, conv0, conv1);
135+
panic!("{}({:?}): std: {:?}, builtins: {:?}", stringify!($fn), $x, conv0, conv1);
111136
}
112137
}
113138
)*
@@ -121,7 +146,7 @@ mod f_to_i {
121146
};
122147

123148
fuzz_float(N, |x: f32| {
124-
f_to_i!(x,
149+
f_to_i!(x, f32, Single, all(),
125150
u32, __fixunssfsi;
126151
u64, __fixunssfdi;
127152
u128, __fixunssfti;
@@ -139,7 +164,7 @@ mod f_to_i {
139164
};
140165

141166
fuzz_float(N, |x: f64| {
142-
f_to_i!(x,
167+
f_to_i!(x, f64, Double, all(),
143168
u32, __fixunsdfsi;
144169
u64, __fixunsdfdi;
145170
u128, __fixunsdfti;
@@ -149,6 +174,29 @@ mod f_to_i {
149174
);
150175
});
151176
}
177+
178+
#[test]
179+
#[cfg(not(feature = "no-f16-f128"))]
180+
fn f128_to_int() {
181+
use compiler_builtins::float::conv::{
182+
__fixtfdi, __fixtfsi, __fixtfti, __fixunstfdi, __fixunstfsi, __fixunstfti,
183+
};
184+
185+
fuzz_float(N, |x: f128| {
186+
f_to_i!(
187+
x,
188+
f128,
189+
Quad,
190+
not(feature = "no-sys-f128-int-convert"),
191+
u32, __fixunstfsi;
192+
u64, __fixunstfdi;
193+
u128, __fixunstfti;
194+
i32, __fixtfsi;
195+
i64, __fixtfdi;
196+
i128, __fixtfti;
197+
);
198+
});
199+
}
152200
}
153201

154202
macro_rules! conv {

0 commit comments

Comments
 (0)