Skip to content

Commit 7750cd9

Browse files
committed
Auto merge of #2894 - RalfJung:simd-ptr, r=RalfJung
implement SIMD ptr casts
2 parents b22bc27 + 10540a2 commit 7750cd9

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

src/tools/miri/src/shims/intrinsics/simd.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -421,34 +421,50 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
421421
}
422422
}
423423
#[rustfmt::skip]
424-
"cast" | "as" => {
424+
"cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
425425
let [op] = check_arg_count(args)?;
426426
let (op, op_len) = this.operand_to_simd(op)?;
427427
let (dest, dest_len) = this.place_to_simd(dest)?;
428428

429429
assert_eq!(dest_len, op_len);
430430

431+
let unsafe_cast = intrinsic_name == "cast";
431432
let safe_cast = intrinsic_name == "as";
433+
let ptr_cast = intrinsic_name == "cast_ptr";
434+
let expose_cast = intrinsic_name == "expose_addr";
435+
let from_exposed_cast = intrinsic_name == "from_exposed_addr";
432436

433437
for i in 0..dest_len {
434438
let op = this.read_immediate(&this.mplace_index(&op, i)?.into())?;
435439
let dest = this.mplace_index(&dest, i)?;
436440

437441
let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) {
438442
// Int-to-(int|float): always safe
439-
(ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) =>
443+
(ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) if safe_cast || unsafe_cast =>
440444
this.int_to_int_or_float(&op, dest.layout.ty)?,
441445
// Float-to-float: always safe
442-
(ty::Float(_), ty::Float(_)) =>
446+
(ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast =>
443447
this.float_to_float_or_int(&op, dest.layout.ty)?,
444448
// Float-to-int in safe mode
445449
(ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast =>
446450
this.float_to_float_or_int(&op, dest.layout.ty)?,
447451
// Float-to-int in unchecked mode
448-
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if !safe_cast =>
452+
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
449453
this.float_to_int_unchecked(op.to_scalar().to_f32()?, dest.layout.ty)?.into(),
450-
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if !safe_cast =>
454+
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
451455
this.float_to_int_unchecked(op.to_scalar().to_f64()?, dest.layout.ty)?.into(),
456+
// Ptr-to-ptr cast
457+
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast => {
458+
this.ptr_to_ptr(&op, dest.layout.ty)?
459+
}
460+
// Ptr/Int casts
461+
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast => {
462+
this.pointer_expose_address_cast(&op, dest.layout.ty)?
463+
}
464+
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => {
465+
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?
466+
}
467+
// Error otherwise
452468
_ =>
453469
throw_unsup_format!(
454470
"Unsupported SIMD cast from element type {from_ty} to {to_ty}",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Separate test without strict provenance
2+
//@compile-flags: -Zmiri-permissive-provenance
3+
#![feature(portable_simd, platform_intrinsics)]
4+
use std::ptr;
5+
use std::simd::*;
6+
7+
fn main() {
8+
// Pointer casts
9+
let _val: Simd<*const u8, 4> = Simd::<*const i32, 4>::splat(ptr::null()).cast_ptr();
10+
let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_addr();
11+
let _ptrs = Simd::<*const i32, 4>::from_exposed_addr(addrs);
12+
}

0 commit comments

Comments
 (0)