Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6390091

Browse files
committedSep 14, 2024·
Auto merge of rust-lang#130268 - RalfJung:simd-shuffle-idx-vector, r=compiler-errors
simd_shuffle: require index argument to be a vector Remove some codegen hacks by forcing the SIMD shuffle `index` argument to be a vector, which means (thanks to rust-lang#128537) that it will automatically be passed as an immediate in LLVM. The only special-casing we still have is for the extra sanity-checks we add that ensure that the indices are all in-bounds. (And the GCC backend needs to do a bunch of work since the Rust intrinsic is modeled after what LLVM expects, which seems to be quite different from what GCC expects.) Fixes rust-lang#128738, see that issue for more context.
2 parents f9567d0 + 7a1b5e5 commit 6390091

File tree

24 files changed

+224
-301
lines changed

24 files changed

+224
-301
lines changed
 

‎compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

+13-27
Original file line numberDiff line numberDiff line change
@@ -180,34 +180,20 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
180180
return;
181181
}
182182

183-
// Make sure this is actually an array, since typeck only checks the length-suffixed
184-
// version of this intrinsic.
183+
// Make sure this is actually a SIMD vector.
185184
let idx_ty = fx.monomorphize(idx.node.ty(fx.mir, fx.tcx));
186-
let n: u16 = match idx_ty.kind() {
187-
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => len
188-
.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
189-
.unwrap_or_else(|| {
190-
span_bug!(span, "could not evaluate shuffle index array length")
191-
})
192-
.try_into()
193-
.unwrap(),
194-
_ if idx_ty.is_simd()
195-
&& matches!(
196-
idx_ty.simd_size_and_type(fx.tcx).1.kind(),
197-
ty::Uint(ty::UintTy::U32)
198-
) =>
199-
{
200-
idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap()
201-
}
202-
_ => {
203-
fx.tcx.dcx().span_err(
204-
span,
205-
format!("simd_shuffle index must be an array of `u32`, got `{}`", idx_ty),
206-
);
207-
// Prevent verifier error
208-
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
209-
return;
210-
}
185+
let n: u16 = if idx_ty.is_simd()
186+
&& matches!(idx_ty.simd_size_and_type(fx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
187+
{
188+
idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap()
189+
} else {
190+
fx.tcx.dcx().span_err(
191+
span,
192+
format!("simd_shuffle index must be a SIMD vector of `u32`, got `{}`", idx_ty),
193+
);
194+
// Prevent verifier error
195+
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
196+
return;
211197
};
212198

213199
assert_eq!(x.layout(), y.layout());

‎compiler/rustc_codegen_gcc/src/builder.rs

+12-27
Original file line numberDiff line numberDiff line change
@@ -1939,33 +1939,18 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
19391939
self.int_type
19401940
};
19411941

1942-
let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() {
1943-
let mask_num_units = vector_type.get_num_units();
1944-
let mut mask_elements = vec![];
1945-
for i in 0..mask_num_units {
1946-
let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
1947-
mask_elements.push(self.context.new_cast(
1948-
self.location,
1949-
self.extract_element(mask, index).to_rvalue(),
1950-
mask_element_type,
1951-
));
1952-
}
1953-
mask_elements
1954-
} else {
1955-
let struct_type = mask.get_type().is_struct().expect("mask should be of struct type");
1956-
let mask_num_units = struct_type.get_field_count();
1957-
let mut mask_elements = vec![];
1958-
for i in 0..mask_num_units {
1959-
let field = struct_type.get_field(i as i32);
1960-
mask_elements.push(self.context.new_cast(
1961-
self.location,
1962-
mask.access_field(self.location, field).to_rvalue(),
1963-
mask_element_type,
1964-
));
1965-
}
1966-
mask_elements
1967-
};
1968-
let mask_num_units = mask_elements.len();
1942+
let vector_type =
1943+
mask.get_type().dyncast_vector().expect("simd_shuffle mask should be of vector type");
1944+
let mask_num_units = vector_type.get_num_units();
1945+
let mut mask_elements = vec![];
1946+
for i in 0..mask_num_units {
1947+
let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
1948+
mask_elements.push(self.context.new_cast(
1949+
self.location,
1950+
self.extract_element(mask, index).to_rvalue(),
1951+
mask_element_type,
1952+
));
1953+
}
19691954

19701955
// NOTE: the mask needs to be the same length as the input vectors, so add the missing
19711956
// elements in the mask if needed.

‎compiler/rustc_codegen_gcc/src/intrinsic/simd.rs

+7-18
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
1414
#[cfg(feature = "master")]
1515
use rustc_hir as hir;
1616
use rustc_middle::mir::BinOp;
17-
use rustc_middle::span_bug;
1817
use rustc_middle::ty::layout::HasTyCtxt;
1918
use rustc_middle::ty::{self, Ty};
2019
use rustc_span::{sym, Span, Symbol};
@@ -353,24 +352,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
353352
}
354353

355354
if name == sym::simd_shuffle {
356-
// Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
357-
// version of this intrinsic.
355+
// Make sure this is actually a SIMD vector.
358356
let idx_ty = args[2].layout.ty;
359-
let n: u64 = match idx_ty.kind() {
360-
ty::Array(ty, len) if matches!(*ty.kind(), ty::Uint(ty::UintTy::U32)) => {
361-
len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
362-
|| span_bug!(span, "could not evaluate shuffle index array length"),
363-
)
364-
}
365-
_ if idx_ty.is_simd()
366-
&& matches!(
367-
idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(),
368-
ty::Uint(ty::UintTy::U32)
369-
) =>
370-
{
371-
idx_ty.simd_size_and_type(bx.cx.tcx).0
372-
}
373-
_ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }),
357+
let n: u64 = if idx_ty.is_simd()
358+
&& matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
359+
{
360+
idx_ty.simd_size_and_type(bx.cx.tcx).0
361+
} else {
362+
return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty })
374363
};
375364
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
376365

‎compiler/rustc_codegen_llvm/src/intrinsic.rs

+24-48
Original file line numberDiff line numberDiff line change
@@ -1290,24 +1290,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
12901290
}
12911291

12921292
if name == sym::simd_shuffle {
1293-
// Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
1294-
// version of this intrinsic.
1293+
// Make sure this is actually a SIMD vector.
12951294
let idx_ty = args[2].layout.ty;
1296-
let n: u64 = match idx_ty.kind() {
1297-
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
1298-
len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
1299-
|| span_bug!(span, "could not evaluate shuffle index array length"),
1300-
)
1301-
}
1302-
_ if idx_ty.is_simd()
1303-
&& matches!(
1304-
idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(),
1305-
ty::Uint(ty::UintTy::U32)
1306-
) =>
1307-
{
1308-
idx_ty.simd_size_and_type(bx.cx.tcx).0
1309-
}
1310-
_ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }),
1295+
let n: u64 = if idx_ty.is_simd()
1296+
&& matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
1297+
{
1298+
idx_ty.simd_size_and_type(bx.cx.tcx).0
1299+
} else {
1300+
return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty })
13111301
};
13121302

13131303
let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
@@ -1322,38 +1312,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
13221312

13231313
let total_len = u128::from(in_len) * 2;
13241314

1325-
let vector = args[2].immediate();
1326-
1327-
let indices: Option<Vec<_>> = (0..n)
1328-
.map(|i| {
1329-
let arg_idx = i;
1330-
let val = bx.const_get_elt(vector, i as u64);
1331-
match bx.const_to_opt_u128(val, true) {
1332-
None => {
1333-
bug!("typeck should have already ensured that these are const")
1334-
}
1335-
Some(idx) if idx >= total_len => {
1336-
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
1337-
span,
1338-
name,
1339-
arg_idx,
1340-
total_len,
1341-
});
1342-
None
1343-
}
1344-
Some(idx) => Some(bx.const_i32(idx as i32)),
1345-
}
1346-
})
1347-
.collect();
1348-
let Some(indices) = indices else {
1349-
return Ok(bx.const_null(llret_ty));
1350-
};
1315+
// Check that the indices are in-bounds.
1316+
let indices = args[2].immediate();
1317+
for i in 0..n {
1318+
let val = bx.const_get_elt(indices, i as u64);
1319+
let idx = bx
1320+
.const_to_opt_u128(val, true)
1321+
.unwrap_or_else(|| bug!("typeck should have already ensured that these are const"));
1322+
if idx >= total_len {
1323+
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
1324+
span,
1325+
name,
1326+
arg_idx: i,
1327+
total_len,
1328+
});
1329+
}
1330+
}
13511331

1352-
return Ok(bx.shuffle_vector(
1353-
args[0].immediate(),
1354-
args[1].immediate(),
1355-
bx.const_vector(&indices),
1356-
));
1332+
return Ok(bx.shuffle_vector(args[0].immediate(), args[1].immediate(), indices));
13571333
}
13581334

13591335
if name == sym::simd_insert {

‎compiler/rustc_codegen_ssa/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `
132132
133133
codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}`
134134
135-
codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
135+
codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `{$ty}`
136136
137137
codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`
138138

‎compiler/rustc_codegen_ssa/src/mir/block.rs

+2-26
Original file line numberDiff line numberDiff line change
@@ -915,32 +915,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
915915
}
916916
};
917917

918-
let args: Vec<_> = args
919-
.iter()
920-
.enumerate()
921-
.map(|(i, arg)| {
922-
// The indices passed to simd_shuffle in the
923-
// third argument must be constant. This is
924-
// checked by the type-checker.
925-
if i == 2 && intrinsic.name == sym::simd_shuffle {
926-
// FIXME: the simd_shuffle argument is actually an array,
927-
// not a vector, so we need this special hack to make sure
928-
// it is passed as an immediate. We should pass the
929-
// shuffle indices as a vector instead to avoid this hack.
930-
if let mir::Operand::Constant(constant) = &arg.node {
931-
let (llval, ty) = self.immediate_const_vector(bx, constant);
932-
return OperandRef {
933-
val: Immediate(llval),
934-
layout: bx.layout_of(ty),
935-
};
936-
} else {
937-
span_bug!(span, "shuffle indices must be constant");
938-
}
939-
}
940-
941-
self.codegen_operand(bx, &arg.node)
942-
})
943-
.collect();
918+
let args: Vec<_> =
919+
args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect();
944920

945921
if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) {
946922
let location = self

‎compiler/rustc_codegen_ssa/src/mir/constant.rs

+11-24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_middle::mir::interpret::ErrorHandled;
22
use rustc_middle::ty::layout::HasTyCtxt;
3-
use rustc_middle::ty::{self, Ty, ValTree};
3+
use rustc_middle::ty::{self, Ty};
44
use rustc_middle::{bug, mir, span_bug};
55
use rustc_target::abi::Abi;
66

@@ -66,35 +66,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6666
constant: &mir::ConstOperand<'tcx>,
6767
) -> (Bx::Value, Ty<'tcx>) {
6868
let ty = self.monomorphize(constant.ty());
69-
let ty_is_simd = ty.is_simd();
70-
// FIXME: ideally we'd assert that this is a SIMD type, but simd_shuffle
71-
// in its current form relies on a regular array being passed as an
72-
// immediate argument. This hack can be removed once that is fixed.
73-
let field_ty = if ty_is_simd {
74-
ty.simd_size_and_type(bx.tcx()).1
75-
} else {
76-
ty.builtin_index().unwrap()
77-
};
69+
assert!(ty.is_simd());
70+
let field_ty = ty.simd_size_and_type(bx.tcx()).1;
7871

7972
let val = self
8073
.eval_unevaluated_mir_constant_to_valtree(constant)
8174
.ok()
8275
.map(|x| x.ok())
8376
.flatten()
8477
.map(|val| {
85-
// Depending on whether this is a SIMD type with an array field
86-
// or a type with many fields (one for each elements), the valtree
87-
// is either a single branch with N children, or a root node
88-
// with exactly one child which then in turn has many children.
89-
// So we look at the first child to determine whether it is a
90-
// leaf or whether we have to go one more layer down.
91-
let branch_or_leaf = val.unwrap_branch();
92-
let first = branch_or_leaf.get(0).unwrap();
93-
let field_iter = match first {
94-
ValTree::Branch(_) => first.unwrap_branch().iter(),
95-
ValTree::Leaf(_) => branch_or_leaf.iter(),
96-
};
97-
let values: Vec<_> = field_iter
78+
// A SIMD type has a single field, which is an array.
79+
let fields = val.unwrap_branch();
80+
assert_eq!(fields.len(), 1);
81+
let array = fields[0].unwrap_branch();
82+
// Iterate over the array elements to obtain the values in the vector.
83+
let values: Vec<_> = array
84+
.iter()
9885
.map(|field| {
9986
if let Some(prim) = field.try_to_scalar() {
10087
let layout = bx.layout_of(field_ty);
@@ -107,7 +94,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10794
}
10895
})
10996
.collect();
110-
if ty_is_simd { bx.const_vector(&values) } else { bx.const_struct(&values, false) }
97+
bx.const_vector(&values)
11198
})
11299
.unwrap_or_else(|| {
113100
bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });

‎library/core/src/intrinsics/simd.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ extern "rust-intrinsic" {
232232
///
233233
/// `T` must be a vector.
234234
///
235-
/// `U` must be a **const** array or vector of `u32`s. This means it must either refer to a named
235+
/// `U` must be a **const** vector of `u32`s. This means it must either refer to a named
236236
/// const or be given as an inline const expression (`const { ... }`).
237237
///
238238
/// `V` must be a vector with the same element type as `T` and the same length as `U`.

‎library/portable-simd/crates/core_simd/src/swizzle.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub trait Swizzle<const N: usize> {
8585
LaneCount<N>: SupportedLaneCount,
8686
LaneCount<M>: SupportedLaneCount,
8787
{
88-
// Safety: `vector` is a vector, and the index is a const array of u32.
88+
// Safety: `vector` is a vector, and the index is a const vector of u32.
8989
unsafe {
9090
core::intrinsics::simd::simd_shuffle(
9191
vector,
@@ -103,7 +103,11 @@ pub trait Swizzle<const N: usize> {
103103
output[i] = index as u32;
104104
i += 1;
105105
}
106-
output
106+
107+
// The index list needs to be returned as a vector.
108+
#[repr(simd)]
109+
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
110+
SimdShuffleIdx(output)
107111
},
108112
)
109113
}
@@ -121,7 +125,7 @@ pub trait Swizzle<const N: usize> {
121125
LaneCount<N>: SupportedLaneCount,
122126
LaneCount<M>: SupportedLaneCount,
123127
{
124-
// Safety: `first` and `second` are vectors, and the index is a const array of u32.
128+
// Safety: `first` and `second` are vectors, and the index is a const vector of u32.
125129
unsafe {
126130
core::intrinsics::simd::simd_shuffle(
127131
first,
@@ -139,7 +143,11 @@ pub trait Swizzle<const N: usize> {
139143
output[i] = index as u32;
140144
i += 1;
141145
}
142-
output
146+
147+
// The index list needs to be returned as a vector.
148+
#[repr(simd)]
149+
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
150+
SimdShuffleIdx(output)
143151
},
144152
)
145153
}

‎src/tools/miri/src/intrinsics/simd.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -664,15 +664,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
664664
let [left, right, index] = check_arg_count(args)?;
665665
let (left, left_len) = this.project_to_simd(left)?;
666666
let (right, right_len) = this.project_to_simd(right)?;
667+
let (index, index_len) = this.project_to_simd(index)?;
667668
let (dest, dest_len) = this.project_to_simd(dest)?;
668669

669-
// `index` is an array or a SIMD type
670-
let (index, index_len) = match index.layout.ty.kind() {
671-
// FIXME: remove this once `index` must always be a SIMD vector.
672-
ty::Array(..) => (index.clone(), index.len(this)?),
673-
_ => this.project_to_simd(index)?,
674-
};
675-
676670
assert_eq!(left_len, right_len);
677671
assert_eq!(index_len, dest_len);
678672

‎src/tools/miri/tests/pass/intrinsics/portable-simd.rs

-5
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,6 @@ fn simd_intrinsics() {
619619
i32x4::from_array([10, 2, 10, 10])
620620
);
621621
assert_eq!(simd_shuffle_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,);
622-
assert_eq!(simd_shuffle::<_, _, i32x4>(a, b, const { [3u32, 1, 0, 2] }), a,);
623622
assert_eq!(
624623
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([3u32, 1, 0, 2]) }),
625624
a,
@@ -628,10 +627,6 @@ fn simd_intrinsics() {
628627
simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b),
629628
i32x4::from_array([4, 2, 1, 10]),
630629
);
631-
assert_eq!(
632-
simd_shuffle::<_, _, i32x4>(a, b, const { [7u32, 5, 4, 6] }),
633-
i32x4::from_array([4, 2, 1, 10]),
634-
);
635630
assert_eq!(
636631
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([7u32, 5, 4, 6]) }),
637632
i32x4::from_array([4, 2, 1, 10]),

‎tests/incremental/issue-61530.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ extern "rust-intrinsic" {
99
fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
1010
}
1111

12+
#[repr(simd)]
13+
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
14+
1215
fn main() {
1316
unsafe {
14-
const IDX: [u32; 2] = [0, 0];
17+
const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 0]);
1518
let _: I32x2 = simd_shuffle(I32x2([1, 2]), I32x2([3, 4]), IDX);
1619
let _: I32x2 = simd_shuffle(I32x2([1, 2]), I32x2([3, 4]), IDX);
1720
}

‎tests/ui/simd/intrinsic/generic-elements-pass.rs

+32-16
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@ extern "rust-intrinsic" {
2323
fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
2424
}
2525

26+
#[repr(simd)]
27+
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
28+
2629
macro_rules! all_eq {
2730
($a: expr, $b: expr) => {{
2831
let a = $a;
2932
let b = $b;
3033
// type inference works better with the concrete type on the
3134
// left, but humans work better with the expected on the
3235
// right.
33-
assert!(b == a,
34-
"{:?} != {:?}", a, b);
35-
}}
36+
assert!(b == a, "{:?} != {:?}", a, b);
37+
}};
3638
}
3739

3840
fn main() {
@@ -79,20 +81,34 @@ fn main() {
7981
let y4 = i32x4([140, 141, 142, 143]);
8082
let y8 = i32x8([180, 181, 182, 183, 184, 185, 186, 187]);
8183
unsafe {
82-
all_eq!(simd_shuffle(x2, y2, const { [3u32, 0] }), i32x2([121, 20]));
83-
all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2] }), i32x4([121, 20, 21, 120]));
84-
all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2, 1, 2, 3, 0] }),
85-
i32x8([121, 20, 21, 120, 21, 120, 121, 20]));
84+
all_eq!(simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0]) }), i32x2([121, 20]));
85+
all_eq!(
86+
simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0, 1, 2]) }),
87+
i32x4([121, 20, 21, 120])
88+
);
89+
all_eq!(
90+
simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0, 1, 2, 1, 2, 3, 0]) }),
91+
i32x8([121, 20, 21, 120, 21, 120, 121, 20])
92+
);
8693

87-
all_eq!(simd_shuffle(x4, y4, const { [7u32, 2] }), i32x2([143, 42]));
88-
all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0] }), i32x4([143, 42, 141, 40]));
89-
all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0, 3, 6, 4, 1] }),
90-
i32x8([143, 42, 141, 40, 43, 142, 140, 41]));
94+
all_eq!(simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2]) }), i32x2([143, 42]));
95+
all_eq!(
96+
simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2, 5, 0]) }),
97+
i32x4([143, 42, 141, 40])
98+
);
99+
all_eq!(
100+
simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2, 5, 0, 3, 6, 4, 1]) }),
101+
i32x8([143, 42, 141, 40, 43, 142, 140, 41])
102+
);
91103

92-
all_eq!(simd_shuffle(x8, y8, const { [11u32, 5] }), i32x2([183, 85]));
93-
all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0] }), i32x4([183, 85, 187, 80]));
94-
all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0, 3, 8, 12, 1] }),
95-
i32x8([183, 85, 187, 80, 83, 180, 184, 81]));
104+
all_eq!(simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5]) }), i32x2([183, 85]));
105+
all_eq!(
106+
simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5, 15, 0]) }),
107+
i32x4([183, 85, 187, 80])
108+
);
109+
all_eq!(
110+
simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5, 15, 0, 3, 8, 12, 1]) }),
111+
i32x8([183, 85, 187, 80, 83, 180, 184, 81])
112+
);
96113
}
97-
98114
}

‎tests/ui/simd/intrinsic/generic-elements.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ extern "rust-intrinsic" {
3737
fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
3838
}
3939

40+
#[repr(simd)]
41+
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
42+
4043
fn main() {
4144
let x = i32x4([0, 0, 0, 0]);
4245

@@ -48,13 +51,13 @@ fn main() {
4851
simd_extract::<_, f32>(x, 0);
4952
//~^ ERROR expected return type `i32` (element of input `i32x4`), found `f32`
5053

51-
const IDX2: [u32; 2] = [0; 2];
54+
const IDX2: SimdShuffleIdx<2> = SimdShuffleIdx([0; 2]);
5255
simd_shuffle::<i32, _, i32>(0, 0, IDX2);
5356
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
54-
const IDX4: [u32; 4] = [0; 4];
57+
const IDX4: SimdShuffleIdx<4> = SimdShuffleIdx([0; 4]);
5558
simd_shuffle::<i32, _, i32>(0, 0, IDX4);
5659
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
57-
const IDX8: [u32; 8] = [0; 8];
60+
const IDX8: SimdShuffleIdx<8> = SimdShuffleIdx([0; 8]);
5861
simd_shuffle::<i32, _, i32>(0, 0, IDX8);
5962
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
6063

‎tests/ui/simd/intrinsic/generic-elements.stderr

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,125 @@
11
error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32`
2-
--> $DIR/generic-elements.rs:44:9
2+
--> $DIR/generic-elements.rs:47:9
33
|
44
LL | simd_insert(0, 0, 0);
55
| ^^^^^^^^^^^^^^^^^^^^
66

77
error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64`
8-
--> $DIR/generic-elements.rs:46:9
8+
--> $DIR/generic-elements.rs:49:9
99
|
1010
LL | simd_insert(x, 0, 1.0);
1111
| ^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32`
14-
--> $DIR/generic-elements.rs:48:9
14+
--> $DIR/generic-elements.rs:51:9
1515
|
1616
LL | simd_extract::<_, f32>(x, 0);
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
20-
--> $DIR/generic-elements.rs:52:9
20+
--> $DIR/generic-elements.rs:55:9
2121
|
2222
LL | simd_shuffle::<i32, _, i32>(0, 0, IDX2);
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2424

2525
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
26-
--> $DIR/generic-elements.rs:55:9
26+
--> $DIR/generic-elements.rs:58:9
2727
|
2828
LL | simd_shuffle::<i32, _, i32>(0, 0, IDX4);
2929
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3030

3131
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
32-
--> $DIR/generic-elements.rs:58:9
32+
--> $DIR/generic-elements.rs:61:9
3333
|
3434
LL | simd_shuffle::<i32, _, i32>(0, 0, IDX8);
3535
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3636

3737
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
38-
--> $DIR/generic-elements.rs:61:9
38+
--> $DIR/generic-elements.rs:64:9
3939
|
4040
LL | simd_shuffle::<_, _, f32x2>(x, x, IDX2);
4141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4242

4343
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
44-
--> $DIR/generic-elements.rs:63:9
44+
--> $DIR/generic-elements.rs:66:9
4545
|
4646
LL | simd_shuffle::<_, _, f32x4>(x, x, IDX4);
4747
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4848

4949
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
50-
--> $DIR/generic-elements.rs:65:9
50+
--> $DIR/generic-elements.rs:68:9
5151
|
5252
LL | simd_shuffle::<_, _, f32x8>(x, x, IDX8);
5353
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5454

5555
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `i32x8` with length 8
56-
--> $DIR/generic-elements.rs:68:9
56+
--> $DIR/generic-elements.rs:71:9
5757
|
5858
LL | simd_shuffle::<_, _, i32x8>(x, x, IDX2);
5959
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6060

6161
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 4, found `i32x8` with length 8
62-
--> $DIR/generic-elements.rs:70:9
62+
--> $DIR/generic-elements.rs:73:9
6363
|
6464
LL | simd_shuffle::<_, _, i32x8>(x, x, IDX4);
6565
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6666

6767
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 8, found `i32x2` with length 2
68-
--> $DIR/generic-elements.rs:72:9
68+
--> $DIR/generic-elements.rs:75:9
6969
|
7070
LL | simd_shuffle::<_, _, i32x2>(x, x, IDX8);
7171
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7272

7373
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
74-
--> $DIR/generic-elements.rs:76:9
74+
--> $DIR/generic-elements.rs:79:9
7575
|
7676
LL | simd_shuffle_generic::<i32, i32, I2>(0, 0);
7777
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7878

7979
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
80-
--> $DIR/generic-elements.rs:79:9
80+
--> $DIR/generic-elements.rs:82:9
8181
|
8282
LL | simd_shuffle_generic::<i32, i32, I4>(0, 0);
8383
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8484

8585
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
86-
--> $DIR/generic-elements.rs:82:9
86+
--> $DIR/generic-elements.rs:85:9
8787
|
8888
LL | simd_shuffle_generic::<i32, i32, I8>(0, 0);
8989
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9090

9191
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
92-
--> $DIR/generic-elements.rs:85:9
92+
--> $DIR/generic-elements.rs:88:9
9393
|
9494
LL | simd_shuffle_generic::<_, f32x2, I2>(x, x);
9595
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9696

9797
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
98-
--> $DIR/generic-elements.rs:87:9
98+
--> $DIR/generic-elements.rs:90:9
9999
|
100100
LL | simd_shuffle_generic::<_, f32x4, I4>(x, x);
101101
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
102102

103103
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
104-
--> $DIR/generic-elements.rs:89:9
104+
--> $DIR/generic-elements.rs:92:9
105105
|
106106
LL | simd_shuffle_generic::<_, f32x8, I8>(x, x);
107107
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
108108

109109
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8
110-
--> $DIR/generic-elements.rs:92:9
110+
--> $DIR/generic-elements.rs:95:9
111111
|
112112
LL | simd_shuffle_generic::<_, i32x8, I2>(x, x);
113113
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114114

115115
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8
116-
--> $DIR/generic-elements.rs:94:9
116+
--> $DIR/generic-elements.rs:97:9
117117
|
118118
LL | simd_shuffle_generic::<_, i32x8, I4>(x, x);
119119
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120120

121121
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2
122-
--> $DIR/generic-elements.rs:96:9
122+
--> $DIR/generic-elements.rs:99:9
123123
|
124124
LL | simd_shuffle_generic::<_, i32x2, I8>(x, x);
125125
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

‎tests/ui/simd/intrinsic/generic-shuffle.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ extern "rust-intrinsic" {
1414
}
1515

1616
fn main() {
17-
const I: [u32; 2] = [0; 2];
18-
const I2: [f32; 2] = [0.; 2];
17+
const I: Simd<u32, 2> = Simd([0; 2]);
18+
const I2: Simd<f32, 2> = Simd([0.; 2]);
1919
let v = Simd::<u32, 4>([0; 4]);
2020

2121
unsafe {
2222
let _: Simd<u32, 2> = simd_shuffle(v, v, I);
2323

24+
let _: Simd<u32, 2> = simd_shuffle(v, v, const { [0u32; 2] });
25+
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
26+
2427
let _: Simd<u32, 4> = simd_shuffle(v, v, I);
2528
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
2629

Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
1-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4>` with length 4
1+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `[u32; 2]`
22
--> $DIR/generic-shuffle.rs:24:31
33
|
4+
LL | let _: Simd<u32, 2> = simd_shuffle(v, v, const { [0u32; 2] });
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4>` with length 4
8+
--> $DIR/generic-shuffle.rs:27:31
9+
|
410
LL | let _: Simd<u32, 4> = simd_shuffle(v, v, I);
511
| ^^^^^^^^^^^^^^^^^^^^^
612

713
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd<u32, 4>`), found `Simd<f32, 2>` with element type `f32`
8-
--> $DIR/generic-shuffle.rs:27:31
14+
--> $DIR/generic-shuffle.rs:30:31
915
|
1016
LL | let _: Simd<f32, 2> = simd_shuffle(v, v, I);
1117
| ^^^^^^^^^^^^^^^^^^^^^
1218

13-
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be an array of `u32`, got `[f32; 2]`
14-
--> $DIR/generic-shuffle.rs:30:31
19+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `Simd<f32, 2>`
20+
--> $DIR/generic-shuffle.rs:33:31
1521
|
1622
LL | let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
1723
| ^^^^^^^^^^^^^^^^^^^^^^
1824

19-
error: aborting due to 3 previous errors
25+
error: aborting due to 4 previous errors
2026

2127
For more information about this error, try `rustc --explain E0511`.

‎tests/ui/simd/intrinsic/inlining-issue67557-ice.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ extern "rust-intrinsic" {
1313
#[derive(Debug, PartialEq)]
1414
struct Simd2([u8; 2]);
1515

16+
#[repr(simd)]
17+
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
18+
1619
fn main() {
1720
unsafe {
1821
let _: Simd2 = inline_me();
@@ -21,6 +24,6 @@ fn main() {
2124

2225
#[inline(always)]
2326
unsafe fn inline_me() -> Simd2 {
24-
const IDX: [u32; 2] = [0, 3];
27+
const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 3]);
2528
simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX)
2629
}

‎tests/ui/simd/intrinsic/inlining-issue67557.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ extern "rust-intrinsic" {
1313
#[derive(Debug, PartialEq)]
1414
struct Simd2([u8; 2]);
1515

16+
#[repr(simd)]
17+
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
18+
1619
fn main() {
1720
unsafe {
18-
const IDX: [u32; 2] = [0, 1];
21+
const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 1]);
1922
let p_res: Simd2 = simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX);
2023
let a_res: Simd2 = inline_me();
2124

@@ -37,6 +40,6 @@ fn assert_10_13(x: Simd2) {
3740

3841
#[inline(always)]
3942
unsafe fn inline_me() -> Simd2 {
40-
const IDX: [u32; 2] = [0, 3];
43+
const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 3]);
4144
simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX)
4245
}

‎tests/ui/simd/monomorphize-shuffle-index.generic.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: overly complex generic constant
22
--> $DIR/monomorphize-shuffle-index.rs:29:45
33
|
4-
LL | return simd_shuffle_generic::<_, _, { &Self::I }>(a, b);
5-
| ^^--------^^
4+
LL | return simd_shuffle_generic::<_, _, { &Self::I.0 }>(a, b);
5+
| ^^----------^^
66
| |
77
| pointer casts are not allowed in generic constants
88
|

‎tests/ui/simd/monomorphize-shuffle-index.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ extern "rust-intrinsic" {
1616
struct Simd<T, const N: usize>([T; N]);
1717

1818
trait Shuffle<const N: usize> {
19-
const I: [u32; N];
20-
const J: &'static [u32] = &Self::I;
19+
const I: Simd<u32, N>;
20+
const J: &'static [u32] = &Self::I.0;
2121

2222
unsafe fn shuffle<T, const M: usize>(&self, a: Simd<T, M>, b: Simd<T, M>) -> Simd<T, N>
2323
where
@@ -26,7 +26,7 @@ trait Shuffle<const N: usize> {
2626
#[cfg(old)]
2727
return simd_shuffle(a, b, Self::I);
2828
#[cfg(generic)]
29-
return simd_shuffle_generic::<_, _, { &Self::I }>(a, b);
29+
return simd_shuffle_generic::<_, _, { &Self::I.0 }>(a, b);
3030
//[generic]~^ overly complex generic constant
3131
#[cfg(generic_with_fn)]
3232
return simd_shuffle_generic::<_, _, { Self::J }>(a, b);
@@ -38,12 +38,12 @@ struct Thing<const X: &'static [u32]>;
3838
fn main() {
3939
struct I1;
4040
impl Shuffle<4> for I1 {
41-
const I: [u32; 4] = [0, 2, 4, 6];
41+
const I: Simd<u32, 4> = Simd([0, 2, 4, 6]);
4242
}
4343

4444
struct I2;
4545
impl Shuffle<2> for I2 {
46-
const I: [u32; 2] = [1, 5];
46+
const I: Simd<u32, 2> = Simd([1, 5]);
4747
}
4848

4949
let a = Simd::<u8, 4>([0, 1, 2, 3]);

‎tests/ui/simd/not-out-of-bounds.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,36 @@ struct u8x64([u8; 64]);
3030

3131
use std::intrinsics::simd::*;
3232

33+
#[repr(simd)]
34+
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
35+
3336
// Test vectors by lane size. Since LLVM does not distinguish between a shuffle
3437
// over two f32s and a shuffle over two u64s, or any other such combination,
3538
// it is not necessary to test every possible vector, only lane counts.
3639
macro_rules! test_shuffle_lanes {
3740
($n:literal, $x:ident, $y:ident) => {
3841
unsafe {
3942
let shuffle: $x = {
40-
const ARR: [u32; $n] = {
43+
const IDX: SimdShuffleIdx<$n> = SimdShuffleIdx({
4144
let mut arr = [0; $n];
4245
arr[0] = $n * 2;
4346
arr
44-
};
47+
});
4548
let mut n: u8 = $n;
4649
let vals = [0; $n].map(|_| { n = n - 1; n });
4750
let vec1 = $x(vals);
4851
let vec2 = $x(vals);
49-
$y(vec1, vec2, ARR)
52+
$y(vec1, vec2, IDX)
5053
};
5154
}
5255
}
5356
}
54-
//~^^^^^ ERROR: invalid monomorphization of `simd_shuffle` intrinsic
55-
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
56-
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
57-
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
58-
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
59-
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
57+
//~^^^^^ ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
58+
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
59+
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
60+
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
61+
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
62+
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
6063
// Because the test is mostly embedded in a macro, all the errors have the same origin point.
6164
// And unfortunately, standard comments, as in the UI test harness, disappear in macros!
6265

@@ -69,15 +72,16 @@ fn main() {
6972
test_shuffle_lanes!(64, u8x64, simd_shuffle);
7073

7174
let v = u8x2([0, 0]);
72-
const I: [u32; 2] = [4, 4];
75+
const I: SimdShuffleIdx<2> = SimdShuffleIdx([4, 4]);
7376
unsafe {
7477
let _: u8x2 = simd_shuffle(v, v, I);
75-
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
78+
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
79+
//~| ERROR invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #1 is out of bounds
7680
}
7781

7882
// also check insert/extract
7983
unsafe {
80-
simd_insert(v, 2, 0); //~ ERROR invalid monomorphization of `simd_insert` intrinsic
81-
let _val: u8 = simd_extract(v, 2); //~ ERROR invalid monomorphization of `simd_extract` intrinsic
84+
simd_insert(v, 2, 0u8); //~ ERROR invalid monomorphization of `simd_insert` intrinsic: SIMD index #1 is out of bounds
85+
let _val: u8 = simd_extract(v, 2); //~ ERROR invalid monomorphization of `simd_extract` intrinsic: SIMD index #1 is out of bounds
8286
}
8387
}
+25-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4)
2-
--> $DIR/not-out-of-bounds.rs:49:21
2+
--> $DIR/not-out-of-bounds.rs:52:21
33
|
4-
LL | $y(vec1, vec2, ARR)
4+
LL | $y(vec1, vec2, IDX)
55
| ^^^^^^^^^^^^^^^^^^^
66
...
77
LL | test_shuffle_lanes!(2, u8x2, simd_shuffle);
@@ -10,9 +10,9 @@ LL | test_shuffle_lanes!(2, u8x2, simd_shuffle);
1010
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
1111

1212
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 8)
13-
--> $DIR/not-out-of-bounds.rs:49:21
13+
--> $DIR/not-out-of-bounds.rs:52:21
1414
|
15-
LL | $y(vec1, vec2, ARR)
15+
LL | $y(vec1, vec2, IDX)
1616
| ^^^^^^^^^^^^^^^^^^^
1717
...
1818
LL | test_shuffle_lanes!(4, u8x4, simd_shuffle);
@@ -21,9 +21,9 @@ LL | test_shuffle_lanes!(4, u8x4, simd_shuffle);
2121
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
2222

2323
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 16)
24-
--> $DIR/not-out-of-bounds.rs:49:21
24+
--> $DIR/not-out-of-bounds.rs:52:21
2525
|
26-
LL | $y(vec1, vec2, ARR)
26+
LL | $y(vec1, vec2, IDX)
2727
| ^^^^^^^^^^^^^^^^^^^
2828
...
2929
LL | test_shuffle_lanes!(8, u8x8, simd_shuffle);
@@ -32,9 +32,9 @@ LL | test_shuffle_lanes!(8, u8x8, simd_shuffle);
3232
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
3333

3434
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 32)
35-
--> $DIR/not-out-of-bounds.rs:49:21
35+
--> $DIR/not-out-of-bounds.rs:52:21
3636
|
37-
LL | $y(vec1, vec2, ARR)
37+
LL | $y(vec1, vec2, IDX)
3838
| ^^^^^^^^^^^^^^^^^^^
3939
...
4040
LL | test_shuffle_lanes!(16, u8x16, simd_shuffle);
@@ -43,9 +43,9 @@ LL | test_shuffle_lanes!(16, u8x16, simd_shuffle);
4343
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
4444

4545
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 64)
46-
--> $DIR/not-out-of-bounds.rs:49:21
46+
--> $DIR/not-out-of-bounds.rs:52:21
4747
|
48-
LL | $y(vec1, vec2, ARR)
48+
LL | $y(vec1, vec2, IDX)
4949
| ^^^^^^^^^^^^^^^^^^^
5050
...
5151
LL | test_shuffle_lanes!(32, u8x32, simd_shuffle);
@@ -54,9 +54,9 @@ LL | test_shuffle_lanes!(32, u8x32, simd_shuffle);
5454
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
5555

5656
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 128)
57-
--> $DIR/not-out-of-bounds.rs:49:21
57+
--> $DIR/not-out-of-bounds.rs:52:21
5858
|
59-
LL | $y(vec1, vec2, ARR)
59+
LL | $y(vec1, vec2, IDX)
6060
| ^^^^^^^^^^^^^^^^^^^
6161
...
6262
LL | test_shuffle_lanes!(64, u8x64, simd_shuffle);
@@ -65,23 +65,29 @@ LL | test_shuffle_lanes!(64, u8x64, simd_shuffle);
6565
= note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
6666

6767
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4)
68-
--> $DIR/not-out-of-bounds.rs:74:23
68+
--> $DIR/not-out-of-bounds.rs:77:23
6969
|
7070
LL | let _: u8x2 = simd_shuffle(v, v, I);
7171
| ^^^^^^^^^^^^^^^^^^^^^
7272

73-
error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `u8` (element of input `u8x2`), found `i32`
74-
--> $DIR/not-out-of-bounds.rs:80:9
73+
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #1 is out of bounds (limit 4)
74+
--> $DIR/not-out-of-bounds.rs:77:23
7575
|
76-
LL | simd_insert(v, 2, 0);
77-
| ^^^^^^^^^^^^^^^^^^^^
76+
LL | let _: u8x2 = simd_shuffle(v, v, I);
77+
| ^^^^^^^^^^^^^^^^^^^^^
78+
79+
error[E0511]: invalid monomorphization of `simd_insert` intrinsic: SIMD index #1 is out of bounds (limit 2)
80+
--> $DIR/not-out-of-bounds.rs:84:9
81+
|
82+
LL | simd_insert(v, 2, 0u8);
83+
| ^^^^^^^^^^^^^^^^^^^^^^
7884

7985
error[E0511]: invalid monomorphization of `simd_extract` intrinsic: SIMD index #1 is out of bounds (limit 2)
80-
--> $DIR/not-out-of-bounds.rs:81:24
86+
--> $DIR/not-out-of-bounds.rs:85:24
8187
|
8288
LL | let _val: u8 = simd_extract(v, 2);
8389
| ^^^^^^^^^^^^^^^^^^
8490

85-
error: aborting due to 9 previous errors
91+
error: aborting due to 10 previous errors
8692

8793
For more information about this error, try `rustc --explain E0511`.

‎tests/ui/simd/shuffle.rs

+3-23
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@ extern "rust-intrinsic" {
1616
#[repr(simd)]
1717
struct Simd<T, const N: usize>([T; N]);
1818

19-
unsafe fn __shuffle_vector16<const IDX: [u32; 16], T, U>(x: T, y: T) -> U {
20-
simd_shuffle(x, y, IDX)
21-
}
22-
unsafe fn __shuffle_vector16_v2<const IDX: Simd<u32, 16>, T, U>(x: T, y: T) -> U {
19+
unsafe fn __shuffle_vector16<const IDX: Simd<u32, 16>, T, U>(x: T, y: T) -> U {
2320
simd_shuffle(x, y, IDX)
2421
}
2522

2623
fn main() {
27-
const I1: [u32; 4] = [0, 2, 4, 6];
28-
const I2: [u32; 2] = [1, 5];
24+
const I1: Simd<u32, 4> = Simd([0, 2, 4, 6]);
25+
const I2: Simd<u32, 2> = Simd([1, 5]);
2926
let a = Simd::<u8, 4>([0, 1, 2, 3]);
3027
let b = Simd::<u8, 4>([4, 5, 6, 7]);
3128
unsafe {
@@ -35,16 +32,6 @@ fn main() {
3532
let y: Simd<u8, 2> = simd_shuffle(a, b, I2);
3633
assert_eq!(y.0, [1, 5]);
3734
}
38-
// Test that we can also use a SIMD vector instead of a normal array for the shuffle.
39-
const I1_SIMD: Simd<u32, 4> = Simd([0, 2, 4, 6]);
40-
const I2_SIMD: Simd<u32, 2> = Simd([1, 5]);
41-
unsafe {
42-
let x: Simd<u8, 4> = simd_shuffle(a, b, I1_SIMD);
43-
assert_eq!(x.0, [0, 2, 4, 6]);
44-
45-
let y: Simd<u8, 2> = simd_shuffle(a, b, I2_SIMD);
46-
assert_eq!(y.0, [1, 5]);
47-
}
4835

4936
// Test that an indirection (via an unnamed constant)
5037
// through a const generic parameter also works.
@@ -53,13 +40,6 @@ fn main() {
5340
let b = Simd::<u8, 16>([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]);
5441
unsafe {
5542
__shuffle_vector16::<
56-
{ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] },
57-
Simd<u8, 16>,
58-
Simd<u8, 16>,
59-
>(a, b);
60-
}
61-
unsafe {
62-
__shuffle_vector16_v2::<
6343
{ Simd([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) },
6444
Simd<u8, 16>,
6545
Simd<u8, 16>,

0 commit comments

Comments
 (0)
Please sign in to comment.