Skip to content

Commit e675073

Browse files
authored
Rollup merge of #88855 - calebzulawski:feature/simd_shuffle, r=nagisa
Allow simd_shuffle to accept vectors of any length cc ``@rust-lang/project-portable-simd`` ``@workingjubilee``
2 parents ebd31f5 + 4a4ca94 commit e675073

File tree

14 files changed

+171
-35
lines changed

14 files changed

+171
-35
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -918,12 +918,29 @@ fn generic_simd_intrinsic(
918918
}
919919

920920
if let Some(stripped) = name_str.strip_prefix("simd_shuffle") {
921-
let n: u64 = stripped.parse().unwrap_or_else(|_| {
922-
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
923-
});
921+
// If this intrinsic is the older "simd_shuffleN" form, simply parse the integer.
922+
// If there is no suffix, use the index array length.
923+
let n: u64 = if stripped.is_empty() {
924+
// Make sure this is actually an array, since typeck only checks the length-suffixed
925+
// version of this intrinsic.
926+
match args[2].layout.ty.kind() {
927+
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
928+
len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| {
929+
span_bug!(span, "could not evaluate shuffle index array length")
930+
})
931+
}
932+
_ => return_error!(
933+
"simd_shuffle index must be an array of `u32`, got `{}`",
934+
args[2].layout.ty
935+
),
936+
}
937+
} else {
938+
stripped.parse().unwrap_or_else(|_| {
939+
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
940+
})
941+
};
924942

925943
require_simd!(ret_ty, "return");
926-
927944
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
928945
require!(
929946
out_len == n,

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
665665
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
666666
if let mir::Operand::Constant(constant) = arg {
667667
let c = self.eval_mir_constant(constant);
668-
let (llval, ty) =
669-
self.simd_shuffle_indices(&bx, constant.span, constant.ty(), c);
668+
let (llval, ty) = self.simd_shuffle_indices(
669+
&bx,
670+
constant.span,
671+
self.monomorphize(constant.ty()),
672+
c,
673+
);
670674
return OperandRef {
671675
val: Immediate(llval),
672676
layout: bx.layout_of(ty),

compiler/rustc_error_codes/src/error_codes/E0439.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
#### Note: this error code is no longer emitted by the compiler.
2+
13
The length of the platform-intrinsic function `simd_shuffle` wasn't specified.
24

35
Erroneous code example:
46

5-
```compile_fail,E0439
7+
```ignore (no longer emitted)
68
#![feature(platform_intrinsics)]
79
810
extern "platform-intrinsic" {

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,7 @@ symbols! {
12121212
simd_select_bitmask,
12131213
simd_shl,
12141214
simd_shr,
1215+
simd_shuffle,
12151216
simd_sub,
12161217
simd_trunc,
12171218
simd_xor,

compiler/rustc_typeck/src/check/intrinsic.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! intrinsics that the compiler exposes.
33
44
use crate::errors::{
5-
SimdShuffleMissingLength, UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
5+
UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
66
WrongNumberOfGenericArgumentsToIntrinsic,
77
};
88
use crate::require_same_types;
@@ -468,14 +468,17 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
468468
| sym::simd_reduce_max
469469
| sym::simd_reduce_min_nanless
470470
| sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)),
471+
sym::simd_shuffle => (3, vec![param(0), param(0), param(1)], param(2)),
471472
name if name.as_str().starts_with("simd_shuffle") => {
472473
match name.as_str()["simd_shuffle".len()..].parse() {
473474
Ok(n) => {
474475
let params = vec![param(0), param(0), tcx.mk_array(tcx.types.u32, n)];
475476
(2, params, param(1))
476477
}
477478
Err(_) => {
478-
tcx.sess.emit_err(SimdShuffleMissingLength { span: it.span, name });
479+
let msg =
480+
format!("unrecognized platform-specific intrinsic function: `{}`", name);
481+
tcx.sess.struct_span_err(it.span, &msg).emit();
479482
return;
480483
}
481484
}

compiler/rustc_typeck/src/errors.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,6 @@ pub struct AssocTypeBindingNotAllowed {
121121
pub span: Span,
122122
}
123123

124-
#[derive(SessionDiagnostic)]
125-
#[error = "E0439"]
126-
pub struct SimdShuffleMissingLength {
127-
#[message = "invalid `simd_shuffle`, needs length: `{name}`"]
128-
pub span: Span,
129-
pub name: Symbol,
130-
}
131-
132124
#[derive(SessionDiagnostic)]
133125
#[error = "E0436"]
134126
pub struct FunctionalRecordUpdateOnNonStruct {

src/test/ui/error-codes/E0439.rs

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/test/ui/error-codes/E0439.stderr

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// build-fail
2+
3+
// Test that the simd_shuffle intrinsic produces ok-ish error
4+
// messages when misused.
5+
6+
#![feature(repr_simd, platform_intrinsics)]
7+
8+
#[repr(simd)]
9+
#[derive(Copy, Clone)]
10+
pub struct Simd<T, const N: usize>([T; N]);
11+
12+
extern "platform-intrinsic" {
13+
fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
14+
}
15+
16+
fn main() {
17+
const I: [u32; 2] = [0; 2];
18+
const I2: [f32; 2] = [0.; 2];
19+
let v = Simd::<u32, 4>([0; 4]);
20+
21+
unsafe {
22+
let _: Simd<u32, 2> = simd_shuffle(v, v, I);
23+
24+
let _: Simd<u32, 4> = simd_shuffle(v, v, I);
25+
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
26+
27+
let _: Simd<f32, 2> = simd_shuffle(v, v, I);
28+
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
29+
30+
let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
31+
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
32+
}
33+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4_usize>` with length 4
2+
--> $DIR/simd-intrinsic-generic-shuffle.rs:24:31
3+
|
4+
LL | let _: Simd<u32, 4> = simd_shuffle(v, v, I);
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
7+
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`
8+
--> $DIR/simd-intrinsic-generic-shuffle.rs:27:31
9+
|
10+
LL | let _: Simd<f32, 2> = simd_shuffle(v, v, I);
11+
| ^^^^^^^^^^^^^^^^^^^^^
12+
13+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be an array of `u32`, got `[f32; 2]`
14+
--> $DIR/simd-intrinsic-generic-shuffle.rs:30:31
15+
|
16+
LL | let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
17+
| ^^^^^^^^^^^^^^^^^^^^^^
18+
19+
error: aborting due to 3 previous errors
20+
21+
For more information about this error, try `rustc --explain E0511`.

0 commit comments

Comments
 (0)