Skip to content

Commit 94ae910

Browse files
committed
Auto merge of #1875 - niluxv:volatile_set_memory_intrinsic, r=RalfJung
Add support for the `volatile_set_memory` intrinsic Add support for the unstable `volatile_set_memory` intrinsic (Runtime behaviour and soundness requirements for `volatile_set_memory` are identical to those of `write_bytes`, so supporting this intrinsic is trivial.)
2 parents 7ec2bee + 083e5e6 commit 94ae910

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

src/shims/intrinsics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6666
this.copy_op(dest, &place.into())?;
6767
}
6868

69-
"write_bytes" => {
69+
"write_bytes" | "volatile_set_memory" => {
7070
let &[ref ptr, ref val_byte, ref count] = check_arg_count(args)?;
7171
let ty = instance.substs.type_at(0);
7272
let ty_layout = this.layout_of(ty)?;
7373
let val_byte = this.read_scalar(val_byte)?.to_u8()?;
7474
let ptr = this.read_pointer(ptr)?;
7575
let count = this.read_scalar(count)?.to_machine_usize(this)?;
7676
let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| {
77-
err_ub_format!("overflow computing total size of `write_bytes`")
77+
err_ub_format!("overflow computing total size of `{}`", intrinsic_name)
7878
})?;
7979
this.memory
8080
.write_bytes(ptr, iter::repeat(val_byte).take(byte_count.bytes() as usize))?;

tests/run-pass/write-bytes.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![feature(core_intrinsics)] // for `volatile_set_memory`
2+
13
#[repr(C)]
24
#[derive(Copy, Clone)]
35
struct Foo {
@@ -42,4 +44,42 @@ fn main() {
4244
assert_eq!(w[idx].b, 0xcdcdcdcdcdcdcdcd);
4345
assert_eq!(w[idx].c, 0xcdcdcdcdcdcdcdcd);
4446
}
47+
48+
// -----
49+
// `std::intrinsics::volatile_set_memory` should behave identically
50+
51+
let mut v: [u64; LENGTH] = [0; LENGTH];
52+
53+
for idx in 0..LENGTH {
54+
assert_eq!(v[idx], 0);
55+
}
56+
57+
unsafe {
58+
let p = v.as_mut_ptr();
59+
::std::intrinsics::volatile_set_memory(p, 0xab, LENGTH);
60+
}
61+
62+
for idx in 0..LENGTH {
63+
assert_eq!(v[idx], 0xabababababababab);
64+
}
65+
66+
// -----
67+
68+
let mut w: [Foo; LENGTH] = [Foo { a: 0, b: 0, c: 0 }; LENGTH];
69+
for idx in 0..LENGTH {
70+
assert_eq!(w[idx].a, 0);
71+
assert_eq!(w[idx].b, 0);
72+
assert_eq!(w[idx].c, 0);
73+
}
74+
75+
unsafe {
76+
let p = w.as_mut_ptr();
77+
::std::intrinsics::volatile_set_memory(p, 0xcd, LENGTH);
78+
}
79+
80+
for idx in 0..LENGTH {
81+
assert_eq!(w[idx].a, 0xcdcdcdcdcdcdcdcd);
82+
assert_eq!(w[idx].b, 0xcdcdcdcdcdcdcdcd);
83+
assert_eq!(w[idx].c, 0xcdcdcdcdcdcdcdcd);
84+
}
4585
}

0 commit comments

Comments
 (0)