@@ -331,6 +331,17 @@ pub unsafe fn _mm_cmpord_ss(a: f32x4, b: f32x4) -> f32x4 {
331
331
cmpss ( a, b, 7 )
332
332
}
333
333
334
+ /// Check if the lowest `f32` of both inputs are unordered. The lowest 32 bits
335
+ /// of the result will be `0xffffffff` if any of `a.extract(0)` or
336
+ /// `b.extract(0)` is a NaN, or `0` otherwise. The upper 96 bits of the result
337
+ /// are the upper 96 bits of `a`.
338
+ #[ inline( always) ]
339
+ #[ target_feature = "+sse" ]
340
+ #[ cfg_attr( test, assert_instr( cmpunordss) ) ]
341
+ pub unsafe fn _mm_cmpunord_ss ( a : f32x4 , b : f32x4 ) -> f32x4 {
342
+ cmpss ( a, b, 3 )
343
+ }
344
+
334
345
/// Construct a `f32x4` with the lowest element set to `a` and the rest set to
335
346
/// zero.
336
347
#[ inline( always) ]
@@ -1535,9 +1546,6 @@ mod tests {
1535
1546
1536
1547
#[ simd_test = "sse" ]
1537
1548
unsafe fn _mm_cmpord_ss ( ) {
1538
- // TODO: This test is exactly the same as for _mm_cmplt_ss, but there
1539
- // must be a difference. It may have to do with behavior in the presence
1540
- // of NaNs (signaling or quiet). If so, we should add tests for those.
1541
1549
use std:: mem:: transmute;
1542
1550
use std:: f32:: NAN ;
1543
1551
@@ -1563,6 +1571,33 @@ mod tests {
1563
1571
assert_eq ! ( rd, ed) ;
1564
1572
}
1565
1573
1574
+ #[ simd_test = "sse" ]
1575
+ unsafe fn _mm_cmpunord_ss ( ) {
1576
+ use std:: mem:: transmute;
1577
+ use std:: f32:: NAN ;
1578
+
1579
+ let a = f32x4:: new ( 1.0 , 2.0 , 3.0 , 4.0 ) ;
1580
+ let b = f32x4:: new ( 0.0 , 5.0 , 6.0 , 7.0 ) ;
1581
+ let c = f32x4:: new ( NAN , 5.0 , 6.0 , 7.0 ) ;
1582
+ let d = f32x4:: new ( 2.0 , 5.0 , 6.0 , 7.0 ) ;
1583
+
1584
+ let b1 = 0u32 ; // a.extract(0) unord b.extract(0)
1585
+ let c1 = !0u32 ; // a.extract(0) unord c.extract(0)
1586
+ let d1 = 0u32 ; // a.extract(0) unord d.extract(0)
1587
+
1588
+ let rb: u32x4 = transmute ( sse:: _mm_cmpunord_ss ( a, b) ) ;
1589
+ let eb: u32x4 = transmute ( f32x4:: new ( transmute ( b1) , 2.0 , 3.0 , 4.0 ) ) ;
1590
+ assert_eq ! ( rb, eb) ;
1591
+
1592
+ let rc: u32x4 = transmute ( sse:: _mm_cmpunord_ss ( a, c) ) ;
1593
+ let ec: u32x4 = transmute ( f32x4:: new ( transmute ( c1) , 2.0 , 3.0 , 4.0 ) ) ;
1594
+ assert_eq ! ( rc, ec) ;
1595
+
1596
+ let rd: u32x4 = transmute ( sse:: _mm_cmpunord_ss ( a, d) ) ;
1597
+ let ed: u32x4 = transmute ( f32x4:: new ( transmute ( d1) , 2.0 , 3.0 , 4.0 ) ) ;
1598
+ assert_eq ! ( rd, ed) ;
1599
+ }
1600
+
1566
1601
#[ simd_test = "sse" ]
1567
1602
unsafe fn _mm_set_ss ( ) {
1568
1603
let r = sse:: _mm_set_ss ( black_box ( 4.25 ) ) ;
0 commit comments