Add simd_cast_ptr, simd_expose_addr, and simd_from_exposed_addr intrinsics
This commit is contained in:
parent
43347397f7
commit
e2866c0a67
@ -1704,6 +1704,85 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
||||
bitwise_red!(simd_reduce_all: vector_reduce_and, true);
|
||||
bitwise_red!(simd_reduce_any: vector_reduce_or, true);
|
||||
|
||||
if name == sym::simd_cast_ptr {
|
||||
require_simd!(ret_ty, "return");
|
||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
require!(
|
||||
in_len == out_len,
|
||||
"expected return type with length {} (same as input type `{}`), \
|
||||
found `{}` with length {}",
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
);
|
||||
|
||||
match in_elem.kind() {
|
||||
ty::RawPtr(_) => {}
|
||||
_ => return_error!("expected pointer, got `{}`", in_elem),
|
||||
}
|
||||
match out_elem.kind() {
|
||||
ty::RawPtr(_) => {}
|
||||
_ => return_error!("expected pointer, got `{}`", out_elem),
|
||||
}
|
||||
|
||||
if in_elem == out_elem {
|
||||
return Ok(args[0].immediate());
|
||||
} else {
|
||||
return Ok(bx.pointercast(args[0].immediate(), llret_ty));
|
||||
}
|
||||
}
|
||||
|
||||
if name == sym::simd_expose_addr {
|
||||
require_simd!(ret_ty, "return");
|
||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
require!(
|
||||
in_len == out_len,
|
||||
"expected return type with length {} (same as input type `{}`), \
|
||||
found `{}` with length {}",
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
);
|
||||
|
||||
match in_elem.kind() {
|
||||
ty::RawPtr(_) => {}
|
||||
_ => return_error!("expected pointer, got `{}`", in_elem),
|
||||
}
|
||||
match out_elem.kind() {
|
||||
ty::Uint(ty::UintTy::Usize) => {}
|
||||
_ => return_error!("expected `usize`, got `{}`", out_elem),
|
||||
}
|
||||
|
||||
return Ok(bx.ptrtoint(args[0].immediate(), llret_ty));
|
||||
}
|
||||
|
||||
if name == sym::simd_from_exposed_addr {
|
||||
require_simd!(ret_ty, "return");
|
||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
require!(
|
||||
in_len == out_len,
|
||||
"expected return type with length {} (same as input type `{}`), \
|
||||
found `{}` with length {}",
|
||||
in_len,
|
||||
in_ty,
|
||||
ret_ty,
|
||||
out_len
|
||||
);
|
||||
|
||||
match in_elem.kind() {
|
||||
ty::Uint(ty::UintTy::Usize) => {}
|
||||
_ => return_error!("expected `usize`, got `{}`", in_elem),
|
||||
}
|
||||
match out_elem.kind() {
|
||||
ty::RawPtr(_) => {}
|
||||
_ => return_error!("expected pointer, got `{}`", out_elem),
|
||||
}
|
||||
|
||||
return Ok(bx.inttoptr(args[0].immediate(), llret_ty));
|
||||
}
|
||||
|
||||
if name == sym::simd_cast || name == sym::simd_as {
|
||||
require_simd!(ret_ty, "return");
|
||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
|
@ -1275,9 +1275,11 @@ symbols! {
|
||||
simd_as,
|
||||
simd_bitmask,
|
||||
simd_cast,
|
||||
simd_cast_ptr,
|
||||
simd_ceil,
|
||||
simd_div,
|
||||
simd_eq,
|
||||
simd_expose_addr,
|
||||
simd_extract,
|
||||
simd_fabs,
|
||||
simd_fcos,
|
||||
@ -1293,6 +1295,7 @@ symbols! {
|
||||
simd_fmin,
|
||||
simd_fpow,
|
||||
simd_fpowi,
|
||||
simd_from_exposed_addr,
|
||||
simd_fsin,
|
||||
simd_fsqrt,
|
||||
simd_gather,
|
||||
|
@ -461,7 +461,11 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
|
||||
sym::simd_scatter => (3, vec![param(0), param(1), param(2)], tcx.mk_unit()),
|
||||
sym::simd_insert => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
|
||||
sym::simd_extract => (2, vec![param(0), tcx.types.u32], param(1)),
|
||||
sym::simd_cast | sym::simd_as => (2, vec![param(0)], param(1)),
|
||||
sym::simd_cast
|
||||
| sym::simd_as
|
||||
| sym::simd_cast_ptr
|
||||
| sym::simd_expose_addr
|
||||
| sym::simd_from_exposed_addr => (2, vec![param(0)], param(1)),
|
||||
sym::simd_bitmask => (2, vec![param(0)], param(1)),
|
||||
sym::simd_select | sym::simd_select_bitmask => {
|
||||
(2, vec![param(0), param(1), param(1)], param(1))
|
||||
|
33
src/test/ui/simd/intrinsic/ptr-cast.rs
Normal file
33
src/test/ui/simd/intrinsic/ptr-cast.rs
Normal file
@ -0,0 +1,33 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(repr_simd, platform_intrinsics)]
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_cast_ptr<T, U>(x: T) -> U;
|
||||
fn simd_expose_addr<T, U>(x: T) -> U;
|
||||
fn simd_from_exposed_addr<T, U>(x: T) -> U;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(simd)]
|
||||
struct V<T>([T; 2]);
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let mut foo = 4i8;
|
||||
let ptr = &mut foo as *mut i8;
|
||||
|
||||
let ptrs = V::<*mut i8>([ptr, core::ptr::null_mut()]);
|
||||
|
||||
// change constness and type
|
||||
let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs);
|
||||
|
||||
let exposed_addr: V<usize> = simd_expose_addr(const_ptrs);
|
||||
|
||||
let from_exposed_addr: V<*mut i8> = simd_from_exposed_addr(exposed_addr);
|
||||
|
||||
assert!(const_ptrs.0 == [ptr as *const u8, core::ptr::null()]);
|
||||
assert!(exposed_addr.0 == [ptr as usize, 0]);
|
||||
assert!(from_exposed_addr.0 == ptrs.0);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user