@@ -31,6 +31,7 @@ fn main() {
31
31
test_fast ( ) ;
32
32
test_algebraic ( ) ;
33
33
test_fmuladd ( ) ;
34
+ test_min_max_nondet ( ) ;
34
35
}
35
36
36
37
trait Float : Copy + PartialEq + Debug {
@@ -1211,3 +1212,30 @@ fn test_fmuladd() {
1211
1212
test_operations_f32 ( 0.1 , 0.2 , 0.3 ) ;
1212
1213
test_operations_f64 ( 1.1 , 1.2 , 1.3 ) ;
1213
1214
}
1215
+
1216
+ /// `min` and `max` on equal arguments are non-deterministic.
1217
+ fn test_min_max_nondet ( ) {
1218
+ /// Ensure that if we call the closure often enough, we see both `true` and `false.`
1219
+ #[ track_caller]
1220
+ fn ensure_both ( f : impl Fn ( ) -> bool ) {
1221
+ let rounds = 16 ;
1222
+ let first = f ( ) ;
1223
+ for _ in 1 ..rounds {
1224
+ if f ( ) != first {
1225
+ // We saw two different values!
1226
+ return ;
1227
+ }
1228
+ }
1229
+ // We saw the same thing N times.
1230
+ panic ! ( "expected non-determinism, got {rounds} times the same result: {first:?}" ) ;
1231
+ }
1232
+
1233
+ ensure_both ( || f16:: min ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1234
+ ensure_both ( || f16:: max ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1235
+ ensure_both ( || f32:: min ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1236
+ ensure_both ( || f32:: max ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1237
+ ensure_both ( || f64:: min ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1238
+ ensure_both ( || f64:: max ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1239
+ ensure_both ( || f128:: min ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1240
+ ensure_both ( || f128:: max ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1241
+ }
0 commit comments