@@ -25,6 +25,14 @@ use super::{
25
25
} ;
26
26
use crate :: fluent_generated as fluent;
27
27
28
+ #[ derive( Copy , Clone ) ]
29
+ pub ( crate ) enum MinMax {
30
+ Minimum ,
31
+ Minnum ,
32
+ Maximum ,
33
+ Maxnum ,
34
+ }
35
+
28
36
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
29
37
pub ( crate ) fn alloc_type_name < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> ( AllocId , u64 ) {
30
38
let path = crate :: util:: type_name ( tcx, ty) ;
@@ -486,25 +494,33 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
486
494
self . write_scalar ( Scalar :: from_target_usize ( align. bytes ( ) , self ) , dest) ?;
487
495
}
488
496
489
- sym:: minnumf16 => self . float_min_intrinsic :: < Half > ( args, dest) ?,
490
- sym:: minnumf32 => self . float_min_intrinsic :: < Single > ( args, dest) ?,
491
- sym:: minnumf64 => self . float_min_intrinsic :: < Double > ( args, dest) ?,
492
- sym:: minnumf128 => self . float_min_intrinsic :: < Quad > ( args, dest) ?,
497
+ sym:: minnumf16 => self . float_minmax_intrinsic :: < Half > ( args, MinMax :: Minnum , dest) ?,
498
+ sym:: minnumf32 => self . float_minmax_intrinsic :: < Single > ( args, MinMax :: Minnum , dest) ?,
499
+ sym:: minnumf64 => self . float_minmax_intrinsic :: < Double > ( args, MinMax :: Minnum , dest) ?,
500
+ sym:: minnumf128 => self . float_minmax_intrinsic :: < Quad > ( args, MinMax :: Minnum , dest) ?,
493
501
494
- sym:: minimumf16 => self . float_minimum_intrinsic :: < Half > ( args, dest) ?,
495
- sym:: minimumf32 => self . float_minimum_intrinsic :: < Single > ( args, dest) ?,
496
- sym:: minimumf64 => self . float_minimum_intrinsic :: < Double > ( args, dest) ?,
497
- sym:: minimumf128 => self . float_minimum_intrinsic :: < Quad > ( args, dest) ?,
502
+ sym:: minimumf16 => self . float_minmax_intrinsic :: < Half > ( args, MinMax :: Minimum , dest) ?,
503
+ sym:: minimumf32 => {
504
+ self . float_minmax_intrinsic :: < Single > ( args, MinMax :: Minimum , dest) ?
505
+ }
506
+ sym:: minimumf64 => {
507
+ self . float_minmax_intrinsic :: < Double > ( args, MinMax :: Minimum , dest) ?
508
+ }
509
+ sym:: minimumf128 => self . float_minmax_intrinsic :: < Quad > ( args, MinMax :: Minimum , dest) ?,
498
510
499
- sym:: maxnumf16 => self . float_max_intrinsic :: < Half > ( args, dest) ?,
500
- sym:: maxnumf32 => self . float_max_intrinsic :: < Single > ( args, dest) ?,
501
- sym:: maxnumf64 => self . float_max_intrinsic :: < Double > ( args, dest) ?,
502
- sym:: maxnumf128 => self . float_max_intrinsic :: < Quad > ( args, dest) ?,
511
+ sym:: maxnumf16 => self . float_minmax_intrinsic :: < Half > ( args, MinMax :: Maxnum , dest) ?,
512
+ sym:: maxnumf32 => self . float_minmax_intrinsic :: < Single > ( args, MinMax :: Maxnum , dest) ?,
513
+ sym:: maxnumf64 => self . float_minmax_intrinsic :: < Double > ( args, MinMax :: Maxnum , dest) ?,
514
+ sym:: maxnumf128 => self . float_minmax_intrinsic :: < Quad > ( args, MinMax :: Maxnum , dest) ?,
503
515
504
- sym:: maximumf16 => self . float_maximum_intrinsic :: < Half > ( args, dest) ?,
505
- sym:: maximumf32 => self . float_maximum_intrinsic :: < Single > ( args, dest) ?,
506
- sym:: maximumf64 => self . float_maximum_intrinsic :: < Double > ( args, dest) ?,
507
- sym:: maximumf128 => self . float_maximum_intrinsic :: < Quad > ( args, dest) ?,
516
+ sym:: maximumf16 => self . float_minmax_intrinsic :: < Half > ( args, MinMax :: Maximum , dest) ?,
517
+ sym:: maximumf32 => {
518
+ self . float_minmax_intrinsic :: < Single > ( args, MinMax :: Maximum , dest) ?
519
+ }
520
+ sym:: maximumf64 => {
521
+ self . float_minmax_intrinsic :: < Double > ( args, MinMax :: Maximum , dest) ?
522
+ }
523
+ sym:: maximumf128 => self . float_minmax_intrinsic :: < Quad > ( args, MinMax :: Maximum , dest) ?,
508
524
509
525
sym:: copysignf16 => self . float_copysign_intrinsic :: < Half > ( args, dest) ?,
510
526
sym:: copysignf32 => self . float_copysign_intrinsic :: < Single > ( args, dest) ?,
@@ -901,76 +917,45 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
901
917
interp_ok ( Scalar :: from_bool ( lhs_bytes == rhs_bytes) )
902
918
}
903
919
904
- fn float_min_intrinsic < F > (
905
- & mut self ,
906
- args : & [ OpTy < ' tcx , M :: Provenance > ] ,
907
- dest : & PlaceTy < ' tcx , M :: Provenance > ,
908
- ) -> InterpResult < ' tcx , ( ) >
909
- where
910
- F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
911
- {
912
- let a: F = self . read_scalar ( & args[ 0 ] ) ?. to_float ( ) ?;
913
- let b: F = self . read_scalar ( & args[ 1 ] ) ?. to_float ( ) ?;
914
- let res = if a == b {
915
- // They are definitely not NaN (those are never equal), but they could be `+0` and `-0`.
916
- // Let the machine decide which one to return.
917
- M :: equal_float_min_max ( self , a, b)
918
- } else {
919
- self . adjust_nan ( a. min ( b) , & [ a, b] )
920
- } ;
921
- self . write_scalar ( res, dest) ?;
922
- interp_ok ( ( ) )
923
- }
924
-
925
- fn float_max_intrinsic < F > (
926
- & mut self ,
927
- args : & [ OpTy < ' tcx , M :: Provenance > ] ,
928
- dest : & PlaceTy < ' tcx , M :: Provenance > ,
929
- ) -> InterpResult < ' tcx , ( ) >
920
+ fn float_minmax < F > (
921
+ & self ,
922
+ a : Scalar < M :: Provenance > ,
923
+ b : Scalar < M :: Provenance > ,
924
+ op : MinMax ,
925
+ ) -> InterpResult < ' tcx , F >
930
926
where
931
- F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
927
+ F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > ,
932
928
{
933
- let a: F = self . read_scalar ( & args [ 0 ] ) ? . to_float ( ) ?;
934
- let b: F = self . read_scalar ( & args [ 1 ] ) ? . to_float ( ) ?;
935
- let res = if a == b {
929
+ let a: F = a . to_float ( ) ?;
930
+ let b: F = b . to_float ( ) ?;
931
+ let res = if matches ! ( op , MinMax :: Minnum | MinMax :: Maxnum ) && a == b {
936
932
// They are definitely not NaN (those are never equal), but they could be `+0` and `-0`.
937
933
// Let the machine decide which one to return.
938
934
M :: equal_float_min_max ( self , a, b)
939
935
} else {
940
- self . adjust_nan ( a. max ( b) , & [ a, b] )
936
+ let result = match op {
937
+ MinMax :: Minimum => a. minimum ( b) ,
938
+ MinMax :: Minnum => a. min ( b) ,
939
+ MinMax :: Maximum => a. maximum ( b) ,
940
+ MinMax :: Maxnum => a. max ( b) ,
941
+ } ;
942
+ self . adjust_nan ( result, & [ a, b] )
941
943
} ;
942
- self . write_scalar ( res, dest) ?;
943
- interp_ok ( ( ) )
944
- }
945
944
946
- fn float_minimum_intrinsic < F > (
947
- & mut self ,
948
- args : & [ OpTy < ' tcx , M :: Provenance > ] ,
949
- dest : & PlaceTy < ' tcx , M :: Provenance > ,
950
- ) -> InterpResult < ' tcx , ( ) >
951
- where
952
- F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
953
- {
954
- let a: F = self . read_scalar ( & args[ 0 ] ) ?. to_float ( ) ?;
955
- let b: F = self . read_scalar ( & args[ 1 ] ) ?. to_float ( ) ?;
956
- let res = a. minimum ( b) ;
957
- let res = self . adjust_nan ( res, & [ a, b] ) ;
958
- self . write_scalar ( res, dest) ?;
959
- interp_ok ( ( ) )
945
+ interp_ok ( res)
960
946
}
961
947
962
- fn float_maximum_intrinsic < F > (
948
+ fn float_minmax_intrinsic < F > (
963
949
& mut self ,
964
950
args : & [ OpTy < ' tcx , M :: Provenance > ] ,
951
+ op : MinMax ,
965
952
dest : & PlaceTy < ' tcx , M :: Provenance > ,
966
953
) -> InterpResult < ' tcx , ( ) >
967
954
where
968
955
F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
969
956
{
970
- let a: F = self . read_scalar ( & args[ 0 ] ) ?. to_float ( ) ?;
971
- let b: F = self . read_scalar ( & args[ 1 ] ) ?. to_float ( ) ?;
972
- let res = a. maximum ( b) ;
973
- let res = self . adjust_nan ( res, & [ a, b] ) ;
957
+ let res =
958
+ self . float_minmax :: < F > ( self . read_scalar ( & args[ 0 ] ) ?, self . read_scalar ( & args[ 1 ] ) ?, op) ?;
974
959
self . write_scalar ( res, dest) ?;
975
960
interp_ok ( ( ) )
976
961
}
0 commit comments