mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Allow simd_shuffle to accept vectors of any length
This commit is contained in:
parent
b69fe57261
commit
1b3fe755ea
@ -918,12 +918,29 @@ fn generic_simd_intrinsic(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(stripped) = name_str.strip_prefix("simd_shuffle") {
|
if let Some(stripped) = name_str.strip_prefix("simd_shuffle") {
|
||||||
let n: u64 = stripped.parse().unwrap_or_else(|_| {
|
// If this intrinsic is the older "simd_shuffleN" form, simply parse the integer.
|
||||||
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
|
// 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");
|
require_simd!(ret_ty, "return");
|
||||||
|
|
||||||
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
||||||
require!(
|
require!(
|
||||||
out_len == n,
|
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.
|
The length of the platform-intrinsic function `simd_shuffle` wasn't specified.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0439
|
```ignore (no longer emitted)
|
||||||
#![feature(platform_intrinsics)]
|
#![feature(platform_intrinsics)]
|
||||||
|
|
||||||
extern "platform-intrinsic" {
|
extern "platform-intrinsic" {
|
||||||
|
@ -1210,6 +1210,7 @@ symbols! {
|
|||||||
simd_select_bitmask,
|
simd_select_bitmask,
|
||||||
simd_shl,
|
simd_shl,
|
||||||
simd_shr,
|
simd_shr,
|
||||||
|
simd_shuffle,
|
||||||
simd_sub,
|
simd_sub,
|
||||||
simd_trunc,
|
simd_trunc,
|
||||||
simd_xor,
|
simd_xor,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//! intrinsics that the compiler exposes.
|
//! intrinsics that the compiler exposes.
|
||||||
|
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
SimdShuffleMissingLength, UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
|
UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
|
||||||
WrongNumberOfGenericArgumentsToIntrinsic,
|
WrongNumberOfGenericArgumentsToIntrinsic,
|
||||||
};
|
};
|
||||||
use crate::require_same_types;
|
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_max
|
||||||
| sym::simd_reduce_min_nanless
|
| sym::simd_reduce_min_nanless
|
||||||
| sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)),
|
| 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") => {
|
name if name.as_str().starts_with("simd_shuffle") => {
|
||||||
match name.as_str()["simd_shuffle".len()..].parse() {
|
match name.as_str()["simd_shuffle".len()..].parse() {
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
@ -475,7 +476,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
|
|||||||
(2, params, param(1))
|
(2, params, param(1))
|
||||||
}
|
}
|
||||||
Err(_) => {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,14 +121,6 @@ pub struct AssocTypeBindingNotAllowed {
|
|||||||
pub span: Span,
|
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)]
|
#[derive(SessionDiagnostic)]
|
||||||
#[error = "E0436"]
|
#[error = "E0436"]
|
||||||
pub struct FunctionalRecordUpdateOnNonStruct {
|
pub struct FunctionalRecordUpdateOnNonStruct {
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
#![feature(platform_intrinsics)]
|
|
||||||
|
|
||||||
extern "platform-intrinsic" {
|
|
||||||
fn simd_shuffle<A,B>(a: A, b: A, c: [u32; 8]) -> B; //~ ERROR E0439
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main () {
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
error[E0439]: invalid `simd_shuffle`, needs length: `simd_shuffle`
|
|
||||||
--> $DIR/E0439.rs:4:5
|
|
||||||
|
|
|
||||||
LL | fn simd_shuffle<A,B>(a: A, b: A, c: [u32; 8]) -> B;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0439`.
|
|
33
src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs
Normal file
33
src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// build-fail
|
||||||
|
|
||||||
|
// Test that the simd_shuffle intrinsic produces ok-ish error
|
||||||
|
// messages when misused.
|
||||||
|
|
||||||
|
#![feature(repr_simd, platform_intrinsics)]
|
||||||
|
|
||||||
|
#[repr(simd)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Simd<T, const N: usize>([T; N]);
|
||||||
|
|
||||||
|
extern "platform-intrinsic" {
|
||||||
|
fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
const I: [u32; 2] = [0; 2];
|
||||||
|
const I2: [f32; 2] = [0.; 2];
|
||||||
|
let v = Simd::<u32, 4>([0; 4]);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let _: Simd<u32, 2> = simd_shuffle(v, v, I);
|
||||||
|
|
||||||
|
let _: Simd<u32, 4> = simd_shuffle(v, v, I);
|
||||||
|
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
|
||||||
|
|
||||||
|
let _: Simd<f32, 2> = simd_shuffle(v, v, I);
|
||||||
|
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
|
||||||
|
|
||||||
|
let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
|
||||||
|
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4_usize>` with length 4
|
||||||
|
--> $DIR/simd-intrinsic-generic-shuffle.rs:24:31
|
||||||
|
|
|
||||||
|
LL | let _: Simd<u32, 4> = simd_shuffle(v, v, I);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd<u32, 4_usize>`), found `Simd<f32, 2_usize>` with element type `f32`
|
||||||
|
--> $DIR/simd-intrinsic-generic-shuffle.rs:27:31
|
||||||
|
|
|
||||||
|
LL | let _: Simd<f32, 2> = simd_shuffle(v, v, I);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be an array of `u32`, got `[f32; 2]`
|
||||||
|
--> $DIR/simd-intrinsic-generic-shuffle.rs:30:31
|
||||||
|
|
|
||||||
|
LL | let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0511`.
|
@ -188,4 +188,14 @@ fn main() {
|
|||||||
48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
|
48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
|
||||||
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
|
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
|
||||||
16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
|
16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
|
||||||
|
|
||||||
|
extern "platform-intrinsic" {
|
||||||
|
fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
|
||||||
|
}
|
||||||
|
let v = u8x2(0, 0);
|
||||||
|
const I: [u32; 2] = [4, 4];
|
||||||
|
unsafe {
|
||||||
|
let _: u8x2 = simd_shuffle(v, v, I);
|
||||||
|
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,12 @@ LL | | 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
|
|||||||
|
|
|
|
||||||
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 4)
|
||||||
|
--> $DIR/shuffle-not-out-of-bounds.rs:198:23
|
||||||
|
|
|
||||||
|
LL | let _: u8x2 = simd_shuffle(v, v, I);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0511`.
|
For more information about this error, try `rustc --explain E0511`.
|
||||||
|
24
src/test/ui/simd/shuffle.rs
Normal file
24
src/test/ui/simd/shuffle.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//run-pass
|
||||||
|
#![feature(repr_simd, platform_intrinsics)]
|
||||||
|
|
||||||
|
extern "platform-intrinsic" {
|
||||||
|
fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(simd)]
|
||||||
|
struct Simd<T, const N: usize>([T; N]);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
const I1: [u32; 4] = [0, 2, 4, 6];
|
||||||
|
const I2: [u32; 2] = [1, 5];
|
||||||
|
let a = Simd::<u8, 4>([0, 1, 2, 3]);
|
||||||
|
let b = Simd::<u8, 4>([4, 5, 6, 7]);
|
||||||
|
unsafe {
|
||||||
|
let x: Simd<u8, 4> = simd_shuffle(a, b, I1);
|
||||||
|
assert_eq!(x.0, [0, 2, 4, 6]);
|
||||||
|
|
||||||
|
let y: Simd<u8, 2> = simd_shuffle(a, b, I2);
|
||||||
|
assert_eq!(y.0, [1, 5]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user