about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-10-08 20:36:25 +0200
committerRalf Jung <post@ralfj.de>2023-10-09 07:37:24 +0200
commit615d738abea23715f649e51cf27112451a0f607b (patch)
treed78e4f7b5f770b77cdeefe8e61c9bc73cc906725
parent6796c5765d7b52271cd09ab977cb617ee3971a3a (diff)
downloadrust-615d738abea23715f649e51cf27112451a0f607b.tar.gz
rust-615d738abea23715f649e51cf27112451a0f607b.zip
ensure unary minus propagates NaN payloads exactly
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs1
-rw-r--r--src/tools/miri/tests/pass/float_nan.rs8
2 files changed, 9 insertions, 0 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index fe8572d9c6f..a685b499d0e 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -461,6 +461,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 Ok((ImmTy::from_bool(res, *self.tcx), false))
             }
             ty::Float(fty) => {
+                // No NaN adjustment here, `-` is a bitwise operation!
                 let res = match (un_op, fty) {
                     (Neg, FloatTy::F32) => Scalar::from_f32(-val.to_f32()?),
                     (Neg, FloatTy::F64) => Scalar::from_f64(-val.to_f64()?),
diff --git a/src/tools/miri/tests/pass/float_nan.rs b/src/tools/miri/tests/pass/float_nan.rs
index 8fa567aa106..cb9cc42c601 100644
--- a/src/tools/miri/tests/pass/float_nan.rs
+++ b/src/tools/miri/tests/pass/float_nan.rs
@@ -241,6 +241,14 @@ fn test_f32() {
         ]),
         || F32::from(just1 % all1_snan),
     );
+
+    // Unary `-` must preserve payloads exactly.
+    check_all_outcomes(HashSet::from_iter([F32::nan(Neg, Quiet, all1_payload)]), || {
+        F32::from(-all1)
+    });
+    check_all_outcomes(HashSet::from_iter([F32::nan(Neg, Signaling, all1_payload)]), || {
+        F32::from(-all1_snan)
+    });
 }
 
 fn test_f64() {