@@ -522,40 +522,39 @@ fn unary_op_f32<'tcx>(
522
522
}
523
523
FloatUnaryOp :: Rcp => {
524
524
let op = op. to_scalar ( ) . to_f32 ( ) ?;
525
- // Calculate 1 / x and multiply the result by 1 + err (where err
526
- // is a random value with a magnitude in the order of 2^-12) to
527
- // simulate the inaccuracy of RCP.
528
- let one = Single :: from_u128 ( 1 ) . value ;
529
- let err = gen_random_float_error ( this, -12 ) ;
530
- let res = ( ( one / op) . value * ( one + err) . value ) . value ;
525
+ let div = ( Single :: from_u128 ( 1 ) . value / op) . value ;
526
+ // Apply a relative error with a magnitude on the order of 2^-12 to simulate the
527
+ // inaccuracy of RCP.
528
+ let res = apply_random_float_error ( this, div, -12 ) ;
531
529
Ok ( Scalar :: from_f32 ( res) )
532
530
}
533
531
FloatUnaryOp :: Rsqrt => {
534
532
let op = op. to_scalar ( ) . to_u32 ( ) ?;
535
- // Calculate 1 / sqrt(x) and multiply the result by 1 + err (where
536
- // err is a random value with a magnitude in the order of 2^-12) to
537
- // simulate the inaccuracy of RSQRT.
538
533
// FIXME using host floats
539
534
let sqrt = Single :: from_bits ( f32:: from_bits ( op) . sqrt ( ) . to_bits ( ) . into ( ) ) ;
540
- let one = Single :: from_u128 ( 1 ) . value ;
541
- let err = gen_random_float_error ( this , - 12 ) ;
542
- let res = ( ( one / sqrt) . value * ( one + err ) . value ) . value ;
535
+ // Apply a relative error with a magnitude on the order of 2^-12 to simulate the
536
+ // inaccuracy of RSQRT.
537
+ let res = apply_random_float_error ( this , sqrt, - 12 ) ;
543
538
Ok ( Scalar :: from_f32 ( res) )
544
539
}
545
540
}
546
541
}
547
542
548
- /// Returns a random a value in the range (-2^scale, 2^scale)
549
- fn gen_random_float_error < F : rustc_apfloat:: Float > (
543
+ /// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale).
544
+ #[ allow( clippy:: arithmetic_side_effects) ] // floating point arithmetic cannot panic
545
+ fn apply_random_float_error < F : rustc_apfloat:: Float > (
550
546
this : & mut crate :: MiriInterpCx < ' _ , ' _ > ,
551
- scale : i32 ,
547
+ val : F ,
548
+ err_scale : i32 ,
552
549
) -> F {
553
550
let rng = this. machine . rng . get_mut ( ) ;
554
551
// generates rand(0, 2^64) * 2^(scale - 64) = rand(0, 1) * 2^scale
555
- let v = F :: from_u128 ( rng. gen :: < u64 > ( ) . into ( ) ) . value . scalbn ( scale. checked_sub ( 64 ) . unwrap ( ) ) ;
552
+ let err =
553
+ F :: from_u128 ( rng. gen :: < u64 > ( ) . into ( ) ) . value . scalbn ( err_scale. checked_sub ( 64 ) . unwrap ( ) ) ;
556
554
// give it a random sign
557
- #[ allow( clippy:: arithmetic_side_effects) ] // floating point negation cannot panic
558
- if rng. gen :: < bool > ( ) { -v } else { v }
555
+ let err = if rng. gen :: < bool > ( ) { -err } else { err } ;
556
+ // multiple the value with (1+err)
557
+ ( val * ( F :: from_u128 ( 1 ) . value + err) . value ) . value
559
558
}
560
559
561
560
/// Performs `which` operation on the first component of `op` and copies
0 commit comments