Allow simd_shuffle to accept vectors of any length
This commit is contained in:
parent
b69fe57261
commit
1b3fe755ea
12 changed files with 125 additions and 33 deletions
|
|
@ -918,12 +918,29 @@ fn generic_simd_intrinsic(
|
|||
}
|
||||
|
||||
if let Some(stripped) = name_str.strip_prefix("simd_shuffle") {
|
||||
let n: u64 = stripped.parse().unwrap_or_else(|_| {
|
||||
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
|
||||
});
|
||||
// If this intrinsic is the older "simd_shuffleN" form, simply parse the integer.
|
||||
// If there is no suffix, use the index array length.
|
||||
let n: u64 = if stripped.is_empty() {
|
||||
// Make sure this is actually an array, since typeck only checks the length-suffixed
|
||||
// version of this intrinsic.
|
||||
match args[2].layout.ty.kind() {
|
||||
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
|
||||
len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| {
|
||||
span_bug!(span, "could not evaluate shuffle index array length")
|
||||
})
|
||||
}
|
||||
_ => return_error!(
|
||||
"simd_shuffle index must be an array of `u32`, got `{}`",
|
||||
args[2].layout.ty
|
||||
),
|
||||
}
|
||||
} else {
|
||||
stripped.parse().unwrap_or_else(|_| {
|
||||
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
|
||||
})
|
||||
};
|
||||
|
||||
require_simd!(ret_ty, "return");
|
||||
|
||||
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
||||
require!(
|
||||
out_len == n,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
The length of the platform-intrinsic function `simd_shuffle` wasn't specified.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0439
|
||||
```ignore (no longer emitted)
|
||||
#![feature(platform_intrinsics)]
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
|
|
|
|||
|
|
@ -1210,6 +1210,7 @@ symbols! {
|
|||
simd_select_bitmask,
|
||||
simd_shl,
|
||||
simd_shr,
|
||||
simd_shuffle,
|
||||
simd_sub,
|
||||
simd_trunc,
|
||||
simd_xor,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//! intrinsics that the compiler exposes.
|
||||
|
||||
use crate::errors::{
|
||||
SimdShuffleMissingLength, UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
|
||||
UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
|
||||
WrongNumberOfGenericArgumentsToIntrinsic,
|
||||
};
|
||||
use crate::require_same_types;
|
||||
|
|
@ -468,6 +468,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
|
|||
| sym::simd_reduce_max
|
||||
| sym::simd_reduce_min_nanless
|
||||
| sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)),
|
||||
sym::simd_shuffle => (3, vec![param(0), param(0), param(1)], param(2)),
|
||||
name if name.as_str().starts_with("simd_shuffle") => {
|
||||
match name.as_str()["simd_shuffle".len()..].parse() {
|
||||
Ok(n) => {
|
||||
|
|
@ -475,7 +476,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
|
|||
(2, params, param(1))
|
||||
}
|
||||
Err(_) => {
|
||||
tcx.sess.emit_err(SimdShuffleMissingLength { span: it.span, name });
|
||||
let msg =
|
||||
format!("unrecognized platform-specific intrinsic function: `{}`", name);
|
||||
tcx.sess.struct_span_err(it.span, &msg).emit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,14 +121,6 @@ pub struct AssocTypeBindingNotAllowed {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error = "E0439"]
|
||||
pub struct SimdShuffleMissingLength {
|
||||
#[message = "invalid `simd_shuffle`, needs length: `{name}`"]
|
||||
pub span: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error = "E0436"]
|
||||
pub struct FunctionalRecordUpdateOnNonStruct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue