@@ -17,7 +17,6 @@ use self::atomic::EvalContextExt as _;
17
17
use self :: helpers:: { ToHost , ToSoft , check_intrinsic_arg_count} ;
18
18
use self :: simd:: EvalContextExt as _;
19
19
use crate :: math:: { IeeeExt , apply_random_float_error_ulp} ;
20
- use crate :: operator:: EvalContextExt as _;
21
20
use crate :: * ;
22
21
23
22
impl < ' tcx > EvalContextExt < ' tcx > for crate :: MiriInterpCx < ' tcx > { }
@@ -535,18 +534,20 @@ fn fixed_float_value<S: Semantics>(
535
534
// (-1)^(±INF) = 1
536
535
( "powf32" | "powf64" , [ base, exp] ) if * base == -one && exp. is_infinite ( ) => one,
537
536
538
- // 1^y = 1 for any y, even a NaN, *but* not a SNaN
537
+ // 1^y = 1 for any y, even a NaN
539
538
( "powf32" | "powf64" , [ base, exp] ) if * base == one => {
540
539
let rng = ecx. machine . rng . get_mut ( ) ;
541
- let return_nan = ecx. machine . float_nondet && rng. random ( ) && exp. is_signaling ( ) ;
540
+ // SNaN exponents get special treatment: they might return 1, or a NaN.
541
+ let return_nan = exp. is_signaling ( ) && ecx. machine . float_nondet && rng. random ( ) ;
542
542
// Handle both the musl and glibc cases non-deterministically.
543
543
if return_nan { ecx. generate_nan ( args) } else { one }
544
544
}
545
545
546
- // x^(±0) = 1 for any x, even a NaN, *but* not a SNaN
546
+ // x^(±0) = 1 for any x, even a NaN
547
547
( "powf32" | "powf64" , [ base, exp] ) if exp. is_zero ( ) => {
548
548
let rng = ecx. machine . rng . get_mut ( ) ;
549
- let return_nan = ecx. machine . float_nondet && rng. random ( ) && base. is_signaling ( ) ;
549
+ // SNaN bases get special treatment: they might return 1, or a NaN.
550
+ let return_nan = base. is_signaling ( ) && ecx. machine . float_nondet && rng. random ( ) ;
550
551
// Handle both the musl and glibc cases non-deterministically.
551
552
if return_nan { ecx. generate_nan ( args) } else { one }
552
553
}
@@ -559,7 +560,9 @@ fn fixed_float_value<S: Semantics>(
559
560
560
561
/// Returns `Some(output)` if `powi` (called `pown` in C) results in a fixed value specified in the C standard
561
562
/// (specifically, C23 annex F.10.4.6) when doing `base^exp`. Otherwise, returns `None`.
562
- // TODO: I'm not sure what I should document here about pown(1, SNaN) since musl and glibc do the same and the C standard is explicit here.
563
+ /// For SNaN treatment, we are consistent with `powf`above.
564
+ /// (We wouldn't have two, unlike powf all implementations seem to agree for powi,
565
+ /// but for now we are maximally conservative.)
563
566
fn fixed_powi_float_value < S : Semantics > (
564
567
ecx : & mut MiriInterpCx < ' _ > ,
565
568
base : IeeeFloat < S > ,
0 commit comments