@@ -96,14 +96,41 @@ fn int_to_float() {
96
96
}
97
97
98
98
macro_rules! f_to_i {
99
- ( $x: ident, $( $f : ty, $fn: ident) ;* ; ) => {
99
+ ( $x: ident, $f_ty : ty , $apfloat_ty : ident , $sys_available : meta , $ ( $i_ty : ty, $fn: ident) ;* ; ) => {
100
100
$(
101
101
// it is undefined behavior in the first place to do conversions with NaNs
102
- if !$x. is_nan( ) {
103
- let conv0 = $x as $f;
104
- let conv1: $f = $fn( $x) ;
102
+ if !apfloat_fallback!(
103
+ $f_ty, $apfloat_ty, $sys_available, |x: FloatTy | x. is_nan( ) => no_convert, $x
104
+ ) {
105
+ let conv0 = apfloat_fallback!(
106
+ $f_ty, $apfloat_ty, $sys_available,
107
+ // Use an `as` cast when the builtin is available on the system.
108
+ |x| x as $i_ty;
109
+ // When the builtin is not available, we need to use a different conversion
110
+ // method (since apfloat doesn't support `as` casting).
111
+ |x: $f_ty| {
112
+ use compiler_builtins:: int:: MinInt ;
113
+
114
+ let apf = FloatTy :: from_bits( x. to_bits( ) . into( ) ) ;
115
+ let bits: usize = <$i_ty>:: BITS . try_into( ) . unwrap( ) ;
116
+
117
+ let err_fn = || panic!(
118
+ "Unable to convert value {x:?} to type {}:" , stringify!( $i_ty)
119
+ ) ;
120
+
121
+ if <$i_ty>:: SIGNED {
122
+ <$i_ty>:: try_from( apf. to_i128( bits) . value) . ok( ) . unwrap_or_else( err_fn)
123
+ } else {
124
+ <$i_ty>:: try_from( apf. to_u128( bits) . value) . ok( ) . unwrap_or_else( err_fn)
125
+ }
126
+ } ,
127
+ $x
128
+ ) ;
129
+
130
+ // $x as $i_ty;
131
+ let conv1: $i_ty = $fn( $x) ;
105
132
if conv0 != conv1 {
106
- panic!( "{}({}): std: {}, builtins: {}" , stringify!( $fn) , $x, conv0, conv1) ;
133
+ panic!( "{}({:? }): std: {:? }, builtins: {:? }" , stringify!( $fn) , $x, conv0, conv1) ;
107
134
}
108
135
}
109
136
) *
@@ -120,7 +147,7 @@ fn float_to_int() {
120
147
} ;
121
148
122
149
fuzz_float ( N , |x : f32 | {
123
- f_to_i ! ( x,
150
+ f_to_i ! ( x, f32 , Single , all ( ) ,
124
151
u32 , __fixunssfsi;
125
152
u64 , __fixunssfdi;
126
153
u128 , __fixunssfti;
@@ -130,7 +157,7 @@ fn float_to_int() {
130
157
) ;
131
158
} ) ;
132
159
fuzz_float ( N , |x : f64 | {
133
- f_to_i ! ( x,
160
+ f_to_i ! ( x, f64 , Double , all ( ) ,
134
161
u32 , __fixunsdfsi;
135
162
u64 , __fixunsdfdi;
136
163
u128 , __fixunsdfti;
0 commit comments