Skip to content

Commit 538adfb

Browse files
tests and pertubations for non-deterministic floating point operations in shims/foreign_items
1 parent 97b5838 commit 538adfb

File tree

2 files changed

+59
-14
lines changed

2 files changed

+59
-14
lines changed

src/shims/foreign_items.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
786786
"fdimf" => f1.to_host().abs_sub(f2.to_host()).to_soft(),
787787
_ => bug!(),
788788
};
789+
// Apply a relative error with a magnitude on the order of 2^-21 to simulate
790+
// non-deterministic behaviour of floats
791+
let res = math::apply_random_float_error(this, res, -21);
789792
let res = this.adjust_nan(res, &[f1, f2]);
790793
this.write_scalar(res, dest)?;
791794
}
@@ -820,7 +823,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
820823
"tgamma" => f_host.gamma(),
821824
_ => bug!(),
822825
};
823-
let res = res.to_soft();
826+
// Apply a relative error with a magnitude on the order of 2^-50 to simulate
827+
// non-deterministic behaviour of floats
828+
let res = math::apply_random_float_error(this, res.to_soft(), -50);
824829
let res = this.adjust_nan(res, &[f]);
825830
this.write_scalar(res, dest)?;
826831
}
@@ -843,6 +848,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
843848
"fdim" => f1.to_host().abs_sub(f2.to_host()).to_soft(),
844849
_ => bug!(),
845850
};
851+
// Apply a relative error with a magnitude on the order of 2^-50 to simulate
852+
// non-deterministic behaviour of floats
853+
let res = math::apply_random_float_error(this, res, -50);
846854
let res = this.adjust_nan(res, &[f1, f2]);
847855
this.write_scalar(res, dest)?;
848856
}
@@ -868,7 +876,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
868876
// Using host floats (but it's fine, these operations do not have guaranteed precision).
869877
let (res, sign) = x.to_host().ln_gamma();
870878
this.write_int(sign, &signp)?;
871-
let res = this.adjust_nan(res.to_soft(), &[x]);
879+
// Apply a relative error with a magnitude on the order of 2^-21 to simulate
880+
// non-deterministic behaviour of floats
881+
let res = math::apply_random_float_error(this, res.to_soft(), -21);
882+
let res = this.adjust_nan(res, &[x]);
872883
this.write_scalar(res, dest)?;
873884
}
874885
"lgamma_r" => {
@@ -879,7 +890,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
879890
// Using host floats (but it's fine, these operations do not have guaranteed precision).
880891
let (res, sign) = x.to_host().ln_gamma();
881892
this.write_int(sign, &signp)?;
882-
let res = this.adjust_nan(res.to_soft(), &[x]);
893+
// Apply a relative error with a magnitude on the order of 2^-50 to simulate
894+
// non-deterministic behaviour of floats
895+
let res = math::apply_random_float_error(this, res.to_soft(), -50);
896+
let res = this.adjust_nan(res, &[x]);
883897
this.write_scalar(res, dest)?;
884898
}
885899

tests/pass/float.rs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,6 @@ fn test_non_determinism() {
12911291
for (idx1, res1) in results {
12921292
for (idx2, res2) in results {
12931293
if idx1 == idx2 {
1294-
assert_eq!(res1, res2);
12951294
continue;
12961295
}
12971296
assert_approx_eq!(res1, res2);
@@ -1324,29 +1323,61 @@ fn test_non_determinism() {
13241323
pub fn test_operations_f32(a: f32, b: f32) {
13251324
test_operations_f!(a, b);
13261325
test_operation!(a, b, f32::log);
1327-
test_operation!(a, f32::cos);
13281326
test_operation!(a, f32::exp);
1329-
test_operation!(a, f32::exp2);
1330-
test_operation!(a, f32::log2);
1331-
test_operation!(a, f32::log10);
1332-
test_operation!(a, f32::sin);
13331327
}
13341328
pub fn test_operations_f64(a: f64, b: f64) {
13351329
test_operations_f!(a, b);
13361330
test_operation!(a, b, f64::log);
1337-
test_operation!(a, f64::cos);
13381331
test_operation!(a, f64::exp);
1339-
test_operation!(a, f64::exp2);
1340-
test_operation!(a, f64::log2);
1341-
test_operation!(a, f64::log10);
1342-
test_operation!(a, f64::sin);
13431332
}
13441333
pub fn test_operations_f128(a: f128, b: f128) {
13451334
test_operations_f!(a, b);
13461335
}
13471336

1337+
pub fn test_extras() {
1338+
// f32
1339+
test_operation!(10f32, f32::exp2);
1340+
test_operation!(f32::consts::E, f32::ln);
1341+
test_operation!(0f32, f32::ln_1p);
1342+
test_operation!(10f32, f32::log10);
1343+
test_operation!(8f32, f32::log2);
1344+
test_operation!(27.0f32, f32::cbrt);
1345+
test_operation!(3.0f32, 4.0f32, f32::hypot);
1346+
test_operation!(0f32, f32::sin);
1347+
test_operation!(0f32, f32::cos);
1348+
test_operation!(1.0f32, f32::sinh);
1349+
test_operation!(1.0f32, f32::asinh);
1350+
test_operation!(1.0f32, f32::cosh);
1351+
test_operation!(2.0f32, f32::acosh);
1352+
test_operation!(1.0f32, f32::tan);
1353+
test_operation!(1.0f32, f32::tanh);
1354+
test_operation!(1.0f32, 2.0f32, f32::atan2);
1355+
test_operation!(0.5f32, f32::atanh);
1356+
test_operation!(5.0f32, f32::gamma);
1357+
1358+
// f64
1359+
test_operation!(50f64, f64::exp2);
1360+
test_operation!(1f64, f64::ln);
1361+
test_operation!(0f64, f64::ln_1p);
1362+
test_operation!(f64::consts::E, f64::log10);
1363+
test_operation!(f64::consts::E, f64::log2);
1364+
test_operation!(0f64, f64::sin);
1365+
test_operation!(0f64, f64::cos);
1366+
test_operation!(27.0f64, f64::cbrt);
1367+
test_operation!(3.0f64, 4.0f64, f64::hypot);
1368+
test_operation!(1.0f64, f64::sinh);
1369+
test_operation!(1.0f64, f64::asinh);
1370+
test_operation!(1.0f64, f64::cosh);
1371+
test_operation!(3.0f64, f64::acosh);
1372+
test_operation!(1.0f64, f64::tan);
1373+
test_operation!(1.0f64, f64::tanh);
1374+
test_operation!(0.5f64, f64::atanh);
1375+
test_operation!(5.0f64, f64::gamma);
1376+
}
1377+
13481378
test_operations_f16(5., 7.);
13491379
test_operations_f32(12., 4.);
13501380
test_operations_f64(19., 11.);
13511381
test_operations_f128(25., 18.);
1382+
test_extras();
13521383
}

0 commit comments

Comments
 (0)