@@ -34,6 +34,18 @@ enum MulAddType {
34
34
Nondeterministic ,
35
35
}
36
36
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
+
37
49
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
38
50
pub ( crate ) fn alloc_type_name < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> ( AllocId , u64 ) {
39
51
let path = crate :: util:: type_name ( tcx, ty) ;
@@ -495,25 +507,33 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
495
507
self . write_scalar ( Scalar :: from_target_usize ( align. bytes ( ) , self ) , dest) ?;
496
508
}
497
509
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) ?,
502
514
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) ?,
507
523
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) ?,
512
528
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) ?,
517
537
518
538
sym:: copysignf16 => self . float_copysign_intrinsic :: < Half > ( args, dest) ?,
519
539
sym:: copysignf32 => self . float_copysign_intrinsic :: < Single > ( args, dest) ?,
@@ -918,76 +938,45 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
918
938
interp_ok ( Scalar :: from_bool ( lhs_bytes == rhs_bytes) )
919
939
}
920
940
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 >
947
947
where
948
- F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
948
+ F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > ,
949
949
{
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 {
953
953
// They are definitely not NaN (those are never equal), but they could be `+0` and `-0`.
954
954
// Let the machine decide which one to return.
955
955
M :: equal_float_min_max ( self , a, b)
956
956
} 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] )
958
964
} ;
959
- self . write_scalar ( res, dest) ?;
960
- interp_ok ( ( ) )
961
- }
962
965
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)
977
967
}
978
968
979
- fn float_maximum_intrinsic < F > (
969
+ fn float_minmax_intrinsic < F > (
980
970
& mut self ,
981
971
args : & [ OpTy < ' tcx , M :: Provenance > ] ,
972
+ op : MinMax ,
982
973
dest : & PlaceTy < ' tcx , M :: Provenance > ,
983
974
) -> InterpResult < ' tcx , ( ) >
984
975
where
985
976
F : rustc_apfloat:: Float + rustc_apfloat:: FloatConvert < F > + Into < Scalar < M :: Provenance > > ,
986
977
{
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) ?;
991
980
self . write_scalar ( res, dest) ?;
992
981
interp_ok ( ( ) )
993
982
}
0 commit comments