@@ -17,7 +17,6 @@ use self::atomic::EvalContextExt as _;
1717use self :: helpers:: { ToHost , ToSoft , check_intrinsic_arg_count} ;
1818use self :: simd:: EvalContextExt as _;
1919use crate :: math:: { IeeeExt , apply_random_float_error_ulp} ;
20- use crate :: operator:: EvalContextExt as _;
2120use crate :: * ;
2221
2322impl < ' tcx > EvalContextExt < ' tcx > for crate :: MiriInterpCx < ' tcx > { }
@@ -535,18 +534,20 @@ fn fixed_float_value<S: Semantics>(
535534 // (-1)^(±INF) = 1
536535 ( "powf32" | "powf64" , [ base, exp] ) if * base == -one && exp. is_infinite ( ) => one,
537536
538- // 1^y = 1 for any y, even a NaN, *but* not a SNaN
537+ // 1^y = 1 for any y, even a NaN
539538 ( "powf32" | "powf64" , [ base, exp] ) if * base == one => {
540539 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 ( ) ;
542542 // Handle both the musl and glibc cases non-deterministically.
543543 if return_nan { ecx. generate_nan ( args) } else { one }
544544 }
545545
546- // x^(±0) = 1 for any x, even a NaN, *but* not a SNaN
546+ // x^(±0) = 1 for any x, even a NaN
547547 ( "powf32" | "powf64" , [ base, exp] ) if exp. is_zero ( ) => {
548548 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 ( ) ;
550551 // Handle both the musl and glibc cases non-deterministically.
551552 if return_nan { ecx. generate_nan ( args) } else { one }
552553 }
@@ -559,7 +560,9 @@ fn fixed_float_value<S: Semantics>(
559560
560561/// Returns `Some(output)` if `powi` (called `pown` in C) results in a fixed value specified in the C standard
561562/// (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.)
563566fn fixed_powi_float_value < S : Semantics > (
564567 ecx : & mut MiriInterpCx < ' _ > ,
565568 base : IeeeFloat < S > ,
0 commit comments