@@ -58,20 +58,6 @@ impl MaybeOverride<(f32,)> for SpecialCase {
58
58
ctx : & CheckCtx ,
59
59
) -> Option < TestResult > {
60
60
if ctx. basis == CheckBasis :: Musl {
61
- if ctx. fname == "acoshf" && input. 0 < -1.0 {
62
- // acoshf is undefined for x <= 1.0, but we return a random result at lower
63
- // values.
64
- return XFAIL ;
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-2 {
70
- // we have a bad approximation near multiples of pi/2
71
- return XFAIL ;
72
- }
73
- }
74
-
75
61
if ctx. fname == "expm1f" && input. 0 > 80.0 && actual. is_infinite ( ) {
76
62
// we return infinity but the number is representable
77
63
return XFAIL ;
@@ -82,15 +68,40 @@ impl MaybeOverride<(f32,)> for SpecialCase {
82
68
// doesn't seem to happen on x86
83
69
return XFAIL ;
84
70
}
71
+ }
85
72
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
- }
73
+ if ctx. fname == "acoshf" && input. 0 < -1.0 {
74
+ // acoshf is undefined for x <= 1.0, but we return a random result at lower
75
+ // values.
76
+ return XFAIL ;
77
+ }
78
+
79
+ if ctx. fname == "lgammaf" || ctx. fname == "lgammaf_r" && input. 0 < 0.0 {
80
+ // loggamma should not be defined for x < 0, yet we both return results
81
+ return XFAIL ;
90
82
}
91
83
92
84
maybe_check_nan_bits ( actual, expected, ctx)
93
85
}
86
+
87
+ fn check_int < I : Int > (
88
+ input : ( f32 , ) ,
89
+ actual : I ,
90
+ expected : I ,
91
+ ctx : & CheckCtx ,
92
+ ) -> Option < anyhow:: Result < ( ) > > {
93
+ // On MPFR for lgammaf_r, we set -1 as the integer result for negative infinity but MPFR
94
+ // sets +1
95
+ if ctx. basis == CheckBasis :: Mpfr
96
+ && ctx. fname == "lgammaf_r"
97
+ && input. 0 == f32:: NEG_INFINITY
98
+ && actual. abs ( ) == expected. abs ( )
99
+ {
100
+ XFAIL
101
+ } else {
102
+ None
103
+ }
104
+ }
94
105
}
95
106
96
107
impl MaybeOverride < ( f64 , ) > for SpecialCase {
@@ -117,15 +128,40 @@ impl MaybeOverride<(f64,)> for SpecialCase {
117
128
// musl returns -0.0, we return +0.0
118
129
return XFAIL ;
119
130
}
131
+ }
120
132
121
- if ctx. fname == "lgamma" || ctx. fname == "lgamma_r" && input. 0 < 0.0 {
122
- // loggamma should not be defined for x < 0, yet we both return results
123
- return XFAIL ;
124
- }
133
+ if ctx. fname == "acosh" && input. 0 < 1.0 {
134
+ // The function is undefined for the inputs, musl and our libm both return
135
+ // random results.
136
+ return XFAIL ;
137
+ }
138
+
139
+ if ctx. fname == "lgamma" || ctx. fname == "lgamma_r" && input. 0 < 0.0 {
140
+ // loggamma should not be defined for x < 0, yet we both return results
141
+ return XFAIL ;
125
142
}
126
143
127
144
maybe_check_nan_bits ( actual, expected, ctx)
128
145
}
146
+
147
+ fn check_int < I : Int > (
148
+ input : ( f64 , ) ,
149
+ actual : I ,
150
+ expected : I ,
151
+ ctx : & CheckCtx ,
152
+ ) -> Option < anyhow:: Result < ( ) > > {
153
+ // On MPFR for lgamma_r, we set -1 as the integer result for negative infinity but MPFR
154
+ // sets +1
155
+ if ctx. basis == CheckBasis :: Mpfr
156
+ && ctx. fname == "lgamma_r"
157
+ && input. 0 == f64:: NEG_INFINITY
158
+ && actual. abs ( ) == expected. abs ( )
159
+ {
160
+ XFAIL
161
+ } else {
162
+ None
163
+ }
164
+ }
129
165
}
130
166
131
167
/// Check NaN bits if the function requires it
@@ -142,6 +178,11 @@ fn maybe_check_nan_bits<F: Float>(actual: F, expected: F, ctx: &CheckCtx) -> Opt
142
178
return SKIP ;
143
179
}
144
180
181
+ // MPFR only has one NaN bitpattern; allow the default `.is_nan()` checks to validate.
182
+ if ctx. basis == CheckBasis :: Mpfr {
183
+ return SKIP ;
184
+ }
185
+
145
186
// abs and copysign require signaling NaNs to be propagated, so verify bit equality.
146
187
if actual. to_bits ( ) == expected. to_bits ( ) {
147
188
return SKIP ;
@@ -158,9 +199,10 @@ impl MaybeOverride<(f32, f32)> for SpecialCase {
158
199
_ulp : & mut u32 ,
159
200
ctx : & CheckCtx ,
160
201
) -> Option < TestResult > {
161
- maybe_skip_min_max_nan ( input, expected, ctx)
202
+ maybe_skip_binop_nan ( input, expected, ctx)
162
203
}
163
204
}
205
+
164
206
impl MaybeOverride < ( f64 , f64 ) > for SpecialCase {
165
207
fn check_float < F : Float > (
166
208
input : ( f64 , f64 ) ,
@@ -169,47 +211,86 @@ impl MaybeOverride<(f64, f64)> for SpecialCase {
169
211
_ulp : & mut u32 ,
170
212
ctx : & CheckCtx ,
171
213
) -> Option < TestResult > {
172
- maybe_skip_min_max_nan ( input, expected, ctx)
214
+ maybe_skip_binop_nan ( input, expected, ctx)
173
215
}
174
216
}
175
217
176
218
/// Musl propagates NaNs if one is provided as the input, but we return the other input.
177
219
// F1 and F2 are always the same type, this is just to please generics
178
- fn maybe_skip_min_max_nan < F1 : Float , F2 : Float > (
220
+ fn maybe_skip_binop_nan < F1 : Float , F2 : Float > (
179
221
input : ( F1 , F1 ) ,
180
222
expected : F2 ,
181
223
ctx : & CheckCtx ,
182
224
) -> Option < TestResult > {
183
- if ( ctx. canonical_name == "fmax" || ctx. canonical_name == "fmin" )
184
- && ( input. 0 . is_nan ( ) || input. 1 . is_nan ( ) )
185
- && expected. is_nan ( )
186
- {
187
- return XFAIL ;
188
- } else {
189
- None
225
+ match ctx. basis {
226
+ CheckBasis :: Musl => {
227
+ if ( ctx. canonical_name == "fmax" || ctx. canonical_name == "fmin" )
228
+ && ( input. 0 . is_nan ( ) || input. 1 . is_nan ( ) )
229
+ && expected. is_nan ( )
230
+ {
231
+ XFAIL
232
+ } else {
233
+ None
234
+ }
235
+ }
236
+ CheckBasis :: Mpfr => {
237
+ if ctx. canonical_name == "copysign" && input. 1 . is_nan ( ) {
238
+ SKIP
239
+ } else {
240
+ None
241
+ }
242
+ }
190
243
}
191
244
}
192
245
193
246
impl MaybeOverride < ( i32 , f32 ) > for SpecialCase {
194
247
fn check_float < F : Float > (
195
248
input : ( i32 , f32 ) ,
196
- _actual : F ,
197
- _expected : F ,
249
+ actual : F ,
250
+ expected : F ,
198
251
ulp : & mut u32 ,
199
252
ctx : & CheckCtx ,
200
253
) -> Option < TestResult > {
201
- bessel_prec_dropoff ( input, ulp, ctx)
254
+ match ctx. basis {
255
+ CheckBasis :: Musl => bessel_prec_dropoff ( input, ulp, ctx) ,
256
+ CheckBasis :: Mpfr => {
257
+ // We return +0.0, MPFR returns -0.0
258
+ if ctx. fname == "jnf"
259
+ && input. 1 == f32:: NEG_INFINITY
260
+ && actual == F :: ZERO
261
+ && expected == F :: ZERO
262
+ {
263
+ XFAIL
264
+ } else {
265
+ None
266
+ }
267
+ }
268
+ }
202
269
}
203
270
}
204
271
impl MaybeOverride < ( i32 , f64 ) > for SpecialCase {
205
272
fn check_float < F : Float > (
206
273
input : ( i32 , f64 ) ,
207
- _actual : F ,
208
- _expected : F ,
274
+ actual : F ,
275
+ expected : F ,
209
276
ulp : & mut u32 ,
210
277
ctx : & CheckCtx ,
211
278
) -> Option < TestResult > {
212
- bessel_prec_dropoff ( input, ulp, ctx)
279
+ match ctx. basis {
280
+ CheckBasis :: Musl => bessel_prec_dropoff ( input, ulp, ctx) ,
281
+ CheckBasis :: Mpfr => {
282
+ // We return +0.0, MPFR returns -0.0
283
+ if ctx. fname == "jn"
284
+ && input. 1 == f64:: NEG_INFINITY
285
+ && actual == F :: ZERO
286
+ && expected == F :: ZERO
287
+ {
288
+ XFAIL
289
+ } else {
290
+ bessel_prec_dropoff ( input, ulp, ctx)
291
+ }
292
+ }
293
+ }
213
294
}
214
295
}
215
296
0 commit comments