@@ -77,9 +77,12 @@ pub fn fmaxf128(x: f128, y: f128) -> f128 {
7777#[ cfg( test) ]
7878mod tests {
7979 use super :: * ;
80+ use crate :: support:: hex_float:: Hexi ;
8081 use crate :: support:: { Float , Hexf } ;
8182
8283 fn fmin_spec_test < F : Float > ( f : impl Fn ( F , F ) -> F ) {
84+ // Note that (YaN, sNaN) and (sNaN, YaN) results differ from 754-2008. This is intentional,
85+ // see comments in the generic implementations.
8386 let cases = [
8487 ( F :: ZERO , F :: ZERO , F :: ZERO ) ,
8588 ( F :: ZERO , F :: ONE , F :: ZERO ) ,
@@ -88,13 +91,17 @@ mod tests {
8891 ( F :: ZERO , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
8992 ( F :: ZERO , F :: NAN , F :: ZERO ) ,
9093 ( F :: ZERO , F :: NEG_NAN , F :: ZERO ) ,
94+ ( F :: ZERO , F :: SNAN , F :: ZERO ) ,
95+ ( F :: ZERO , F :: NEG_SNAN , F :: ZERO ) ,
9196 ( F :: NEG_ZERO , F :: NEG_ZERO , F :: NEG_ZERO ) ,
9297 ( F :: NEG_ZERO , F :: ONE , F :: NEG_ZERO ) ,
9398 ( F :: NEG_ZERO , F :: NEG_ONE , F :: NEG_ONE ) ,
9499 ( F :: NEG_ZERO , F :: INFINITY , F :: NEG_ZERO ) ,
95100 ( F :: NEG_ZERO , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
96101 ( F :: NEG_ZERO , F :: NAN , F :: NEG_ZERO ) ,
97102 ( F :: NEG_ZERO , F :: NEG_NAN , F :: NEG_ZERO ) ,
103+ ( F :: NEG_ZERO , F :: SNAN , F :: NEG_ZERO ) ,
104+ ( F :: NEG_ZERO , F :: NEG_SNAN , F :: NEG_ZERO ) ,
98105 ( F :: ONE , F :: ZERO , F :: ZERO ) ,
99106 ( F :: ONE , F :: NEG_ZERO , F :: NEG_ZERO ) ,
100107 ( F :: ONE , F :: ONE , F :: ONE ) ,
@@ -103,6 +110,8 @@ mod tests {
103110 ( F :: ONE , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
104111 ( F :: ONE , F :: NAN , F :: ONE ) ,
105112 ( F :: ONE , F :: NEG_NAN , F :: ONE ) ,
113+ ( F :: ONE , F :: SNAN , F :: ONE ) ,
114+ ( F :: ONE , F :: NEG_SNAN , F :: ONE ) ,
106115 ( F :: NEG_ONE , F :: ZERO , F :: NEG_ONE ) ,
107116 ( F :: NEG_ONE , F :: NEG_ZERO , F :: NEG_ONE ) ,
108117 ( F :: NEG_ONE , F :: ONE , F :: NEG_ONE ) ,
@@ -111,6 +120,8 @@ mod tests {
111120 ( F :: NEG_ONE , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
112121 ( F :: NEG_ONE , F :: NAN , F :: NEG_ONE ) ,
113122 ( F :: NEG_ONE , F :: NEG_NAN , F :: NEG_ONE ) ,
123+ ( F :: NEG_ONE , F :: SNAN , F :: NEG_ONE ) ,
124+ ( F :: NEG_ONE , F :: NEG_SNAN , F :: NEG_ONE ) ,
114125 ( F :: INFINITY , F :: ZERO , F :: ZERO ) ,
115126 ( F :: INFINITY , F :: NEG_ZERO , F :: NEG_ZERO ) ,
116127 ( F :: INFINITY , F :: ONE , F :: ONE ) ,
@@ -119,6 +130,8 @@ mod tests {
119130 ( F :: INFINITY , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
120131 ( F :: INFINITY , F :: NAN , F :: INFINITY ) ,
121132 ( F :: INFINITY , F :: NEG_NAN , F :: INFINITY ) ,
133+ ( F :: INFINITY , F :: SNAN , F :: INFINITY ) ,
134+ ( F :: INFINITY , F :: NEG_SNAN , F :: INFINITY ) ,
122135 ( F :: NEG_INFINITY , F :: ZERO , F :: NEG_INFINITY ) ,
123136 ( F :: NEG_INFINITY , F :: NEG_ZERO , F :: NEG_INFINITY ) ,
124137 ( F :: NEG_INFINITY , F :: ONE , F :: NEG_INFINITY ) ,
@@ -127,6 +140,8 @@ mod tests {
127140 ( F :: NEG_INFINITY , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
128141 ( F :: NEG_INFINITY , F :: NAN , F :: NEG_INFINITY ) ,
129142 ( F :: NEG_INFINITY , F :: NEG_NAN , F :: NEG_INFINITY ) ,
143+ ( F :: NEG_INFINITY , F :: SNAN , F :: NEG_INFINITY ) ,
144+ ( F :: NEG_INFINITY , F :: NEG_SNAN , F :: NEG_INFINITY ) ,
130145 ( F :: NAN , F :: ZERO , F :: ZERO ) ,
131146 ( F :: NAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
132147 ( F :: NAN , F :: ONE , F :: ONE ) ,
@@ -140,19 +155,48 @@ mod tests {
140155 ( F :: NEG_NAN , F :: NEG_ONE , F :: NEG_ONE ) ,
141156 ( F :: NEG_NAN , F :: INFINITY , F :: INFINITY ) ,
142157 ( F :: NEG_NAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
158+ ( F :: SNAN , F :: ZERO , F :: ZERO ) ,
159+ ( F :: SNAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
160+ ( F :: SNAN , F :: ONE , F :: ONE ) ,
161+ ( F :: SNAN , F :: NEG_ONE , F :: NEG_ONE ) ,
162+ ( F :: SNAN , F :: INFINITY , F :: INFINITY ) ,
163+ ( F :: SNAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
164+ ( F :: NEG_SNAN , F :: ZERO , F :: ZERO ) ,
165+ ( F :: NEG_SNAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
166+ ( F :: NEG_SNAN , F :: ONE , F :: ONE ) ,
167+ ( F :: NEG_SNAN , F :: NEG_ONE , F :: NEG_ONE ) ,
168+ ( F :: NEG_SNAN , F :: INFINITY , F :: INFINITY ) ,
169+ ( F :: NEG_SNAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
143170 ] ;
144171
145172 for ( x, y, res) in cases {
146173 let val = f ( x, y) ;
147174 assert_biteq ! ( val, res, "fmin({}, {})" , Hexf ( x) , Hexf ( y) ) ;
148175 }
149176
150- // Ordering between zeros and NaNs does not matter
177+ // Ordering between zeros does not matter
151178 assert_eq ! ( f( F :: ZERO , F :: NEG_ZERO ) , F :: ZERO ) ;
152179 assert_eq ! ( f( F :: NEG_ZERO , F :: ZERO ) , F :: ZERO ) ;
153- assert ! ( f( F :: NAN , F :: NEG_NAN ) . is_nan( ) ) ;
154- assert ! ( f( F :: NEG_NAN , F :: NAN ) . is_nan( ) ) ;
155- assert ! ( f( F :: NEG_NAN , F :: NEG_NAN ) . is_nan( ) ) ;
180+
181+ // Selection between NaNs does not matter, it just must be quiet
182+ assert ! ( f( F :: NAN , F :: NEG_NAN ) . is_qnan( ) ) ;
183+ assert ! ( f( F :: NEG_NAN , F :: NAN ) . is_qnan( ) ) ;
184+ assert ! ( f( F :: NEG_NAN , F :: NEG_NAN ) . is_qnan( ) ) ;
185+
186+ // These operations should technically return a qnan, but LLVM optimizes out our
187+ // `* 1.0` canonicalization.
188+ assert ! ( f( F :: NAN , F :: NEG_SNAN ) . is_nan( ) ) ;
189+ assert ! ( f( F :: NAN , F :: SNAN ) . is_nan( ) ) ;
190+ assert ! ( f( F :: NEG_NAN , F :: NEG_SNAN ) . is_nan( ) ) ;
191+ assert ! ( f( F :: NEG_NAN , F :: SNAN ) . is_nan( ) ) ;
192+ assert ! ( f( F :: NEG_SNAN , F :: NAN ) . is_nan( ) ) ;
193+ assert ! ( f( F :: NEG_SNAN , F :: NEG_NAN ) . is_nan( ) ) ;
194+ assert ! ( f( F :: NEG_SNAN , F :: NEG_SNAN ) . is_nan( ) ) ;
195+ assert ! ( f( F :: NEG_SNAN , F :: SNAN ) . is_nan( ) ) ;
196+ assert ! ( f( F :: SNAN , F :: NAN ) . is_nan( ) ) ;
197+ assert ! ( f( F :: SNAN , F :: NAN ) . is_nan( ) ) ;
198+ assert ! ( f( F :: SNAN , F :: NEG_NAN ) . is_nan( ) ) ;
199+ assert ! ( f( F :: SNAN , F :: NEG_SNAN ) . is_nan( ) ) ;
156200 }
157201
158202 #[ test]
@@ -186,13 +230,17 @@ mod tests {
186230 ( F :: ZERO , F :: NEG_INFINITY , F :: ZERO ) ,
187231 ( F :: ZERO , F :: NAN , F :: ZERO ) ,
188232 ( F :: ZERO , F :: NEG_NAN , F :: ZERO ) ,
233+ ( F :: ZERO , F :: SNAN , F :: ZERO ) ,
234+ ( F :: ZERO , F :: NEG_SNAN , F :: ZERO ) ,
189235 ( F :: NEG_ZERO , F :: NEG_ZERO , F :: NEG_ZERO ) ,
190236 ( F :: NEG_ZERO , F :: ONE , F :: ONE ) ,
191237 ( F :: NEG_ZERO , F :: NEG_ONE , F :: NEG_ZERO ) ,
192238 ( F :: NEG_ZERO , F :: INFINITY , F :: INFINITY ) ,
193239 ( F :: NEG_ZERO , F :: NEG_INFINITY , F :: NEG_ZERO ) ,
194240 ( F :: NEG_ZERO , F :: NAN , F :: NEG_ZERO ) ,
195241 ( F :: NEG_ZERO , F :: NEG_NAN , F :: NEG_ZERO ) ,
242+ ( F :: NEG_ZERO , F :: SNAN , F :: NEG_ZERO ) ,
243+ ( F :: NEG_ZERO , F :: NEG_SNAN , F :: NEG_ZERO ) ,
196244 ( F :: ONE , F :: ZERO , F :: ONE ) ,
197245 ( F :: ONE , F :: NEG_ZERO , F :: ONE ) ,
198246 ( F :: ONE , F :: ONE , F :: ONE ) ,
@@ -201,6 +249,8 @@ mod tests {
201249 ( F :: ONE , F :: NEG_INFINITY , F :: ONE ) ,
202250 ( F :: ONE , F :: NAN , F :: ONE ) ,
203251 ( F :: ONE , F :: NEG_NAN , F :: ONE ) ,
252+ ( F :: ONE , F :: SNAN , F :: ONE ) ,
253+ ( F :: ONE , F :: NEG_SNAN , F :: ONE ) ,
204254 ( F :: NEG_ONE , F :: ZERO , F :: ZERO ) ,
205255 ( F :: NEG_ONE , F :: NEG_ZERO , F :: NEG_ZERO ) ,
206256 ( F :: NEG_ONE , F :: ONE , F :: ONE ) ,
@@ -209,6 +259,8 @@ mod tests {
209259 ( F :: NEG_ONE , F :: NEG_INFINITY , F :: NEG_ONE ) ,
210260 ( F :: NEG_ONE , F :: NAN , F :: NEG_ONE ) ,
211261 ( F :: NEG_ONE , F :: NEG_NAN , F :: NEG_ONE ) ,
262+ ( F :: NEG_ONE , F :: SNAN , F :: NEG_ONE ) ,
263+ ( F :: NEG_ONE , F :: NEG_SNAN , F :: NEG_ONE ) ,
212264 ( F :: INFINITY , F :: ZERO , F :: INFINITY ) ,
213265 ( F :: INFINITY , F :: NEG_ZERO , F :: INFINITY ) ,
214266 ( F :: INFINITY , F :: ONE , F :: INFINITY ) ,
@@ -217,6 +269,8 @@ mod tests {
217269 ( F :: INFINITY , F :: NEG_INFINITY , F :: INFINITY ) ,
218270 ( F :: INFINITY , F :: NAN , F :: INFINITY ) ,
219271 ( F :: INFINITY , F :: NEG_NAN , F :: INFINITY ) ,
272+ ( F :: INFINITY , F :: SNAN , F :: INFINITY ) ,
273+ ( F :: INFINITY , F :: NEG_SNAN , F :: INFINITY ) ,
220274 ( F :: NEG_INFINITY , F :: ZERO , F :: ZERO ) ,
221275 ( F :: NEG_INFINITY , F :: NEG_ZERO , F :: NEG_ZERO ) ,
222276 ( F :: NEG_INFINITY , F :: ONE , F :: ONE ) ,
@@ -225,6 +279,8 @@ mod tests {
225279 ( F :: NEG_INFINITY , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
226280 ( F :: NEG_INFINITY , F :: NAN , F :: NEG_INFINITY ) ,
227281 ( F :: NEG_INFINITY , F :: NEG_NAN , F :: NEG_INFINITY ) ,
282+ ( F :: NEG_INFINITY , F :: SNAN , F :: NEG_INFINITY ) ,
283+ ( F :: NEG_INFINITY , F :: NEG_SNAN , F :: NEG_INFINITY ) ,
228284 ( F :: NAN , F :: ZERO , F :: ZERO ) ,
229285 ( F :: NAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
230286 ( F :: NAN , F :: ONE , F :: ONE ) ,
@@ -238,19 +294,54 @@ mod tests {
238294 ( F :: NEG_NAN , F :: NEG_ONE , F :: NEG_ONE ) ,
239295 ( F :: NEG_NAN , F :: INFINITY , F :: INFINITY ) ,
240296 ( F :: NEG_NAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
297+ ( F :: SNAN , F :: ZERO , F :: ZERO ) ,
298+ ( F :: SNAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
299+ ( F :: SNAN , F :: ONE , F :: ONE ) ,
300+ ( F :: SNAN , F :: NEG_ONE , F :: NEG_ONE ) ,
301+ ( F :: SNAN , F :: INFINITY , F :: INFINITY ) ,
302+ ( F :: SNAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
303+ ( F :: NEG_SNAN , F :: ZERO , F :: ZERO ) ,
304+ ( F :: NEG_SNAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
305+ ( F :: NEG_SNAN , F :: ONE , F :: ONE ) ,
306+ ( F :: NEG_SNAN , F :: NEG_ONE , F :: NEG_ONE ) ,
307+ ( F :: NEG_SNAN , F :: INFINITY , F :: INFINITY ) ,
308+ ( F :: NEG_SNAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
241309 ] ;
242310
243311 for ( x, y, res) in cases {
244312 let val = f ( x, y) ;
245- assert_biteq ! ( val, res, "fmax({}, {})" , Hexf ( x) , Hexf ( y) ) ;
313+ assert_biteq ! (
314+ val,
315+ res,
316+ "fmax({}, {}) ({}, {})" ,
317+ Hexf ( x) ,
318+ Hexf ( y) ,
319+ Hexi ( x. to_bits( ) ) ,
320+ Hexi ( y. to_bits( ) ) ,
321+ ) ;
246322 }
247323
248- // Ordering between zeros and NaNs does not matter
324+ // Ordering between zeros
249325 assert_eq ! ( f( F :: ZERO , F :: NEG_ZERO ) , F :: ZERO ) ;
250326 assert_eq ! ( f( F :: NEG_ZERO , F :: ZERO ) , F :: ZERO ) ;
251- assert ! ( f( F :: NAN , F :: NEG_NAN ) . is_nan( ) ) ;
252- assert ! ( f( F :: NEG_NAN , F :: NAN ) . is_nan( ) ) ;
253- assert ! ( f( F :: NEG_NAN , F :: NEG_NAN ) . is_nan( ) ) ;
327+
328+ // Selection between NaNs does not matter, it just must be quiet
329+ assert ! ( f( F :: NAN , F :: NEG_NAN ) . is_qnan( ) ) ;
330+ assert ! ( f( F :: NEG_NAN , F :: NAN ) . is_qnan( ) ) ;
331+ assert ! ( f( F :: NEG_NAN , F :: NEG_NAN ) . is_qnan( ) ) ;
332+
333+ assert ! ( f( F :: NAN , F :: NEG_SNAN ) . is_nan( ) ) ;
334+ assert ! ( f( F :: NAN , F :: SNAN ) . is_nan( ) ) ;
335+ assert ! ( f( F :: NEG_NAN , F :: NEG_SNAN ) . is_nan( ) ) ;
336+ assert ! ( f( F :: NEG_NAN , F :: SNAN ) . is_nan( ) ) ;
337+ assert ! ( f( F :: NEG_SNAN , F :: NAN ) . is_nan( ) ) ;
338+ assert ! ( f( F :: NEG_SNAN , F :: NEG_NAN ) . is_nan( ) ) ;
339+ assert ! ( f( F :: NEG_SNAN , F :: NEG_SNAN ) . is_nan( ) ) ;
340+ assert ! ( f( F :: NEG_SNAN , F :: SNAN ) . is_nan( ) ) ;
341+ assert ! ( f( F :: SNAN , F :: NAN ) . is_nan( ) ) ;
342+ assert ! ( f( F :: SNAN , F :: NEG_NAN ) . is_nan( ) ) ;
343+ assert ! ( f( F :: SNAN , F :: NEG_SNAN ) . is_nan( ) ) ;
344+ assert ! ( f( F :: SNAN , F :: SNAN ) . is_nan( ) ) ;
254345 }
255346
256347 #[ test]
0 commit comments