@@ -329,6 +329,17 @@ pub unsafe fn _mm_cmpord_ss(a: f32x4, b: f32x4) -> f32x4 {
329
329
cmpss ( a, b, 7 )
330
330
}
331
331
332
+ /// Check if the lowest `f32` of both inputs are unordered. The lowest 32 bits
333
+ /// of the result will be `0xffffffff` if any of `a.extract(0)` or
334
+ /// `b.extract(0)` is a NaN, or `0` otherwise. The upper 96 bits of the result
335
+ /// are the upper 96 bits of `a`.
336
+ #[ inline( always) ]
337
+ #[ target_feature = "+sse" ]
338
+ #[ cfg_attr( test, assert_instr( cmpunordss) ) ]
339
+ pub unsafe fn _mm_cmpunord_ss ( a : f32x4 , b : f32x4 ) -> f32x4 {
340
+ cmpss ( a, b, 3 )
341
+ }
342
+
332
343
/// Construct a `f32x4` with the lowest element set to `a` and the rest set to
333
344
/// zero.
334
345
#[ inline( always) ]
@@ -1338,9 +1349,6 @@ mod tests {
1338
1349
1339
1350
#[ simd_test = "sse" ]
1340
1351
unsafe fn _mm_cmpord_ss ( ) {
1341
- // TODO: This test is exactly the same as for _mm_cmplt_ss, but there
1342
- // must be a difference. It may have to do with behavior in the presence
1343
- // of NaNs (signaling or quiet). If so, we should add tests for those.
1344
1352
use std:: mem:: transmute;
1345
1353
use std:: f32:: NAN ;
1346
1354
@@ -1366,6 +1374,33 @@ mod tests {
1366
1374
assert_eq ! ( rd, ed) ;
1367
1375
}
1368
1376
1377
+ #[ simd_test = "sse" ]
1378
+ unsafe fn _mm_cmpunord_ss ( ) {
1379
+ use std:: mem:: transmute;
1380
+ use std:: f32:: NAN ;
1381
+
1382
+ let a = f32x4:: new ( 1.0 , 2.0 , 3.0 , 4.0 ) ;
1383
+ let b = f32x4:: new ( 0.0 , 5.0 , 6.0 , 7.0 ) ;
1384
+ let c = f32x4:: new ( NAN , 5.0 , 6.0 , 7.0 ) ;
1385
+ let d = f32x4:: new ( 2.0 , 5.0 , 6.0 , 7.0 ) ;
1386
+
1387
+ let b1 = 0u32 ; // a.extract(0) unord b.extract(0)
1388
+ let c1 = !0u32 ; // a.extract(0) unord c.extract(0)
1389
+ let d1 = 0u32 ; // a.extract(0) unord d.extract(0)
1390
+
1391
+ let rb: u32x4 = transmute ( sse:: _mm_cmpunord_ss ( a, b) ) ;
1392
+ let eb: u32x4 = transmute ( f32x4:: new ( transmute ( b1) , 2.0 , 3.0 , 4.0 ) ) ;
1393
+ assert_eq ! ( rb, eb) ;
1394
+
1395
+ let rc: u32x4 = transmute ( sse:: _mm_cmpunord_ss ( a, c) ) ;
1396
+ let ec: u32x4 = transmute ( f32x4:: new ( transmute ( c1) , 2.0 , 3.0 , 4.0 ) ) ;
1397
+ assert_eq ! ( rc, ec) ;
1398
+
1399
+ let rd: u32x4 = transmute ( sse:: _mm_cmpunord_ss ( a, d) ) ;
1400
+ let ed: u32x4 = transmute ( f32x4:: new ( transmute ( d1) , 2.0 , 3.0 , 4.0 ) ) ;
1401
+ assert_eq ! ( rd, ed) ;
1402
+ }
1403
+
1369
1404
#[ simd_test = "sse" ]
1370
1405
unsafe fn _mm_set_ss ( ) {
1371
1406
let r = sse:: _mm_set_ss ( black_box ( 4.25 ) ) ;
0 commit comments