diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-09-17 15:31:07 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-17 15:31:07 +0530 |
| commit | cbd561d41f61201decae3adb45fe827d30aa96ec (patch) | |
| tree | 61f8f4dce1a826fd0cb071559ab21f7fa925c8b8 /compiler/rustc_codegen_llvm | |
| parent | 3ad81e0dd854d0edaeea7429fba6c2255c6a27ef (diff) | |
| parent | 3f2ce0624dfed866f758521b225e26c00b3250d8 (diff) | |
| download | rust-cbd561d41f61201decae3adb45fe827d30aa96ec.tar.gz rust-cbd561d41f61201decae3adb45fe827d30aa96ec.zip | |
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``
Diffstat (limited to 'compiler/rustc_codegen_llvm')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/intrinsic.rs | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 3d789904707..a640de42a6a 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -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()); |
