@@ -25,6 +25,14 @@ use super::{
2525} ;
2626use crate :: fluent_generated as fluent;
2727
28+ #[ derive( Copy , Clone ) ]
29+ pub ( crate ) enum MinMax {
30+ Minimum ,
31+ Minnum ,
32+ Maximum ,
33+ Maxnum ,
34+ }
35+
2836/// Directly returns an `Allocation` containing an absolute path representation of the given type.
2937pub ( crate ) fn alloc_type_name < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> ( AllocId , u64 ) {
3038 let path = crate :: util:: type_name ( tcx, ty) ;
@@ -486,25 +494,33 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
486494 self . write_scalar ( Scalar :: from_target_usize ( align. bytes ( ) , self ) , dest) ?;
487495 }
488496
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) ?,
493501
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) ?,
498510
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) ?,
503515
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) ?,
508524
509525 sym:: copysignf16 => self . float_copysign_intrinsic :: < Half > ( args, dest) ?,
510526 sym:: copysignf32 => self . float_copysign_intrinsic :: < Single > ( args, dest) ?,
@@ -901,76 +917,45 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
901917 interp_ok ( Scalar :: from_bool ( lhs_bytes == rhs_bytes) )
902918 }
903919
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 >
930926 where
931- F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
927+ F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > ,
932928 {
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 {
936932 // They are definitely not NaN (those are never equal), but they could be `+0` and `-0`.
937933 // Let the machine decide which one to return.
938934 M :: equal_float_min_max ( self , a, b)
939935 } 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] )
941943 } ;
942- self . write_scalar ( res, dest) ?;
943- interp_ok ( ( ) )
944- }
945944
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)
960946 }
961947
962- fn float_maximum_intrinsic < F > (
948+ fn float_minmax_intrinsic < F > (
963949 & mut self ,
964950 args : & [ OpTy < ' tcx , M :: Provenance > ] ,
951+ op : MinMax ,
965952 dest : & PlaceTy < ' tcx , M :: Provenance > ,
966953 ) -> InterpResult < ' tcx , ( ) >
967954 where
968955 F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
969956 {
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) ?;
974959 self . write_scalar ( res, dest) ?;
975960 interp_ok ( ( ) )
976961 }
0 commit comments