@@ -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
@@ -138,6 +182,12 @@ fn maybe_check_nan_bits<F: Float>(actual: F, expected: F, ctx: &CheckCtx) -> Opt
138
182
if cfg ! ( target_arch = "x86" ) && ctx. basis == CheckBasis :: Musl && ctx. canonical_name == "fabs" {
139
183
return SKIP ;
140
184
}
185
+
186
+ // MPFR only has one NaN bitpattern; allow the default `.is_nan()` checks to validate.
187
+ if ctx. basis == CheckBasis :: Mpfr {
188
+ return SKIP ;
189
+ }
190
+
141
191
// abs and copysign require signaling NaNs to be propagated, so verify bit equality.
142
192
if actual. to_bits ( ) == expected. to_bits ( ) {
143
193
return SKIP ;
@@ -154,7 +204,7 @@ impl MaybeOverride<(f32, f32)> for SpecialCase {
154
204
_ulp : & mut u32 ,
155
205
ctx : & CheckCtx ,
156
206
) -> Option < TestResult > {
157
- maybe_skip_min_max_nan ( input, expected, ctx)
207
+ maybe_skip_binop_nan ( input, expected, ctx)
158
208
}
159
209
}
160
210
impl MaybeOverride < ( f64 , f64 ) > for SpecialCase {
@@ -165,47 +215,86 @@ impl MaybeOverride<(f64, f64)> for SpecialCase {
165
215
_ulp : & mut u32 ,
166
216
ctx : & CheckCtx ,
167
217
) -> Option < TestResult > {
168
- maybe_skip_min_max_nan ( input, expected, ctx)
218
+ maybe_skip_binop_nan ( input, expected, ctx)
169
219
}
170
220
}
171
221
172
222
/// Musl propagates NaNs if one is provided as the input, but we return the other input.
173
223
// F1 and F2 are always the same type, this is just to please generics
174
- fn maybe_skip_min_max_nan < F1 : Float , F2 : Float > (
224
+ fn maybe_skip_binop_nan < F1 : Float , F2 : Float > (
175
225
input : ( F1 , F1 ) ,
176
226
expected : F2 ,
177
227
ctx : & CheckCtx ,
178
228
) -> Option < TestResult > {
179
- if ( ctx. canonical_name == "fmax" || ctx. canonical_name == "fmin" )
180
- && ( input. 0 . is_nan ( ) || input. 1 . is_nan ( ) )
181
- && expected. is_nan ( )
182
- {
183
- return XFAIL ;
184
- } else {
185
- None
229
+ match ctx. basis {
230
+ CheckBasis :: Musl => {
231
+ if ( ctx. canonical_name == "fmax" || ctx. canonical_name == "fmin" )
232
+ && ( input. 0 . is_nan ( ) || input. 1 . is_nan ( ) )
233
+ && expected. is_nan ( )
234
+ {
235
+ XFAIL
236
+ } else {
237
+ None
238
+ }
239
+ }
240
+ CheckBasis :: Mpfr => {
241
+ if ctx. canonical_name == "copysign" && input. 1 . is_nan ( ) {
242
+ SKIP
243
+ } else {
244
+ None
245
+ }
246
+ }
186
247
}
187
248
}
188
249
189
250
impl MaybeOverride < ( i32 , f32 ) > for SpecialCase {
190
251
fn check_float < F : Float > (
191
252
input : ( i32 , f32 ) ,
192
- _actual : F ,
193
- _expected : F ,
253
+ actual : F ,
254
+ expected : F ,
194
255
ulp : & mut u32 ,
195
256
ctx : & CheckCtx ,
196
257
) -> Option < TestResult > {
197
- bessel_prec_dropoff ( input, ulp, ctx)
258
+ match ctx. basis {
259
+ CheckBasis :: Musl => bessel_prec_dropoff ( input, ulp, ctx) ,
260
+ CheckBasis :: Mpfr => {
261
+ // We return +0.0, MPFR returns -0.0
262
+ if ctx. fname == "jnf"
263
+ && input. 1 == f32:: NEG_INFINITY
264
+ && actual == F :: ZERO
265
+ && expected == F :: ZERO
266
+ {
267
+ XFAIL
268
+ } else {
269
+ None
270
+ }
271
+ }
272
+ }
198
273
}
199
274
}
200
275
impl MaybeOverride < ( i32 , f64 ) > for SpecialCase {
201
276
fn check_float < F : Float > (
202
277
input : ( i32 , f64 ) ,
203
- _actual : F ,
204
- _expected : F ,
278
+ actual : F ,
279
+ expected : F ,
205
280
ulp : & mut u32 ,
206
281
ctx : & CheckCtx ,
207
282
) -> Option < TestResult > {
208
- bessel_prec_dropoff ( input, ulp, ctx)
283
+ match ctx. basis {
284
+ CheckBasis :: Musl => bessel_prec_dropoff ( input, ulp, ctx) ,
285
+ CheckBasis :: Mpfr => {
286
+ // We return +0.0, MPFR returns -0.0
287
+ if ctx. fname == "jn"
288
+ && input. 1 == f64:: NEG_INFINITY
289
+ && actual == F :: ZERO
290
+ && expected == F :: ZERO
291
+ {
292
+ XFAIL
293
+ } else {
294
+ None
295
+ }
296
+ }
297
+ }
209
298
}
210
299
}
211
300
0 commit comments