about summary refs log tree commit diff
path: root/src/tools/miri
diff options
context:
space:
mode:
authorCatherine Flores <catherine.3.flores@gmail.com>2023-08-01 15:35:12 +0000
committerNicholas Thompson <NCGThompson@gmail.com>2024-01-19 13:46:27 -0500
commit5a4561749a18fa96691f9cf79699e6ab2f1f7b2c (patch)
tree108d8b27aab1d3348a0c84e2dab8ab50b15fde7f /src/tools/miri
parent94807670a6a3834cc9b71b0b803d49d307c9ba5d (diff)
downloadrust-5a4561749a18fa96691f9cf79699e6ab2f1f7b2c.tar.gz
rust-5a4561749a18fa96691f9cf79699e6ab2f1f7b2c.zip
Add new intrinsic `is_constant` and optimize `pow`
Fix overflow check

Make MIRI choose the path randomly and rename the intrinsic

Add back test

Add miri test and make it operate on `ptr`

Define `llvm.is.constant` for primitives

Update MIRI comment and fix test in stage2

Add const eval test

Clarify that both branches must have the same side effects

guaranteed non guarantee

use immediate type instead

Co-Authored-By: Ralf Jung <post@ralfj.de>
Diffstat (limited to 'src/tools/miri')
-rw-r--r--src/tools/miri/src/shims/intrinsics/mod.rs12
-rw-r--r--src/tools/miri/tests/pass/intrinsics.rs15
2 files changed, 27 insertions, 0 deletions
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index a1db7bf74f2..8edc0a4220d 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -5,6 +5,7 @@ use std::iter;
 
 use log::trace;
 
+use rand::Rng;
 use rustc_apfloat::{Float, Round};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::{
@@ -141,6 +142,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 this.write_pointer(Pointer::new(ptr.provenance, masked_addr), dest)?;
             }
 
+            // We want to return either `true` or `false` at random, or else something like
+            // ```
+            // if !is_val_statically_known(0) { unreachable_unchecked(); }
+            // ```
+            // Would not be considered UB, or the other way around (`is_val_statically_known(0)`).
+            "is_val_statically_known" => {
+                let [_] = check_arg_count(args)?;
+                let branch: bool = this.machine.rng.get_mut().gen();
+                this.write_scalar(Scalar::from_bool(branch), dest)?;
+            }
+
             // Floating-point operations
             "fabsf32" => {
                 let [f] = check_arg_count(args)?;
diff --git a/src/tools/miri/tests/pass/intrinsics.rs b/src/tools/miri/tests/pass/intrinsics.rs
index 8c6eeab2219..8e46bd7ad48 100644
--- a/src/tools/miri/tests/pass/intrinsics.rs
+++ b/src/tools/miri/tests/pass/intrinsics.rs
@@ -33,6 +33,21 @@ fn main() {
     assert_eq!(intrinsics::likely(false), false);
     assert_eq!(intrinsics::unlikely(true), true);
 
+    let mut saw_true = false;
+    let mut saw_false = false;
+
+    for _ in 0..50 {
+        if unsafe { intrinsics::is_val_statically_known(0) } {
+            saw_true = true;
+        } else {
+            saw_false = true;
+        }
+    }
+    assert!(
+        saw_true && saw_false,
+        "`is_val_statically_known` failed to return both true and false. Congrats, you won the lottery!"
+    );
+
     intrinsics::forget(Bomb);
 
     let _v = intrinsics::discriminant_value(&Some(()));