@@ -1505,6 +1505,34 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
1505
1505
} )
1506
1506
}
1507
1507
1508
+ fn vector_extremum ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > , direction : ExtremumOperation ) -> RValue < ' gcc > {
1509
+ let vector_type = a. get_type ( ) ;
1510
+
1511
+ // mask out the NaNs in b and replace them with the corresponding lane in a, so when a and
1512
+ // b get compared & spliced together, we get the numeric values instead of NaNs.
1513
+ let b_nan_mask = self . context . new_comparison ( None , ComparisonOp :: NotEquals , b, b) ;
1514
+ let mask_type = b_nan_mask. get_type ( ) ;
1515
+ let b_nan_mask_inverted = self . context . new_unary_op ( None , UnaryOp :: BitwiseNegate , mask_type, b_nan_mask) ;
1516
+ let a_cast = self . context . new_bitcast ( None , a, mask_type) ;
1517
+ let b_cast = self . context . new_bitcast ( None , b, mask_type) ;
1518
+ let res = ( b_nan_mask & a_cast) | ( b_nan_mask_inverted & b_cast) ;
1519
+ let b = self . context . new_bitcast ( None , res, vector_type) ;
1520
+
1521
+ // now do the actual comparison
1522
+ let comparison_op = match direction {
1523
+ ExtremumOperation :: Min => ComparisonOp :: LessThan ,
1524
+ ExtremumOperation :: Max => ComparisonOp :: GreaterThan ,
1525
+ } ;
1526
+ let cmp = self . context . new_comparison ( None , comparison_op, a, b) ;
1527
+ let cmp_inverted = self . context . new_unary_op ( None , UnaryOp :: BitwiseNegate , cmp. get_type ( ) , cmp) ;
1528
+ let res = ( cmp & a_cast) | ( cmp_inverted & res) ;
1529
+ self . context . new_bitcast ( None , res, vector_type)
1530
+ }
1531
+
1532
+ pub fn vector_fmin ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
1533
+ self . vector_extremum ( a, b, ExtremumOperation :: Min )
1534
+ }
1535
+
1508
1536
#[ cfg( feature="master" ) ]
1509
1537
pub fn vector_reduce_fmin ( & mut self , src : RValue < ' gcc > ) -> RValue < ' gcc > {
1510
1538
let vector_type = src. get_type ( ) . unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
@@ -1525,6 +1553,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
1525
1553
unimplemented ! ( ) ;
1526
1554
}
1527
1555
1556
+ pub fn vector_fmax ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
1557
+ self . vector_extremum ( a, b, ExtremumOperation :: Max )
1558
+ }
1559
+
1528
1560
#[ cfg( feature="master" ) ]
1529
1561
pub fn vector_reduce_fmax ( & mut self , src : RValue < ' gcc > ) -> RValue < ' gcc > {
1530
1562
let vector_type = src. get_type ( ) . unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
0 commit comments