@@ -58,20 +58,6 @@ impl MaybeOverride<(f32,)> for SpecialCase {
5858 ctx : & CheckCtx ,
5959 ) -> Option < TestResult > {
6060 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-
7561 if ctx. fname == "expm1f" && input. 0 > 80.0 && actual. is_infinite ( ) {
7662 // we return infinity but the number is representable
7763 return XFAIL ;
@@ -82,15 +68,40 @@ impl MaybeOverride<(f32,)> for SpecialCase {
8268 // doesn't seem to happen on x86
8369 return XFAIL ;
8470 }
71+ }
8572
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 ;
9082 }
9183
9284 maybe_check_nan_bits ( actual, expected, ctx)
9385 }
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+ }
94105}
95106
96107impl MaybeOverride < ( f64 , ) > for SpecialCase {
@@ -117,15 +128,40 @@ impl MaybeOverride<(f64,)> for SpecialCase {
117128 // musl returns -0.0, we return +0.0
118129 return XFAIL ;
119130 }
131+ }
120132
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 ;
125142 }
126143
127144 maybe_check_nan_bits ( actual, expected, ctx)
128145 }
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+ }
129165}
130166
131167/// 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
142178 return SKIP ;
143179 }
144180
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+
145186 // abs and copysign require signaling NaNs to be propagated, so verify bit equality.
146187 if actual. to_bits ( ) == expected. to_bits ( ) {
147188 return SKIP ;
@@ -158,9 +199,10 @@ impl MaybeOverride<(f32, f32)> for SpecialCase {
158199 _ulp : & mut u32 ,
159200 ctx : & CheckCtx ,
160201 ) -> Option < TestResult > {
161- maybe_skip_min_max_nan ( input, expected, ctx)
202+ maybe_skip_binop_nan ( input, expected, ctx)
162203 }
163204}
205+
164206impl MaybeOverride < ( f64 , f64 ) > for SpecialCase {
165207 fn check_float < F : Float > (
166208 input : ( f64 , f64 ) ,
@@ -169,47 +211,86 @@ impl MaybeOverride<(f64, f64)> for SpecialCase {
169211 _ulp : & mut u32 ,
170212 ctx : & CheckCtx ,
171213 ) -> Option < TestResult > {
172- maybe_skip_min_max_nan ( input, expected, ctx)
214+ maybe_skip_binop_nan ( input, expected, ctx)
173215 }
174216}
175217
176218/// Musl propagates NaNs if one is provided as the input, but we return the other input.
177219// 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 > (
179221 input : ( F1 , F1 ) ,
180222 expected : F2 ,
181223 ctx : & CheckCtx ,
182224) -> 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+ }
190243 }
191244}
192245
193246impl MaybeOverride < ( i32 , f32 ) > for SpecialCase {
194247 fn check_float < F : Float > (
195248 input : ( i32 , f32 ) ,
196- _actual : F ,
197- _expected : F ,
249+ actual : F ,
250+ expected : F ,
198251 ulp : & mut u32 ,
199252 ctx : & CheckCtx ,
200253 ) -> 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+ }
202269 }
203270}
204271impl MaybeOverride < ( i32 , f64 ) > for SpecialCase {
205272 fn check_float < F : Float > (
206273 input : ( i32 , f64 ) ,
207- _actual : F ,
208- _expected : F ,
274+ actual : F ,
275+ expected : F ,
209276 ulp : & mut u32 ,
210277 ctx : & CheckCtx ,
211278 ) -> 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+ }
213294 }
214295}
215296
0 commit comments