1
1
//! Configuration for skipping or changing the result for individual test cases (inputs) rather
2
2
//! than ignoring entire tests.
3
3
4
- use crate :: { CheckCtx , Float , Int , TestResult } ;
4
+ use core:: f32;
5
+
6
+ use crate :: { CheckBasis , CheckCtx , Float , Int , TestResult } ;
5
7
6
8
/// Type implementing [`IgnoreCase`].
7
9
pub struct SpecialCase ;
@@ -49,37 +51,77 @@ pub trait MaybeOverride<Input> {
49
51
50
52
impl MaybeOverride < ( f32 , ) > for SpecialCase {
51
53
fn check_float < F : Float > (
52
- _input : ( f32 , ) ,
54
+ input : ( f32 , ) ,
53
55
actual : F ,
54
56
expected : F ,
55
57
_ulp : & mut u32 ,
56
58
ctx : & CheckCtx ,
57
59
) -> Option < TestResult > {
60
+ if ctx. basis == CheckBasis :: Musl {
61
+ if ctx. fname == "acoshf" && input. 0 < -1.0 {
62
+ // acoshf is defined for x > 1.0, but musl seems to return results
63
+ // for more negative numbers
64
+ return SKIP ;
65
+ }
66
+
67
+ if ctx. fname == "sincosf" {
68
+ let factor_frac_pi_2 = input. 0 . abs ( ) / f32:: consts:: FRAC_PI_2 ;
69
+ if ( factor_frac_pi_2 - factor_frac_pi_2. round ( ) ) . abs ( ) < 1e-3 {
70
+ // musl has a bad approximation near multiples of pi/2
71
+ return SKIP ;
72
+ }
73
+ }
74
+
75
+ if ctx. fname == "expm1f" && input. 0 > 80.0 && expected. is_infinite ( ) {
76
+ // mustl returns infinity but the number is representable
77
+ return SKIP ;
78
+ }
79
+
80
+ if ctx. fname == "sinhf" && input. 0 . abs ( ) > 80.0 && expected. is_nan ( ) {
81
+ // mustl returns some NaN that should be infinity, or near it
82
+ // doesn't seem to happen on x86
83
+ return SKIP ;
84
+ }
85
+
86
+ if ctx. fname == "lgammaf" || ctx. fname == "lgammaf_r" && input. 0 < 0.0 {
87
+ // loggamma should not be defined for x < 0, yet we both return results
88
+ return XFAIL ;
89
+ }
90
+ }
91
+
58
92
maybe_check_nan_bits ( actual, expected, ctx)
59
93
}
60
94
}
61
95
62
96
impl MaybeOverride < ( f64 , ) > for SpecialCase {
63
97
fn check_float < F : Float > (
64
- _input : ( f64 , ) ,
98
+ input : ( f64 , ) ,
65
99
actual : F ,
66
100
expected : F ,
67
101
_ulp : & mut u32 ,
68
102
ctx : & CheckCtx ,
69
103
) -> Option < TestResult > {
104
+ if ctx. basis == CheckBasis :: Musl {
105
+ if cfg ! ( target_arch = "x86" ) && ctx. fname == "acosh" && input. 0 < 1.0 {
106
+ // The function is undefined, implementations return random results
107
+ return SKIP ;
108
+ }
109
+
110
+ if cfg ! ( x86_no_sse) && ctx. fname == "ceil" && expected == F :: ZERO && actual == F :: ZERO {
111
+ // musl returns -0.0, we return +0.0
112
+ return SKIP ;
113
+ }
114
+
115
+ if ctx. fname == "lgamma" || ctx. fname == "lgamma_r" && input. 0 < 0.0 {
116
+ // loggamma should not be defined for x < 0, yet we both return results
117
+ return XFAIL ;
118
+ }
119
+ }
120
+
70
121
maybe_check_nan_bits ( actual, expected, ctx)
71
122
}
72
123
}
73
124
74
- impl MaybeOverride < ( f32 , f32 ) > for SpecialCase { }
75
- impl MaybeOverride < ( f64 , f64 ) > for SpecialCase { }
76
- impl MaybeOverride < ( f32 , f32 , f32 ) > for SpecialCase { }
77
- impl MaybeOverride < ( f64 , f64 , f64 ) > for SpecialCase { }
78
- impl MaybeOverride < ( i32 , f32 ) > for SpecialCase { }
79
- impl MaybeOverride < ( i32 , f64 ) > for SpecialCase { }
80
- impl MaybeOverride < ( f32 , i32 ) > for SpecialCase { }
81
- impl MaybeOverride < ( f64 , i32 ) > for SpecialCase { }
82
-
83
125
/// Check NaN bits if the function requires it
84
126
fn maybe_check_nan_bits < F : Float > ( actual : F , expected : F , ctx : & CheckCtx ) -> Option < TestResult > {
85
127
if !( ctx. canonical_name == "abs" || ctx. canonical_name == "copysigh" ) {
@@ -93,3 +135,91 @@ fn maybe_check_nan_bits<F: Float>(actual: F, expected: F, ctx: &CheckCtx) -> Opt
93
135
Some ( Err ( anyhow:: anyhow!( "NaNs have different bitpatterns" ) ) )
94
136
}
95
137
}
138
+
139
+ impl MaybeOverride < ( f32 , f32 ) > for SpecialCase {
140
+ fn check_float < F : Float > (
141
+ input : ( f32 , f32 ) ,
142
+ actual : F ,
143
+ _expected : F ,
144
+ _ulp : & mut u32 ,
145
+ ctx : & CheckCtx ,
146
+ ) -> Option < TestResult > {
147
+ maybe_skip_min_max_nan ( input, actual, ctx)
148
+ }
149
+ }
150
+ impl MaybeOverride < ( f64 , f64 ) > for SpecialCase {
151
+ fn check_float < F : Float > (
152
+ input : ( f64 , f64 ) ,
153
+ actual : F ,
154
+ _expected : F ,
155
+ _ulp : & mut u32 ,
156
+ ctx : & CheckCtx ,
157
+ ) -> Option < TestResult > {
158
+ maybe_skip_min_max_nan ( input, actual, ctx)
159
+ }
160
+ }
161
+
162
+ /// Our max and min functions propagate NaNs if proided by the inputs
163
+ // F1 and F2 are always the same type, this is just to please generics
164
+ fn maybe_skip_min_max_nan < F1 : Float , F2 : Float > (
165
+ input : ( F1 , F1 ) ,
166
+ actual : F2 ,
167
+ ctx : & CheckCtx ,
168
+ ) -> Option < TestResult > {
169
+ if ( ctx. canonical_name == "fmax" || ctx. canonical_name == "fmin" )
170
+ && ( input. 0 . is_nan ( ) || input. 1 . is_nan ( ) )
171
+ && actual. is_nan ( )
172
+ {
173
+ return XFAIL ;
174
+ } else {
175
+ None
176
+ }
177
+ }
178
+
179
+ impl MaybeOverride < ( i32 , f32 ) > for SpecialCase {
180
+ fn check_float < F : Float > (
181
+ input : ( i32 , f32 ) ,
182
+ _actual : F ,
183
+ _expected : F ,
184
+ ulp : & mut u32 ,
185
+ ctx : & CheckCtx ,
186
+ ) -> Option < TestResult > {
187
+ bessel_prec_dropoff ( input, ulp, ctx)
188
+ }
189
+ }
190
+ impl MaybeOverride < ( i32 , f64 ) > for SpecialCase {
191
+ fn check_float < F : Float > (
192
+ input : ( i32 , f64 ) ,
193
+ _actual : F ,
194
+ _expected : F ,
195
+ ulp : & mut u32 ,
196
+ ctx : & CheckCtx ,
197
+ ) -> Option < TestResult > {
198
+ bessel_prec_dropoff ( input, ulp, ctx)
199
+ }
200
+ }
201
+
202
+ /// Our bessel functions blow up with large N values
203
+ fn bessel_prec_dropoff < F : Float > (
204
+ input : ( i32 , F ) ,
205
+ ulp : & mut u32 ,
206
+ ctx : & CheckCtx ,
207
+ ) -> Option < TestResult > {
208
+ if ctx. canonical_name == "jn" {
209
+ if input. 0 > 4000 {
210
+ return XFAIL ;
211
+ } else if input. 0 > 2000 {
212
+ // *ulp = 20_000;
213
+ * ulp = 20000 ;
214
+ } else if input. 0 > 1000 {
215
+ * ulp = 4000 ;
216
+ }
217
+ }
218
+
219
+ None
220
+ }
221
+
222
+ impl MaybeOverride < ( f32 , f32 , f32 ) > for SpecialCase { }
223
+ impl MaybeOverride < ( f64 , f64 , f64 ) > for SpecialCase { }
224
+ impl MaybeOverride < ( f32 , i32 ) > for SpecialCase { }
225
+ impl MaybeOverride < ( f64 , i32 ) > for SpecialCase { }
0 commit comments