1
Fork 0

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:
Dylan DPC 2022-09-17 15:31:07 +05:30 committed by GitHub
commit cbd561d41f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 132 additions and 1 deletions

View file

@ -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());