@@ -345,7 +345,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
345
345
bug ! ( "simd_fabs operand is not a float" )
346
346
} ;
347
347
let op = op. to_scalar ( ) ?;
348
- // FIXME: Using host floats.
349
348
match float_ty {
350
349
FloatTy :: F32 => Scalar :: from_f32 ( op. to_f32 ( ) ?. abs ( ) ) ,
351
350
FloatTy :: F64 => Scalar :: from_f64 ( op. to_f64 ( ) ?. abs ( ) ) ,
@@ -438,12 +437,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
438
437
}
439
438
}
440
439
Op :: FMax => {
441
- assert ! ( matches!( dest. layout. ty. kind( ) , ty:: Float ( _) ) ) ;
442
- this. max_op ( & left, & right) ?. to_scalar ( ) ?
440
+ fmax_op ( & left, & right) ?
443
441
}
444
442
Op :: FMin => {
445
- assert ! ( matches!( dest. layout. ty. kind( ) , ty:: Float ( _) ) ) ;
446
- this. min_op ( & left, & right) ?. to_scalar ( ) ?
443
+ fmin_op ( & left, & right) ?
447
444
}
448
445
} ;
449
446
this. write_scalar ( val, & dest. into ( ) ) ?;
@@ -499,10 +496,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
499
496
this. binary_op ( mir_op, & res, & op) ?
500
497
}
501
498
Op :: Max => {
502
- this. max_op ( & res, & op) ?
499
+ if matches ! ( res. layout. ty. kind( ) , ty:: Float ( _) ) {
500
+ ImmTy :: from_scalar ( fmax_op ( & res, & op) ?, res. layout )
501
+ } else {
502
+ // Just boring integers, so NaNs to worry about
503
+ if this. binary_op ( BinOp :: Ge , & res, & op) ?. to_scalar ( ) ?. to_bool ( ) ? {
504
+ res
505
+ } else {
506
+ op
507
+ }
508
+ }
503
509
}
504
510
Op :: Min => {
505
- this. min_op ( & res, & op) ?
511
+ if matches ! ( res. layout. ty. kind( ) , ty:: Float ( _) ) {
512
+ ImmTy :: from_scalar ( fmin_op ( & res, & op) ?, res. layout )
513
+ } else {
514
+ // Just boring integers, so NaNs to worry about
515
+ if this. binary_op ( BinOp :: Le , & res, & op) ?. to_scalar ( ) ?. to_bool ( ) ? {
516
+ res
517
+ } else {
518
+ op
519
+ }
520
+ }
506
521
}
507
522
} ;
508
523
}
@@ -1078,30 +1093,36 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1078
1093
_ => bug ! ( "`float_to_int_unchecked` called with non-int output type {:?}" , dest_ty) ,
1079
1094
} )
1080
1095
}
1096
+ }
1081
1097
1082
- fn max_op (
1083
- & self ,
1084
- left : & ImmTy < ' tcx , Tag > ,
1085
- right : & ImmTy < ' tcx , Tag > ,
1086
- ) -> InterpResult < ' tcx , ImmTy < ' tcx , Tag > > {
1087
- let this = self . eval_context_ref ( ) ;
1088
- Ok ( if this. binary_op ( BinOp :: Gt , left, right) ?. to_scalar ( ) ?. to_bool ( ) ? {
1089
- * left
1090
- } else {
1091
- * right
1092
- } )
1093
- }
1098
+ fn fmax_op < ' tcx > (
1099
+ left : & ImmTy < ' tcx , Tag > ,
1100
+ right : & ImmTy < ' tcx , Tag > ,
1101
+ ) -> InterpResult < ' tcx , Scalar < Tag > > {
1102
+ assert_eq ! ( left. layout. ty, right. layout. ty) ;
1103
+ let ty:: Float ( float_ty) = left. layout . ty . kind ( ) else {
1104
+ bug ! ( "fmax operand is not a float" )
1105
+ } ;
1106
+ let left = left. to_scalar ( ) ?;
1107
+ let right = right. to_scalar ( ) ?;
1108
+ Ok ( match float_ty {
1109
+ FloatTy :: F32 => Scalar :: from_f32 ( left. to_f32 ( ) ?. max ( right. to_f32 ( ) ?) ) ,
1110
+ FloatTy :: F64 => Scalar :: from_f64 ( left. to_f64 ( ) ?. max ( right. to_f64 ( ) ?) ) ,
1111
+ } )
1112
+ }
1094
1113
1095
- fn min_op (
1096
- & self ,
1097
- left : & ImmTy < ' tcx , Tag > ,
1098
- right : & ImmTy < ' tcx , Tag > ,
1099
- ) -> InterpResult < ' tcx , ImmTy < ' tcx , Tag > > {
1100
- let this = self . eval_context_ref ( ) ;
1101
- Ok ( if this. binary_op ( BinOp :: Lt , left, right) ?. to_scalar ( ) ?. to_bool ( ) ? {
1102
- * left
1103
- } else {
1104
- * right
1105
- } )
1106
- }
1114
+ fn fmin_op < ' tcx > (
1115
+ left : & ImmTy < ' tcx , Tag > ,
1116
+ right : & ImmTy < ' tcx , Tag > ,
1117
+ ) -> InterpResult < ' tcx , Scalar < Tag > > {
1118
+ assert_eq ! ( left. layout. ty, right. layout. ty) ;
1119
+ let ty:: Float ( float_ty) = left. layout . ty . kind ( ) else {
1120
+ bug ! ( "fmin operand is not a float" )
1121
+ } ;
1122
+ let left = left. to_scalar ( ) ?;
1123
+ let right = right. to_scalar ( ) ?;
1124
+ Ok ( match float_ty {
1125
+ FloatTy :: F32 => Scalar :: from_f32 ( left. to_f32 ( ) ?. min ( right. to_f32 ( ) ?) ) ,
1126
+ FloatTy :: F64 => Scalar :: from_f64 ( left. to_f64 ( ) ?. min ( right. to_f64 ( ) ?) ) ,
1127
+ } )
1107
1128
}
0 commit comments