@@ -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,7 +199,7 @@ 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
}
164
205
impl MaybeOverride < ( f64 , f64 ) > for SpecialCase {
@@ -169,47 +210,86 @@ impl MaybeOverride<(f64, f64)> for SpecialCase {
169
210
_ulp : & mut u32 ,
170
211
ctx : & CheckCtx ,
171
212
) -> Option < TestResult > {
172
- maybe_skip_min_max_nan ( input, expected, ctx)
213
+ maybe_skip_binop_nan ( input, expected, ctx)
173
214
}
174
215
}
175
216
176
217
/// Musl propagates NaNs if one is provided as the input, but we return the other input.
177
218
// 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 > (
219
+ fn maybe_skip_binop_nan < F1 : Float , F2 : Float > (
179
220
input : ( F1 , F1 ) ,
180
221
expected : F2 ,
181
222
ctx : & CheckCtx ,
182
223
) -> 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
224
+ match ctx. basis {
225
+ CheckBasis :: Musl => {
226
+ if ( ctx. canonical_name == "fmax" || ctx. canonical_name == "fmin" )
227
+ && ( input. 0 . is_nan ( ) || input. 1 . is_nan ( ) )
228
+ && expected. is_nan ( )
229
+ {
230
+ XFAIL
231
+ } else {
232
+ None
233
+ }
234
+ }
235
+ CheckBasis :: Mpfr => {
236
+ if ctx. canonical_name == "copysign" && input. 1 . is_nan ( ) {
237
+ SKIP
238
+ } else {
239
+ None
240
+ }
241
+ }
190
242
}
191
243
}
192
244
193
245
impl MaybeOverride < ( i32 , f32 ) > for SpecialCase {
194
246
fn check_float < F : Float > (
195
247
input : ( i32 , f32 ) ,
196
- _actual : F ,
197
- _expected : F ,
248
+ actual : F ,
249
+ expected : F ,
198
250
ulp : & mut u32 ,
199
251
ctx : & CheckCtx ,
200
252
) -> Option < TestResult > {
201
- bessel_prec_dropoff ( input, ulp, ctx)
253
+ match ctx. basis {
254
+ CheckBasis :: Musl => bessel_prec_dropoff ( input, ulp, ctx) ,
255
+ CheckBasis :: Mpfr => {
256
+ // We return +0.0, MPFR returns -0.0
257
+ if ctx. fname == "jnf"
258
+ && input. 1 == f32:: NEG_INFINITY
259
+ && actual == F :: ZERO
260
+ && expected == F :: ZERO
261
+ {
262
+ XFAIL
263
+ } else {
264
+ None
265
+ }
266
+ }
267
+ }
202
268
}
203
269
}
204
270
impl MaybeOverride < ( i32 , f64 ) > for SpecialCase {
205
271
fn check_float < F : Float > (
206
272
input : ( i32 , f64 ) ,
207
- _actual : F ,
208
- _expected : F ,
273
+ actual : F ,
274
+ expected : F ,
209
275
ulp : & mut u32 ,
210
276
ctx : & CheckCtx ,
211
277
) -> Option < TestResult > {
212
- bessel_prec_dropoff ( input, ulp, ctx)
278
+ match ctx. basis {
279
+ CheckBasis :: Musl => bessel_prec_dropoff ( input, ulp, ctx) ,
280
+ CheckBasis :: Mpfr => {
281
+ // We return +0.0, MPFR returns -0.0
282
+ if ctx. fname == "jn"
283
+ && input. 1 == f64:: NEG_INFINITY
284
+ && actual == F :: ZERO
285
+ && expected == F :: ZERO
286
+ {
287
+ XFAIL
288
+ } else {
289
+ bessel_prec_dropoff ( input, ulp, ctx)
290
+ }
291
+ }
292
+ }
213
293
}
214
294
}
215
295
0 commit comments