@@ -34,6 +34,18 @@ enum MulAddType {
3434 Nondeterministic ,
3535}
3636
37+ #[ derive( Copy , Clone ) ]
38+ pub ( crate ) enum MinMax {
39+ /// The IEEE `Minimum` operation - see `f32::minimum` etc
40+ Minimum ,
41+ /// The IEEE `MinNum` operation - see `f32::min` etc
42+ Minnum ,
43+ /// The IEEE `Maximum` operation - see `f32::maximum` etc
44+ Maximum ,
45+ /// The IEEE `MaxNum` operation - see `f32::max` etc
46+ Maxnum ,
47+ }
48+
3749/// Directly returns an `Allocation` containing an absolute path representation of the given type.
3850pub ( crate ) fn alloc_type_name < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> ( AllocId , u64 ) {
3951 let path = crate :: util:: type_name ( tcx, ty) ;
@@ -495,25 +507,33 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
495507 self . write_scalar ( Scalar :: from_target_usize ( align. bytes ( ) , self ) , dest) ?;
496508 }
497509
498- sym:: minnumf16 => self . float_min_intrinsic :: < Half > ( args, dest) ?,
499- sym:: minnumf32 => self . float_min_intrinsic :: < Single > ( args, dest) ?,
500- sym:: minnumf64 => self . float_min_intrinsic :: < Double > ( args, dest) ?,
501- sym:: minnumf128 => self . float_min_intrinsic :: < Quad > ( args, dest) ?,
510+ sym:: minnumf16 => self . float_minmax_intrinsic :: < Half > ( args, MinMax :: Minnum , dest) ?,
511+ sym:: minnumf32 => self . float_minmax_intrinsic :: < Single > ( args, MinMax :: Minnum , dest) ?,
512+ sym:: minnumf64 => self . float_minmax_intrinsic :: < Double > ( args, MinMax :: Minnum , dest) ?,
513+ sym:: minnumf128 => self . float_minmax_intrinsic :: < Quad > ( args, MinMax :: Minnum , dest) ?,
502514
503- sym:: minimumf16 => self . float_minimum_intrinsic :: < Half > ( args, dest) ?,
504- sym:: minimumf32 => self . float_minimum_intrinsic :: < Single > ( args, dest) ?,
505- sym:: minimumf64 => self . float_minimum_intrinsic :: < Double > ( args, dest) ?,
506- sym:: minimumf128 => self . float_minimum_intrinsic :: < Quad > ( args, dest) ?,
515+ sym:: minimumf16 => self . float_minmax_intrinsic :: < Half > ( args, MinMax :: Minimum , dest) ?,
516+ sym:: minimumf32 => {
517+ self . float_minmax_intrinsic :: < Single > ( args, MinMax :: Minimum , dest) ?
518+ }
519+ sym:: minimumf64 => {
520+ self . float_minmax_intrinsic :: < Double > ( args, MinMax :: Minimum , dest) ?
521+ }
522+ sym:: minimumf128 => self . float_minmax_intrinsic :: < Quad > ( args, MinMax :: Minimum , dest) ?,
507523
508- sym:: maxnumf16 => self . float_max_intrinsic :: < Half > ( args, dest) ?,
509- sym:: maxnumf32 => self . float_max_intrinsic :: < Single > ( args, dest) ?,
510- sym:: maxnumf64 => self . float_max_intrinsic :: < Double > ( args, dest) ?,
511- sym:: maxnumf128 => self . float_max_intrinsic :: < Quad > ( args, dest) ?,
524+ sym:: maxnumf16 => self . float_minmax_intrinsic :: < Half > ( args, MinMax :: Maxnum , dest) ?,
525+ sym:: maxnumf32 => self . float_minmax_intrinsic :: < Single > ( args, MinMax :: Maxnum , dest) ?,
526+ sym:: maxnumf64 => self . float_minmax_intrinsic :: < Double > ( args, MinMax :: Maxnum , dest) ?,
527+ sym:: maxnumf128 => self . float_minmax_intrinsic :: < Quad > ( args, MinMax :: Maxnum , dest) ?,
512528
513- sym:: maximumf16 => self . float_maximum_intrinsic :: < Half > ( args, dest) ?,
514- sym:: maximumf32 => self . float_maximum_intrinsic :: < Single > ( args, dest) ?,
515- sym:: maximumf64 => self . float_maximum_intrinsic :: < Double > ( args, dest) ?,
516- sym:: maximumf128 => self . float_maximum_intrinsic :: < Quad > ( args, dest) ?,
529+ sym:: maximumf16 => self . float_minmax_intrinsic :: < Half > ( args, MinMax :: Maximum , dest) ?,
530+ sym:: maximumf32 => {
531+ self . float_minmax_intrinsic :: < Single > ( args, MinMax :: Maximum , dest) ?
532+ }
533+ sym:: maximumf64 => {
534+ self . float_minmax_intrinsic :: < Double > ( args, MinMax :: Maximum , dest) ?
535+ }
536+ sym:: maximumf128 => self . float_minmax_intrinsic :: < Quad > ( args, MinMax :: Maximum , dest) ?,
517537
518538 sym:: copysignf16 => self . float_copysign_intrinsic :: < Half > ( args, dest) ?,
519539 sym:: copysignf32 => self . float_copysign_intrinsic :: < Single > ( args, dest) ?,
@@ -918,76 +938,45 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
918938 interp_ok ( Scalar :: from_bool ( lhs_bytes == rhs_bytes) )
919939 }
920940
921- fn float_min_intrinsic < F > (
922- & mut self ,
923- args : & [ OpTy < ' tcx , M :: Provenance > ] ,
924- dest : & PlaceTy < ' tcx , M :: Provenance > ,
925- ) -> InterpResult < ' tcx , ( ) >
926- where
927- F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
928- {
929- let a: F = self . read_scalar ( & args[ 0 ] ) ?. to_float ( ) ?;
930- let b: F = self . read_scalar ( & args[ 1 ] ) ?. to_float ( ) ?;
931- let res = if a == b {
932- // They are definitely not NaN (those are never equal), but they could be `+0` and `-0`.
933- // Let the machine decide which one to return.
934- M :: equal_float_min_max ( self , a, b)
935- } else {
936- self . adjust_nan ( a. min ( b) , & [ a, b] )
937- } ;
938- self . write_scalar ( res, dest) ?;
939- interp_ok ( ( ) )
940- }
941-
942- fn float_max_intrinsic < F > (
943- & mut self ,
944- args : & [ OpTy < ' tcx , M :: Provenance > ] ,
945- dest : & PlaceTy < ' tcx , M :: Provenance > ,
946- ) -> InterpResult < ' tcx , ( ) >
941+ fn float_minmax < F > (
942+ & self ,
943+ a : Scalar < M :: Provenance > ,
944+ b : Scalar < M :: Provenance > ,
945+ op : MinMax ,
946+ ) -> InterpResult < ' tcx , F >
947947 where
948- F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
948+ F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > ,
949949 {
950- let a: F = self . read_scalar ( & args [ 0 ] ) ? . to_float ( ) ?;
951- let b: F = self . read_scalar ( & args [ 1 ] ) ? . to_float ( ) ?;
952- let res = if a == b {
950+ let a: F = a . to_float ( ) ?;
951+ let b: F = b . to_float ( ) ?;
952+ let res = if matches ! ( op , MinMax :: Minnum | MinMax :: Maxnum ) && a == b {
953953 // They are definitely not NaN (those are never equal), but they could be `+0` and `-0`.
954954 // Let the machine decide which one to return.
955955 M :: equal_float_min_max ( self , a, b)
956956 } else {
957- self . adjust_nan ( a. max ( b) , & [ a, b] )
957+ let result = match op {
958+ MinMax :: Minimum => a. minimum ( b) ,
959+ MinMax :: Minnum => a. min ( b) ,
960+ MinMax :: Maximum => a. maximum ( b) ,
961+ MinMax :: Maxnum => a. max ( b) ,
962+ } ;
963+ self . adjust_nan ( result, & [ a, b] )
958964 } ;
959- self . write_scalar ( res, dest) ?;
960- interp_ok ( ( ) )
961- }
962965
963- fn float_minimum_intrinsic < F > (
964- & mut self ,
965- args : & [ OpTy < ' tcx , M :: Provenance > ] ,
966- dest : & PlaceTy < ' tcx , M :: Provenance > ,
967- ) -> InterpResult < ' tcx , ( ) >
968- where
969- F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
970- {
971- let a: F = self . read_scalar ( & args[ 0 ] ) ?. to_float ( ) ?;
972- let b: F = self . read_scalar ( & args[ 1 ] ) ?. to_float ( ) ?;
973- let res = a. minimum ( b) ;
974- let res = self . adjust_nan ( res, & [ a, b] ) ;
975- self . write_scalar ( res, dest) ?;
976- interp_ok ( ( ) )
966+ interp_ok ( res)
977967 }
978968
979- fn float_maximum_intrinsic < F > (
969+ fn float_minmax_intrinsic < F > (
980970 & mut self ,
981971 args : & [ OpTy < ' tcx , M :: Provenance > ] ,
972+ op : MinMax ,
982973 dest : & PlaceTy < ' tcx , M :: Provenance > ,
983974 ) -> InterpResult < ' tcx , ( ) >
984975 where
985976 F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
986977 {
987- let a: F = self . read_scalar ( & args[ 0 ] ) ?. to_float ( ) ?;
988- let b: F = self . read_scalar ( & args[ 1 ] ) ?. to_float ( ) ?;
989- let res = a. maximum ( b) ;
990- let res = self . adjust_nan ( res, & [ a, b] ) ;
978+ let res =
979+ self . float_minmax :: < F > ( self . read_scalar ( & args[ 0 ] ) ?, self . read_scalar ( & args[ 1 ] ) ?, op) ?;
991980 self . write_scalar ( res, dest) ?;
992981 interp_ok ( ( ) )
993982 }
0 commit comments