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