Rollup merge of #98441 - calebzulawski:simd_as, r=oli-obk
Implement simd_as for pointers Expands `simd_as` (and `simd_cast`) to handle pointer-to-pointer, pointer-to-integer, and integer-to-pointer conversions. cc ``@programmerjake`` ``@thomcc``
This commit is contained in:
commit
cbd561d41f
4 changed files with 132 additions and 1 deletions
|
@ -1705,6 +1705,97 @@ 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(p) => {
|
||||
let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
|
||||
});
|
||||
assert!(!check_sized); // we are in codegen, so we shouldn't see these types
|
||||
require!(metadata.is_unit(), "cannot cast fat pointer `{}`", in_elem)
|
||||
}
|
||||
_ => return_error!("expected pointer, got `{}`", in_elem),
|
||||
}
|
||||
match out_elem.kind() {
|
||||
ty::RawPtr(p) => {
|
||||
let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
|
||||
});
|
||||
assert!(!check_sized); // we are in codegen, so we shouldn't see these types
|
||||
require!(metadata.is_unit(), "cannot cast to fat pointer `{}`", out_elem)
|
||||
}
|
||||
_ => 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());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue