@@ -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
154202macro_rules! conv {
0 commit comments