Skip to content

Commit 3567586

Browse files
RalfJungworkingjubilee
authored andcommitted
enable and extend float-classify test
1 parent c40ee79 commit 3567586

File tree

3 files changed

+126
-126
lines changed

3 files changed

+126
-126
lines changed

Diff for: tests/ui/float/classify-runtime-const.rs

+39-34
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,45 @@
11
//@ compile-flags: -Zmir-opt-level=0 -Znext-solver
2-
//@ known-bug: #110395
3-
// FIXME(effects) run-pass
2+
//@ run-pass
3+
// ignore-tidy-linelength
44

5+
// This tests the float classification functions, for regular runtime code and for const evaluation.
6+
7+
#![feature(const_float_bits_conv)]
58
#![feature(const_float_classify)]
6-
#![feature(const_trait_impl, effects)]
7-
#![allow(incomplete_features)]
89

9-
// Don't promote
10-
const fn nop<T>(x: T) -> T { x }
10+
use std::hint::black_box;
11+
use std::num::FpCategory::*;
1112

12-
impl const PartialEq<NonDet> for bool {
13-
fn eq(&self, _: &NonDet) -> bool {
14-
true
15-
}
16-
}
17-
18-
macro_rules! const_assert {
19-
($a:expr, $b:expr) => {
13+
macro_rules! both_assert {
14+
($a:expr, NonDet) => {
2015
{
21-
const _: () = assert!($a == $b);
22-
assert!(nop($a) == nop($b));
16+
// Compute `a`, but do not compare with anything as the result is non-deterministic.
17+
const _: () = { let _val = $a; };
18+
// `black_box` prevents promotion, and MIR opts are disabled above, so this is truly
19+
// going through LLVM.
20+
let _val = black_box($a);
21+
}
22+
};
23+
($a:expr, $b:ident) => {
24+
{
25+
const _: () = assert!(matches!($a, $b));
26+
assert!(black_box($a) == black_box($b));
2327
}
2428
};
2529
}
2630

2731
macro_rules! suite {
28-
( $( $tt:tt )* ) => {
32+
( $tyname:ident: $( $tt:tt )* ) => {
2933
fn f32() {
34+
type $tyname = f32;
3035
suite_inner!(f32 $($tt)*);
3136
}
3237

3338
fn f64() {
39+
type $tyname = f64;
3440
suite_inner!(f64 $($tt)*);
3541
}
3642
}
37-
3843
}
3944

4045
macro_rules! suite_inner {
@@ -44,33 +49,33 @@ macro_rules! suite_inner {
4449

4550
$( $tail:tt )*
4651
) => {
47-
$( const_assert!($ty::$fn($val), $out); )*
52+
$( both_assert!($ty::$fn($val), $out); )*
4853
suite_inner!($ty [$($fn),*] $($tail)*)
4954
};
5055

5156
( $ty:ident [$( $fn:ident ),*]) => {};
5257
}
5358

54-
#[derive(Debug)]
55-
struct NonDet;
56-
57-
// The result of the `is_sign` methods are not checked for correctness, since LLVM does not
59+
// The result of the `is_sign` methods are not checked for correctness, since we do not
5860
// guarantee anything about the signedness of NaNs. See
59-
// https://github.com/rust-lang/rust/issues/55131.
61+
// https://rust-lang.github.io/rfcs/3514-float-semantics.html.
6062

61-
suite! {
62-
[is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative]
63-
-0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet]
64-
0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet]
65-
1.0 => [ false, false, true, true, true, false]
66-
-1.0 => [ false, false, true, true, false, true]
67-
0.0 => [ false, false, true, false, true, false]
68-
-0.0 => [ false, false, true, false, false, true]
69-
1.0 / 0.0 => [ false, true, false, false, true, false]
70-
-1.0 / 0.0 => [ false, true, false, false, false, true]
63+
suite! { T: // type alias for the type we are testing
64+
[ classify, is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative]
65+
-0.0 / 0.0 => [ Nan, true, false, false, false, NonDet, NonDet]
66+
0.0 / 0.0 => [ Nan, true, false, false, false, NonDet, NonDet]
67+
1.0 => [ Normal, false, false, true, true, true, false]
68+
-1.0 => [ Normal, false, false, true, true, false, true]
69+
0.0 => [ Zero, false, false, true, false, true, false]
70+
-0.0 => [ Zero, false, false, true, false, false, true]
71+
1.0 / 0.0 => [ Infinite, false, true, false, false, true, false]
72+
-1.0 / 0.0 => [ Infinite, false, true, false, false, false, true]
73+
1.0 / T::MAX => [Subnormal, false, false, true, false, true, false]
74+
-1.0 / T::MAX => [Subnormal, false, false, true, false, false, true]
7175
}
7276

7377
fn main() {
7478
f32();
7579
f64();
80+
// FIXME(f16_f128): also test f16 and f128
7681
}

Diff for: tests/ui/float/classify-runtime-const.stderr

-11
This file was deleted.

Diff for: tests/ui/float/conv-bits-runtime-const.rs

+87-81
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,167 @@
11
//@ compile-flags: -Zmir-opt-level=0
22
//@ run-pass
33

4+
// This tests the float classification functions, for regular runtime code and for const evaluation.
5+
6+
#![feature(const_float_bits_conv)]
47
#![feature(const_float_classify)]
5-
#![feature(f16, f16_const)]
6-
#![feature(f128, f128_const)]
8+
#![feature(f16)]
9+
#![feature(f128)]
710
#![allow(unused_macro_rules)]
8-
// Don't promote
9-
const fn nop<T>(x: T) -> T { x }
1011

11-
macro_rules! const_assert {
12+
use std::hint::black_box;
13+
14+
macro_rules! both_assert {
1215
($a:expr) => {
1316
{
1417
const _: () = assert!($a);
15-
assert!(nop($a));
18+
// `black_box` prevents promotion, and MIR opts are disabled above, so this is truly
19+
// going through LLVM.
20+
assert!(black_box($a));
1621
}
1722
};
1823
($a:expr, $b:expr) => {
1924
{
2025
const _: () = assert!($a == $b);
21-
assert_eq!(nop($a), nop($b));
26+
assert_eq!(black_box($a), black_box($b));
2227
}
2328
};
2429
}
2530

2631
fn has_broken_floats() -> bool {
2732
// i586 targets are broken due to <https://github.com/rust-lang/rust/issues/114479>.
28-
std::env::var("TARGET").is_ok_and(|v| v.contains("i586"))
33+
cfg!(all(target_arch = "x86", not(target_feature = "sse2")))
2934
}
3035

3136
#[cfg(target_arch = "x86_64")]
3237
fn f16(){
33-
const_assert!((1f16).to_bits(), 0x3c00);
34-
const_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00);
35-
const_assert!((12.5f16).to_bits(), 0x4a40);
36-
const_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40);
37-
const_assert!((1337f16).to_bits(), 0x6539);
38-
const_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539);
39-
const_assert!((-14.25f16).to_bits(), 0xcb20);
40-
const_assert!(f16::from_bits(0x3c00), 1.0);
41-
const_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0);
42-
const_assert!(f16::from_bits(0x4a40), 12.5);
43-
const_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5);
44-
const_assert!(f16::from_bits(0x5be0), 252.0);
45-
const_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0);
46-
const_assert!(f16::from_bits(0xcb20), -14.25);
38+
both_assert!((1f16).to_bits(), 0x3c00);
39+
both_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00);
40+
both_assert!((12.5f16).to_bits(), 0x4a40);
41+
both_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40);
42+
both_assert!((1337f16).to_bits(), 0x6539);
43+
both_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539);
44+
both_assert!((-14.25f16).to_bits(), 0xcb20);
45+
both_assert!(f16::from_bits(0x3c00), 1.0);
46+
both_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0);
47+
both_assert!(f16::from_bits(0x4a40), 12.5);
48+
both_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5);
49+
both_assert!(f16::from_bits(0x5be0), 252.0);
50+
both_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0);
51+
both_assert!(f16::from_bits(0xcb20), -14.25);
4752

4853
// Check that NaNs roundtrip their bits regardless of signalingness
4954
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
5055
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
5156
const QUIET_NAN: u16 = f16::NAN.to_bits() ^ 0x0155;
5257
const SIGNALING_NAN: u16 = f16::NAN.to_bits() ^ 0x02AA;
5358

54-
const_assert!(f16::from_bits(QUIET_NAN).is_nan());
55-
const_assert!(f16::from_bits(SIGNALING_NAN).is_nan());
56-
const_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
59+
both_assert!(f16::from_bits(QUIET_NAN).is_nan());
60+
both_assert!(f16::from_bits(SIGNALING_NAN).is_nan());
61+
both_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
5762
if !has_broken_floats() {
58-
const_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
63+
both_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
5964
}
6065
}
6166

6267
fn f32() {
63-
const_assert!((1f32).to_bits(), 0x3f800000);
64-
const_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000);
65-
const_assert!((12.5f32).to_bits(), 0x41480000);
66-
const_assert!(u32::from_le_bytes(12.5f32.to_le_bytes()), 0x41480000);
67-
const_assert!((1337f32).to_bits(), 0x44a72000);
68-
const_assert!(u32::from_ne_bytes(1337f32.to_ne_bytes()), 0x44a72000);
69-
const_assert!((-14.25f32).to_bits(), 0xc1640000);
70-
const_assert!(f32::from_bits(0x3f800000), 1.0);
71-
const_assert!(f32::from_be_bytes(0x3f800000u32.to_be_bytes()), 1.0);
72-
const_assert!(f32::from_bits(0x41480000), 12.5);
73-
const_assert!(f32::from_le_bytes(0x41480000u32.to_le_bytes()), 12.5);
74-
const_assert!(f32::from_bits(0x44a72000), 1337.0);
75-
const_assert!(f32::from_ne_bytes(0x44a72000u32.to_ne_bytes()), 1337.0);
76-
const_assert!(f32::from_bits(0xc1640000), -14.25);
68+
both_assert!((1f32).to_bits(), 0x3f800000);
69+
both_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000);
70+
both_assert!((12.5f32).to_bits(), 0x41480000);
71+
both_assert!(u32::from_le_bytes(12.5f32.to_le_bytes()), 0x41480000);
72+
both_assert!((1337f32).to_bits(), 0x44a72000);
73+
both_assert!(u32::from_ne_bytes(1337f32.to_ne_bytes()), 0x44a72000);
74+
both_assert!((-14.25f32).to_bits(), 0xc1640000);
75+
both_assert!(f32::from_bits(0x3f800000), 1.0);
76+
both_assert!(f32::from_be_bytes(0x3f800000u32.to_be_bytes()), 1.0);
77+
both_assert!(f32::from_bits(0x41480000), 12.5);
78+
both_assert!(f32::from_le_bytes(0x41480000u32.to_le_bytes()), 12.5);
79+
both_assert!(f32::from_bits(0x44a72000), 1337.0);
80+
both_assert!(f32::from_ne_bytes(0x44a72000u32.to_ne_bytes()), 1337.0);
81+
both_assert!(f32::from_bits(0xc1640000), -14.25);
7782

7883
// Check that NaNs roundtrip their bits regardless of signalingness
7984
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
8085
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
8186
const QUIET_NAN: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
8287
const SIGNALING_NAN: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
8388

84-
const_assert!(f32::from_bits(QUIET_NAN).is_nan());
85-
const_assert!(f32::from_bits(SIGNALING_NAN).is_nan());
86-
const_assert!(f32::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
89+
both_assert!(f32::from_bits(QUIET_NAN).is_nan());
90+
both_assert!(f32::from_bits(SIGNALING_NAN).is_nan());
91+
both_assert!(f32::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
8792
if !has_broken_floats() {
88-
const_assert!(f32::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
93+
both_assert!(f32::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
8994
}
9095
}
9196

9297
fn f64() {
93-
const_assert!((1f64).to_bits(), 0x3ff0000000000000);
94-
const_assert!(u64::from_be_bytes(1f64.to_be_bytes()), 0x3ff0000000000000);
95-
const_assert!((12.5f64).to_bits(), 0x4029000000000000);
96-
const_assert!(u64::from_le_bytes(12.5f64.to_le_bytes()), 0x4029000000000000);
97-
const_assert!((1337f64).to_bits(), 0x4094e40000000000);
98-
const_assert!(u64::from_ne_bytes(1337f64.to_ne_bytes()), 0x4094e40000000000);
99-
const_assert!((-14.25f64).to_bits(), 0xc02c800000000000);
100-
const_assert!(f64::from_bits(0x3ff0000000000000), 1.0);
101-
const_assert!(f64::from_be_bytes(0x3ff0000000000000u64.to_be_bytes()), 1.0);
102-
const_assert!(f64::from_bits(0x4029000000000000), 12.5);
103-
const_assert!(f64::from_le_bytes(0x4029000000000000u64.to_le_bytes()), 12.5);
104-
const_assert!(f64::from_bits(0x4094e40000000000), 1337.0);
105-
const_assert!(f64::from_ne_bytes(0x4094e40000000000u64.to_ne_bytes()), 1337.0);
106-
const_assert!(f64::from_bits(0xc02c800000000000), -14.25);
98+
both_assert!((1f64).to_bits(), 0x3ff0000000000000);
99+
both_assert!(u64::from_be_bytes(1f64.to_be_bytes()), 0x3ff0000000000000);
100+
both_assert!((12.5f64).to_bits(), 0x4029000000000000);
101+
both_assert!(u64::from_le_bytes(12.5f64.to_le_bytes()), 0x4029000000000000);
102+
both_assert!((1337f64).to_bits(), 0x4094e40000000000);
103+
both_assert!(u64::from_ne_bytes(1337f64.to_ne_bytes()), 0x4094e40000000000);
104+
both_assert!((-14.25f64).to_bits(), 0xc02c800000000000);
105+
both_assert!(f64::from_bits(0x3ff0000000000000), 1.0);
106+
both_assert!(f64::from_be_bytes(0x3ff0000000000000u64.to_be_bytes()), 1.0);
107+
both_assert!(f64::from_bits(0x4029000000000000), 12.5);
108+
both_assert!(f64::from_le_bytes(0x4029000000000000u64.to_le_bytes()), 12.5);
109+
both_assert!(f64::from_bits(0x4094e40000000000), 1337.0);
110+
both_assert!(f64::from_ne_bytes(0x4094e40000000000u64.to_ne_bytes()), 1337.0);
111+
both_assert!(f64::from_bits(0xc02c800000000000), -14.25);
107112

108113
// Check that NaNs roundtrip their bits regardless of signalingness
109114
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
110115
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
111116
const QUIET_NAN: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
112117
const SIGNALING_NAN: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
113118

114-
const_assert!(f64::from_bits(QUIET_NAN).is_nan());
115-
const_assert!(f64::from_bits(SIGNALING_NAN).is_nan());
116-
const_assert!(f64::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
119+
both_assert!(f64::from_bits(QUIET_NAN).is_nan());
120+
both_assert!(f64::from_bits(SIGNALING_NAN).is_nan());
121+
both_assert!(f64::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
117122
if !has_broken_floats() {
118-
const_assert!(f64::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
123+
both_assert!(f64::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
119124
}
120125
}
121126

122127
#[cfg(target_arch = "x86_64")]
123128
fn f128() {
124-
const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
125-
const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000);
126-
const_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
127-
const_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000);
128-
const_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000);
129-
const_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000);
130-
const_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000);
131-
const_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0);
132-
const_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0);
133-
const_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5);
134-
const_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5);
135-
const_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0);
129+
both_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
130+
both_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000);
131+
both_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
132+
both_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000);
133+
both_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000);
134+
both_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000);
135+
both_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000);
136+
both_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0);
137+
both_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0);
138+
both_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5);
139+
both_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5);
140+
both_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0);
136141
assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0);
137-
const_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25);
142+
both_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25);
138143

139144
// Check that NaNs roundtrip their bits regardless of signalingness
140145
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
141146
// NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
142147
const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA;
143148
const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555;
144149

145-
const_assert!(f128::from_bits(QUIET_NAN).is_nan());
146-
const_assert!(f128::from_bits(SIGNALING_NAN).is_nan());
147-
const_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
150+
both_assert!(f128::from_bits(QUIET_NAN).is_nan());
151+
both_assert!(f128::from_bits(SIGNALING_NAN).is_nan());
152+
both_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
148153
if !has_broken_floats() {
149-
const_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
154+
both_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
150155
}
151156
}
152157

153158
fn main() {
159+
f32();
160+
f64();
161+
154162
#[cfg(target_arch = "x86_64")]
155163
{
156164
f16();
157165
f128();
158166
}
159-
f32();
160-
f64();
161167
}

0 commit comments

Comments
 (0)