about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-09-12 11:33:13 +0200
committerRalf Jung <post@ralfj.de>2024-09-14 14:43:24 +0200
commit60ee1b7ac6e1c18679573d4a752e6fc02790d892 (patch)
tree106c9c63ac9b311a0a44b947ed0b2f78c47fd7be
parent0307e401c26699656ae08e3809e7d272f5c103f4 (diff)
downloadrust-60ee1b7ac6e1c18679573d4a752e6fc02790d892.tar.gz
rust-60ee1b7ac6e1c18679573d4a752e6fc02790d892.zip
simd_shuffle: require index argument to be a vector
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs40
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs39
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs25
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs80
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs28
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs35
-rw-r--r--library/core/src/intrinsics/simd.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/swizzle.rs16
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs8
-rw-r--r--src/tools/miri/tests/pass/intrinsics/portable-simd.rs5
-rw-r--r--tests/incremental/issue-61530.rs5
-rw-r--r--tests/ui/simd/intrinsic/generic-elements-pass.rs48
-rw-r--r--tests/ui/simd/intrinsic/generic-elements.rs9
-rw-r--r--tests/ui/simd/intrinsic/generic-elements.stderr42
-rw-r--r--tests/ui/simd/intrinsic/generic-shuffle.rs7
-rw-r--r--tests/ui/simd/intrinsic/generic-shuffle.stderr16
-rw-r--r--tests/ui/simd/intrinsic/inlining-issue67557-ice.rs5
-rw-r--r--tests/ui/simd/intrinsic/inlining-issue67557.rs7
-rw-r--r--tests/ui/simd/monomorphize-shuffle-index.generic.stderr4
-rw-r--r--tests/ui/simd/monomorphize-shuffle-index.rs10
-rw-r--r--tests/ui/simd/not-out-of-bounds.rs29
-rw-r--r--tests/ui/simd/not-out-of-bounds.stderr36
-rw-r--r--tests/ui/simd/shuffle.rs26
24 files changed, 220 insertions, 304 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index 604a88393fd..a5621aec244 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -180,34 +180,20 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                 return;
             }
 
-            // Make sure this is actually an array, since typeck only checks the length-suffixed
-            // version of this intrinsic.
+            // Make sure this is actually a SIMD vector.
             let idx_ty = fx.monomorphize(idx.node.ty(fx.mir, fx.tcx));
-            let n: u16 = match idx_ty.kind() {
-                ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => len
-                    .try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
-                    .unwrap_or_else(|| {
-                        span_bug!(span, "could not evaluate shuffle index array length")
-                    })
-                    .try_into()
-                    .unwrap(),
-                _ if idx_ty.is_simd()
-                    && matches!(
-                        idx_ty.simd_size_and_type(fx.tcx).1.kind(),
-                        ty::Uint(ty::UintTy::U32)
-                    ) =>
-                {
-                    idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap()
-                }
-                _ => {
-                    fx.tcx.dcx().span_err(
-                        span,
-                        format!("simd_shuffle index must be an array of `u32`, got `{}`", idx_ty),
-                    );
-                    // Prevent verifier error
-                    fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
-                    return;
-                }
+            let n: u16 = if idx_ty.is_simd()
+                && matches!(idx_ty.simd_size_and_type(fx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
+            {
+                idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap()
+            } else {
+                fx.tcx.dcx().span_err(
+                    span,
+                    format!("simd_shuffle index must be a SIMD vector of `u32`, got `{}`", idx_ty),
+                );
+                // Prevent verifier error
+                fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
+                return;
             };
 
             assert_eq!(x.layout(), y.layout());
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 6ba678e2e7c..31d778823e0 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -1939,33 +1939,18 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
             self.int_type
         };
 
-        let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() {
-            let mask_num_units = vector_type.get_num_units();
-            let mut mask_elements = vec![];
-            for i in 0..mask_num_units {
-                let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
-                mask_elements.push(self.context.new_cast(
-                    self.location,
-                    self.extract_element(mask, index).to_rvalue(),
-                    mask_element_type,
-                ));
-            }
-            mask_elements
-        } else {
-            let struct_type = mask.get_type().is_struct().expect("mask should be of struct type");
-            let mask_num_units = struct_type.get_field_count();
-            let mut mask_elements = vec![];
-            for i in 0..mask_num_units {
-                let field = struct_type.get_field(i as i32);
-                mask_elements.push(self.context.new_cast(
-                    self.location,
-                    mask.access_field(self.location, field).to_rvalue(),
-                    mask_element_type,
-                ));
-            }
-            mask_elements
-        };
-        let mask_num_units = mask_elements.len();
+        let vector_type =
+            mask.get_type().dyncast_vector().expect("simd_shuffle mask should be of vector type");
+        let mask_num_units = vector_type.get_num_units();
+        let mut mask_elements = vec![];
+        for i in 0..mask_num_units {
+            let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
+            mask_elements.push(self.context.new_cast(
+                self.location,
+                self.extract_element(mask, index).to_rvalue(),
+                mask_element_type,
+            ));
+        }
 
         // NOTE: the mask needs to be the same length as the input vectors, so add the missing
         // elements in the mask if needed.
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 96a833ccaf2..2eabc1430db 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -14,7 +14,6 @@ use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
 #[cfg(feature = "master")]
 use rustc_hir as hir;
 use rustc_middle::mir::BinOp;
-use rustc_middle::span_bug;
 use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::{sym, Span, Symbol};
@@ -353,24 +352,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     }
 
     if name == sym::simd_shuffle {
-        // Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
-        // version of this intrinsic.
+        // Make sure this is actually a SIMD vector.
         let idx_ty = args[2].layout.ty;
-        let n: u64 = match idx_ty.kind() {
-            ty::Array(ty, len) if matches!(*ty.kind(), ty::Uint(ty::UintTy::U32)) => {
-                len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
-                    || span_bug!(span, "could not evaluate shuffle index array length"),
-                )
-            }
-            _ if idx_ty.is_simd()
-                && matches!(
-                    idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(),
-                    ty::Uint(ty::UintTy::U32)
-                ) =>
-            {
-                idx_ty.simd_size_and_type(bx.cx.tcx).0
-            }
-            _ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }),
+        let n: u64 = if idx_ty.is_simd()
+            && matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
+        {
+            idx_ty.simd_size_and_type(bx.cx.tcx).0
+        } else {
+            return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty })
         };
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
 
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 05fb77a193a..9705dd506b9 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -573,6 +573,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     span,
                 ) {
                     Ok(llval) => llval,
+                    // If there was an error, just skip this invocation... we'll abort compilation anyway,
+                    // but we can keep codegen'ing to find more errors.
                     Err(()) => return Ok(()),
                 }
             }
@@ -1290,24 +1292,14 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     }
 
     if name == sym::simd_shuffle {
-        // Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
-        // version of this intrinsic.
+        // Make sure this is actually a SIMD vector.
         let idx_ty = args[2].layout.ty;
-        let n: u64 = match idx_ty.kind() {
-            ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
-                len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
-                    || span_bug!(span, "could not evaluate shuffle index array length"),
-                )
-            }
-            _ if idx_ty.is_simd()
-                && matches!(
-                    idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(),
-                    ty::Uint(ty::UintTy::U32)
-                ) =>
-            {
-                idx_ty.simd_size_and_type(bx.cx.tcx).0
-            }
-            _ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }),
+        let n: u64 = if idx_ty.is_simd()
+            && matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
+        {
+            idx_ty.simd_size_and_type(bx.cx.tcx).0
+        } else {
+            return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty })
         };
 
         let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
@@ -1322,38 +1314,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
 
         let total_len = u128::from(in_len) * 2;
 
-        let vector = args[2].immediate();
-
-        let indices: Option<Vec<_>> = (0..n)
-            .map(|i| {
-                let arg_idx = i;
-                let val = bx.const_get_elt(vector, i as u64);
-                match bx.const_to_opt_u128(val, true) {
-                    None => {
-                        bug!("typeck should have already ensured that these are const")
-                    }
-                    Some(idx) if idx >= total_len => {
-                        bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
-                            span,
-                            name,
-                            arg_idx,
-                            total_len,
-                        });
-                        None
-                    }
-                    Some(idx) => Some(bx.const_i32(idx as i32)),
-                }
-            })
-            .collect();
-        let Some(indices) = indices else {
-            return Ok(bx.const_null(llret_ty));
-        };
+        // Check that the indices are in-bounds.
+        let indices = args[2].immediate();
+        for i in 0..n {
+            let val = bx.const_get_elt(indices, i as u64);
+            let idx = bx
+                .const_to_opt_u128(val, true)
+                .unwrap_or_else(|| bug!("typeck should have already ensured that these are const"));
+            if idx >= total_len {
+                return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
+                    span,
+                    name,
+                    arg_idx: i,
+                    total_len,
+                });
+            }
+        }
 
-        return Ok(bx.shuffle_vector(
-            args[0].immediate(),
-            args[1].immediate(),
-            bx.const_vector(&indices),
-        ));
+        return Ok(bx.shuffle_vector(args[0].immediate(), args[1].immediate(), indices));
     }
 
     if name == sym::simd_insert {
@@ -1371,13 +1349,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             .const_to_opt_u128(args[1].immediate(), false)
             .expect("typeck should have ensure that this is a const");
         if idx >= in_len.into() {
-            bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
+            return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
                 span,
                 name,
                 arg_idx: 1,
                 total_len: in_len.into(),
             });
-            return Ok(bx.const_null(llret_ty));
         }
         return Ok(bx.insert_element(
             args[0].immediate(),
@@ -1394,13 +1371,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             .const_to_opt_u128(args[1].immediate(), false)
             .expect("typeck should have ensure that this is a const");
         if idx >= in_len.into() {
-            bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
+            return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
                 span,
                 name,
                 arg_idx: 1,
                 total_len: in_len.into(),
             });
-            return Ok(bx.const_null(llret_ty));
         }
         return Ok(bx.extract_element(args[0].immediate(), bx.const_i32(idx as i32)));
     }
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index 8a6a2acd87d..9091602d75b 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -132,7 +132,7 @@ codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `
 
 codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}`
 
-codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
+codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `{$ty}`
 
 codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 817e2ca72ec..8f96c462240 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -915,32 +915,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
                 };
 
-                let args: Vec<_> = args
-                    .iter()
-                    .enumerate()
-                    .map(|(i, arg)| {
-                        // The indices passed to simd_shuffle in the
-                        // third argument must be constant. This is
-                        // checked by the type-checker.
-                        if i == 2 && intrinsic.name == sym::simd_shuffle {
-                            // FIXME: the simd_shuffle argument is actually an array,
-                            // not a vector, so we need this special hack to make sure
-                            // it is passed as an immediate. We should pass the
-                            // shuffle indices as a vector instead to avoid this hack.
-                            if let mir::Operand::Constant(constant) = &arg.node {
-                                let (llval, ty) = self.immediate_const_vector(bx, constant);
-                                return OperandRef {
-                                    val: Immediate(llval),
-                                    layout: bx.layout_of(ty),
-                                };
-                            } else {
-                                span_bug!(span, "shuffle indices must be constant");
-                            }
-                        }
-
-                        self.codegen_operand(bx, &arg.node)
-                    })
-                    .collect();
+                let args: Vec<_> =
+                    args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect();
 
                 if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) {
                     let location = self
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index 0aa85b82038..8254fb3d866 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -1,6 +1,6 @@
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::layout::HasTyCtxt;
-use rustc_middle::ty::{self, Ty, ValTree};
+use rustc_middle::ty::{self, Ty};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_target::abi::Abi;
 
@@ -66,15 +66,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         constant: &mir::ConstOperand<'tcx>,
     ) -> (Bx::Value, Ty<'tcx>) {
         let ty = self.monomorphize(constant.ty());
-        let ty_is_simd = ty.is_simd();
-        // FIXME: ideally we'd assert that this is a SIMD type, but simd_shuffle
-        // in its current form relies on a regular array being passed as an
-        // immediate argument. This hack can be removed once that is fixed.
-        let field_ty = if ty_is_simd {
-            ty.simd_size_and_type(bx.tcx()).1
-        } else {
-            ty.builtin_index().unwrap()
-        };
+        assert!(ty.is_simd());
+        let field_ty = ty.simd_size_and_type(bx.tcx()).1;
 
         let val = self
             .eval_unevaluated_mir_constant_to_valtree(constant)
@@ -82,19 +75,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             .map(|x| x.ok())
             .flatten()
             .map(|val| {
-                // Depending on whether this is a SIMD type with an array field
-                // or a type with many fields (one for each elements), the valtree
-                // is either a single branch with N children, or a root node
-                // with exactly one child which then in turn has many children.
-                // So we look at the first child to determine whether it is a
-                // leaf or whether we have to go one more layer down.
-                let branch_or_leaf = val.unwrap_branch();
-                let first = branch_or_leaf.get(0).unwrap();
-                let field_iter = match first {
-                    ValTree::Branch(_) => first.unwrap_branch().iter(),
-                    ValTree::Leaf(_) => branch_or_leaf.iter(),
-                };
-                let values: Vec<_> = field_iter
+                // A SIMD type has a single field, which is an array.
+                let fields = val.unwrap_branch();
+                assert_eq!(fields.len(), 1);
+                let array = fields[0].unwrap_branch();
+                // Iterate over the array elements to obtain the values in the vector.
+                let values: Vec<_> = array
+                    .iter()
                     .map(|field| {
                         if let Some(prim) = field.try_to_scalar() {
                             let layout = bx.layout_of(field_ty);
@@ -107,7 +94,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         }
                     })
                     .collect();
-                if ty_is_simd { bx.const_vector(&values) } else { bx.const_struct(&values, false) }
+                bx.const_vector(&values)
             })
             .unwrap_or_else(|| {
                 bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index 59828198099..5ddca9c4dce 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -232,7 +232,7 @@ extern "rust-intrinsic" {
     ///
     /// `T` must be a vector.
     ///
-    /// `U` must be a **const** array or vector of `u32`s. This means it must either refer to a named
+    /// `U` must be a **const** vector of `u32`s. This means it must either refer to a named
     /// const or be given as an inline const expression (`const { ... }`).
     ///
     /// `V` must be a vector with the same element type as `T` and the same length as `U`.
diff --git a/library/portable-simd/crates/core_simd/src/swizzle.rs b/library/portable-simd/crates/core_simd/src/swizzle.rs
index 2f4f777b20e..d62642fb906 100644
--- a/library/portable-simd/crates/core_simd/src/swizzle.rs
+++ b/library/portable-simd/crates/core_simd/src/swizzle.rs
@@ -85,7 +85,7 @@ pub trait Swizzle<const N: usize> {
         LaneCount<N>: SupportedLaneCount,
         LaneCount<M>: SupportedLaneCount,
     {
-        // Safety: `vector` is a vector, and the index is a const array of u32.
+        // Safety: `vector` is a vector, and the index is a const vector of u32.
         unsafe {
             core::intrinsics::simd::simd_shuffle(
                 vector,
@@ -103,7 +103,11 @@ pub trait Swizzle<const N: usize> {
                         output[i] = index as u32;
                         i += 1;
                     }
-                    output
+
+                    // The index list needs to be returned as a vector.
+                    #[repr(simd)]
+                    struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
+                    SimdShuffleIdx(output)
                 },
             )
         }
@@ -121,7 +125,7 @@ pub trait Swizzle<const N: usize> {
         LaneCount<N>: SupportedLaneCount,
         LaneCount<M>: SupportedLaneCount,
     {
-        // Safety: `first` and `second` are vectors, and the index is a const array of u32.
+        // Safety: `first` and `second` are vectors, and the index is a const vector of u32.
         unsafe {
             core::intrinsics::simd::simd_shuffle(
                 first,
@@ -139,7 +143,11 @@ pub trait Swizzle<const N: usize> {
                         output[i] = index as u32;
                         i += 1;
                     }
-                    output
+
+                    // The index list needs to be returned as a vector.
+                    #[repr(simd)]
+                    struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
+                    SimdShuffleIdx(output)
                 },
             )
         }
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index aa91b89d0ec..e22306ca82f 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -664,15 +664,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let [left, right, index] = check_arg_count(args)?;
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
+                let (index, index_len) = this.project_to_simd(index)?;
                 let (dest, dest_len) = this.project_to_simd(dest)?;
 
-                // `index` is an array or a SIMD type
-                let (index, index_len) = match index.layout.ty.kind() {
-                    // FIXME: remove this once `index` must always be a SIMD vector.
-                    ty::Array(..) => (index.clone(), index.len(this)?),
-                    _ => this.project_to_simd(index)?,
-                };
-
                 assert_eq!(left_len, right_len);
                 assert_eq!(index_len, dest_len);
 
diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
index daf75fee8fe..4c0d6f52425 100644
--- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
+++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
@@ -619,7 +619,6 @@ fn simd_intrinsics() {
             i32x4::from_array([10, 2, 10, 10])
         );
         assert_eq!(simd_shuffle_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,);
-        assert_eq!(simd_shuffle::<_, _, i32x4>(a, b, const { [3u32, 1, 0, 2] }), a,);
         assert_eq!(
             simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([3u32, 1, 0, 2]) }),
             a,
@@ -629,10 +628,6 @@ fn simd_intrinsics() {
             i32x4::from_array([4, 2, 1, 10]),
         );
         assert_eq!(
-            simd_shuffle::<_, _, i32x4>(a, b, const { [7u32, 5, 4, 6] }),
-            i32x4::from_array([4, 2, 1, 10]),
-        );
-        assert_eq!(
             simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([7u32, 5, 4, 6]) }),
             i32x4::from_array([4, 2, 1, 10]),
         );
diff --git a/tests/incremental/issue-61530.rs b/tests/incremental/issue-61530.rs
index b4914dda11a..71ac39d0e03 100644
--- a/tests/incremental/issue-61530.rs
+++ b/tests/incremental/issue-61530.rs
@@ -9,9 +9,12 @@ extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
 }
 
+#[repr(simd)]
+struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
+
 fn main() {
     unsafe {
-        const IDX: [u32; 2] = [0, 0];
+        const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 0]);
         let _: I32x2 = simd_shuffle(I32x2([1, 2]), I32x2([3, 4]), IDX);
         let _: I32x2 = simd_shuffle(I32x2([1, 2]), I32x2([3, 4]), IDX);
     }
diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs
index b159387ab62..7b1bda4fbcd 100644
--- a/tests/ui/simd/intrinsic/generic-elements-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs
@@ -23,6 +23,9 @@ extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
 }
 
+#[repr(simd)]
+struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
+
 macro_rules! all_eq {
     ($a: expr, $b: expr) => {{
         let a = $a;
@@ -30,9 +33,8 @@ macro_rules! all_eq {
         // type inference works better with the concrete type on the
         // left, but humans work better with the expected on the
         // right.
-        assert!(b == a,
-                "{:?} != {:?}", a, b);
-    }}
+        assert!(b == a, "{:?} != {:?}", a, b);
+    }};
 }
 
 fn main() {
@@ -79,20 +81,34 @@ fn main() {
     let y4 = i32x4([140, 141, 142, 143]);
     let y8 = i32x8([180, 181, 182, 183, 184, 185, 186, 187]);
     unsafe {
-        all_eq!(simd_shuffle(x2, y2, const { [3u32, 0] }), i32x2([121, 20]));
-        all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2] }), i32x4([121, 20, 21, 120]));
-        all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2, 1, 2, 3, 0] }),
-                i32x8([121, 20, 21, 120, 21, 120, 121, 20]));
+        all_eq!(simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0]) }), i32x2([121, 20]));
+        all_eq!(
+            simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0, 1, 2]) }),
+            i32x4([121, 20, 21, 120])
+        );
+        all_eq!(
+            simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0, 1, 2, 1, 2, 3, 0]) }),
+            i32x8([121, 20, 21, 120, 21, 120, 121, 20])
+        );
 
-        all_eq!(simd_shuffle(x4, y4, const { [7u32, 2] }), i32x2([143, 42]));
-        all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0] }), i32x4([143, 42, 141, 40]));
-        all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0, 3, 6, 4, 1] }),
-                i32x8([143, 42, 141, 40, 43, 142, 140, 41]));
+        all_eq!(simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2]) }), i32x2([143, 42]));
+        all_eq!(
+            simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2, 5, 0]) }),
+            i32x4([143, 42, 141, 40])
+        );
+        all_eq!(
+            simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2, 5, 0, 3, 6, 4, 1]) }),
+            i32x8([143, 42, 141, 40, 43, 142, 140, 41])
+        );
 
-        all_eq!(simd_shuffle(x8, y8, const { [11u32, 5] }), i32x2([183, 85]));
-        all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0] }), i32x4([183, 85, 187, 80]));
-        all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0, 3, 8, 12, 1] }),
-                i32x8([183, 85, 187, 80, 83, 180, 184, 81]));
+        all_eq!(simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5]) }), i32x2([183, 85]));
+        all_eq!(
+            simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5, 15, 0]) }),
+            i32x4([183, 85, 187, 80])
+        );
+        all_eq!(
+            simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5, 15, 0, 3, 8, 12, 1]) }),
+            i32x8([183, 85, 187, 80, 83, 180, 184, 81])
+        );
     }
-
 }
diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs
index 4848fd1b803..5d784a25eab 100644
--- a/tests/ui/simd/intrinsic/generic-elements.rs
+++ b/tests/ui/simd/intrinsic/generic-elements.rs
@@ -37,6 +37,9 @@ extern "rust-intrinsic" {
     fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
 }
 
+#[repr(simd)]
+struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
+
 fn main() {
     let x = i32x4([0, 0, 0, 0]);
 
@@ -48,13 +51,13 @@ fn main() {
         simd_extract::<_, f32>(x, 0);
         //~^ ERROR expected return type `i32` (element of input `i32x4`), found `f32`
 
-        const IDX2: [u32; 2] = [0; 2];
+        const IDX2: SimdShuffleIdx<2> = SimdShuffleIdx([0; 2]);
         simd_shuffle::<i32, _, i32>(0, 0, IDX2);
         //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        const IDX4: [u32; 4] = [0; 4];
+        const IDX4: SimdShuffleIdx<4> = SimdShuffleIdx([0; 4]);
         simd_shuffle::<i32, _, i32>(0, 0, IDX4);
         //~^ ERROR expected SIMD input type, found non-SIMD `i32`
-        const IDX8: [u32; 8] = [0; 8];
+        const IDX8: SimdShuffleIdx<8> = SimdShuffleIdx([0; 8]);
         simd_shuffle::<i32, _, i32>(0, 0, IDX8);
         //~^ ERROR expected SIMD input type, found non-SIMD `i32`
 
diff --git a/tests/ui/simd/intrinsic/generic-elements.stderr b/tests/ui/simd/intrinsic/generic-elements.stderr
index 0788a7c17f9..fd726d75326 100644
--- a/tests/ui/simd/intrinsic/generic-elements.stderr
+++ b/tests/ui/simd/intrinsic/generic-elements.stderr
@@ -1,125 +1,125 @@
 error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:44:9
+  --> $DIR/generic-elements.rs:47:9
    |
 LL |         simd_insert(0, 0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64`
-  --> $DIR/generic-elements.rs:46:9
+  --> $DIR/generic-elements.rs:49:9
    |
 LL |         simd_insert(x, 0, 1.0);
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32`
-  --> $DIR/generic-elements.rs:48:9
+  --> $DIR/generic-elements.rs:51:9
    |
 LL |         simd_extract::<_, f32>(x, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:52:9
+  --> $DIR/generic-elements.rs:55:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:55:9
+  --> $DIR/generic-elements.rs:58:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:58:9
+  --> $DIR/generic-elements.rs:61:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
-  --> $DIR/generic-elements.rs:61:9
+  --> $DIR/generic-elements.rs:64:9
    |
 LL |         simd_shuffle::<_, _, f32x2>(x, x, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
-  --> $DIR/generic-elements.rs:63:9
+  --> $DIR/generic-elements.rs:66:9
    |
 LL |         simd_shuffle::<_, _, f32x4>(x, x, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
-  --> $DIR/generic-elements.rs:65:9
+  --> $DIR/generic-elements.rs:68:9
    |
 LL |         simd_shuffle::<_, _, f32x8>(x, x, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:68:9
+  --> $DIR/generic-elements.rs:71:9
    |
 LL |         simd_shuffle::<_, _, i32x8>(x, x, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 4, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:70:9
+  --> $DIR/generic-elements.rs:73:9
    |
 LL |         simd_shuffle::<_, _, i32x8>(x, x, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 8, found `i32x2` with length 2
-  --> $DIR/generic-elements.rs:72:9
+  --> $DIR/generic-elements.rs:75:9
    |
 LL |         simd_shuffle::<_, _, i32x2>(x, x, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:76:9
+  --> $DIR/generic-elements.rs:79:9
    |
 LL |         simd_shuffle_generic::<i32, i32, I2>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:79:9
+  --> $DIR/generic-elements.rs:82:9
    |
 LL |         simd_shuffle_generic::<i32, i32, I4>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:82:9
+  --> $DIR/generic-elements.rs:85:9
    |
 LL |         simd_shuffle_generic::<i32, i32, I8>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
-  --> $DIR/generic-elements.rs:85:9
+  --> $DIR/generic-elements.rs:88:9
    |
 LL |         simd_shuffle_generic::<_, f32x2, I2>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
-  --> $DIR/generic-elements.rs:87:9
+  --> $DIR/generic-elements.rs:90:9
    |
 LL |         simd_shuffle_generic::<_, f32x4, I4>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
-  --> $DIR/generic-elements.rs:89:9
+  --> $DIR/generic-elements.rs:92:9
    |
 LL |         simd_shuffle_generic::<_, f32x8, I8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:92:9
+  --> $DIR/generic-elements.rs:95:9
    |
 LL |         simd_shuffle_generic::<_, i32x8, I2>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:94:9
+  --> $DIR/generic-elements.rs:97:9
    |
 LL |         simd_shuffle_generic::<_, i32x8, I4>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2
-  --> $DIR/generic-elements.rs:96:9
+  --> $DIR/generic-elements.rs:99:9
    |
 LL |         simd_shuffle_generic::<_, i32x2, I8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-shuffle.rs b/tests/ui/simd/intrinsic/generic-shuffle.rs
index c0888f67784..2752718d99d 100644
--- a/tests/ui/simd/intrinsic/generic-shuffle.rs
+++ b/tests/ui/simd/intrinsic/generic-shuffle.rs
@@ -14,13 +14,16 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    const I: [u32; 2] = [0; 2];
-    const I2: [f32; 2] = [0.; 2];
+    const I: Simd<u32, 2> = Simd([0; 2]);
+    const I2: Simd<f32, 2> = Simd([0.; 2]);
     let v = Simd::<u32, 4>([0; 4]);
 
     unsafe {
         let _: Simd<u32, 2> = simd_shuffle(v, v, I);
 
+        let _: Simd<u32, 2> = simd_shuffle(v, v, const { [0u32; 2] });
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+
         let _: Simd<u32, 4> = simd_shuffle(v, v, I);
         //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
 
diff --git a/tests/ui/simd/intrinsic/generic-shuffle.stderr b/tests/ui/simd/intrinsic/generic-shuffle.stderr
index 81e641612ce..7e6d51a5f65 100644
--- a/tests/ui/simd/intrinsic/generic-shuffle.stderr
+++ b/tests/ui/simd/intrinsic/generic-shuffle.stderr
@@ -1,21 +1,27 @@
-error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4>` with length 4
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `[u32; 2]`
   --> $DIR/generic-shuffle.rs:24:31
    |
+LL |         let _: Simd<u32, 2> = simd_shuffle(v, v, const { [0u32; 2] });
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4>` with length 4
+  --> $DIR/generic-shuffle.rs:27: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>`), found `Simd<f32, 2>` with element type `f32`
-  --> $DIR/generic-shuffle.rs:27:31
+  --> $DIR/generic-shuffle.rs:30: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/generic-shuffle.rs:30:31
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `Simd<f32, 2>`
+  --> $DIR/generic-shuffle.rs:33:31
    |
 LL |         let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
    |                               ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0511`.
diff --git a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
index a64a7c0b48a..d9239ef5801 100644
--- a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
+++ b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
@@ -13,6 +13,9 @@ extern "rust-intrinsic" {
 #[derive(Debug, PartialEq)]
 struct Simd2([u8; 2]);
 
+#[repr(simd)]
+struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
+
 fn main() {
     unsafe {
         let _: Simd2 = inline_me();
@@ -21,6 +24,6 @@ fn main() {
 
 #[inline(always)]
 unsafe fn inline_me() -> Simd2 {
-    const IDX: [u32; 2] = [0, 3];
+    const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 3]);
     simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX)
 }
diff --git a/tests/ui/simd/intrinsic/inlining-issue67557.rs b/tests/ui/simd/intrinsic/inlining-issue67557.rs
index cb80d65d468..23dd5075f96 100644
--- a/tests/ui/simd/intrinsic/inlining-issue67557.rs
+++ b/tests/ui/simd/intrinsic/inlining-issue67557.rs
@@ -13,9 +13,12 @@ extern "rust-intrinsic" {
 #[derive(Debug, PartialEq)]
 struct Simd2([u8; 2]);
 
+#[repr(simd)]
+struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
+
 fn main() {
     unsafe {
-        const IDX: [u32; 2] = [0, 1];
+        const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 1]);
         let p_res: Simd2 = simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX);
         let a_res: Simd2 = inline_me();
 
@@ -37,6 +40,6 @@ fn assert_10_13(x: Simd2) {
 
 #[inline(always)]
 unsafe fn inline_me() -> Simd2 {
-    const IDX: [u32; 2] = [0, 3];
+    const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 3]);
     simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX)
 }
diff --git a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr
index c4cfca7be1d..2d1fa1f8da2 100644
--- a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr
+++ b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr
@@ -1,8 +1,8 @@
 error: overly complex generic constant
   --> $DIR/monomorphize-shuffle-index.rs:29:45
    |
-LL |         return simd_shuffle_generic::<_, _, { &Self::I }>(a, b);
-   |                                             ^^--------^^
+LL |         return simd_shuffle_generic::<_, _, { &Self::I.0 }>(a, b);
+   |                                             ^^----------^^
    |                                               |
    |                                               pointer casts are not allowed in generic constants
    |
diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs
index 30c345cb904..140cf6fbe96 100644
--- a/tests/ui/simd/monomorphize-shuffle-index.rs
+++ b/tests/ui/simd/monomorphize-shuffle-index.rs
@@ -16,8 +16,8 @@ extern "rust-intrinsic" {
 struct Simd<T, const N: usize>([T; N]);
 
 trait Shuffle<const N: usize> {
-    const I: [u32; N];
-    const J: &'static [u32] = &Self::I;
+    const I: Simd<u32, N>;
+    const J: &'static [u32] = &Self::I.0;
 
     unsafe fn shuffle<T, const M: usize>(&self, a: Simd<T, M>, b: Simd<T, M>) -> Simd<T, N>
     where
@@ -26,7 +26,7 @@ trait Shuffle<const N: usize> {
         #[cfg(old)]
         return simd_shuffle(a, b, Self::I);
         #[cfg(generic)]
-        return simd_shuffle_generic::<_, _, { &Self::I }>(a, b);
+        return simd_shuffle_generic::<_, _, { &Self::I.0 }>(a, b);
         //[generic]~^ overly complex generic constant
         #[cfg(generic_with_fn)]
         return simd_shuffle_generic::<_, _, { Self::J }>(a, b);
@@ -38,12 +38,12 @@ struct Thing<const X: &'static [u32]>;
 fn main() {
     struct I1;
     impl Shuffle<4> for I1 {
-        const I: [u32; 4] = [0, 2, 4, 6];
+        const I: Simd<u32, 4> = Simd([0, 2, 4, 6]);
     }
 
     struct I2;
     impl Shuffle<2> for I2 {
-        const I: [u32; 2] = [1, 5];
+        const I: Simd<u32, 2> = Simd([1, 5]);
     }
 
     let a = Simd::<u8, 4>([0, 1, 2, 3]);
diff --git a/tests/ui/simd/not-out-of-bounds.rs b/tests/ui/simd/not-out-of-bounds.rs
index 36d7a5865bc..4bd2a69edbf 100644
--- a/tests/ui/simd/not-out-of-bounds.rs
+++ b/tests/ui/simd/not-out-of-bounds.rs
@@ -30,6 +30,9 @@ struct u8x64([u8; 64]);
 
 use std::intrinsics::simd::*;
 
+#[repr(simd)]
+struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
+
 // Test vectors by lane size. Since LLVM does not distinguish between a shuffle
 // over two f32s and a shuffle over two u64s, or any other such combination,
 // it is not necessary to test every possible vector, only lane counts.
@@ -37,26 +40,26 @@ macro_rules! test_shuffle_lanes {
     ($n:literal, $x:ident, $y:ident) => {
         unsafe {
                 let shuffle: $x = {
-                    const ARR: [u32; $n] = {
+                    const IDX: SimdShuffleIdx<$n> = SimdShuffleIdx({
                         let mut arr = [0; $n];
                         arr[0] = $n * 2;
                         arr
-                    };
+                    });
                     let mut n: u8 = $n;
                     let vals = [0; $n].map(|_| { n = n - 1; n });
                     let vec1 = $x(vals);
                     let vec2 = $x(vals);
-                    $y(vec1, vec2, ARR)
+                    $y(vec1, vec2, IDX)
                 };
         }
     }
 }
-//~^^^^^ ERROR: invalid monomorphization of `simd_shuffle` intrinsic
-//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
-//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
-//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
-//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
-//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
+//~^^^^^ ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
+//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
+//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
+//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
+//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
+//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
 // Because the test is mostly embedded in a macro, all the errors have the same origin point.
 // And unfortunately, standard comments, as in the UI test harness, disappear in macros!
 
@@ -69,15 +72,15 @@ fn main() {
     test_shuffle_lanes!(64, u8x64, simd_shuffle);
 
     let v = u8x2([0, 0]);
-    const I: [u32; 2] = [4, 4];
+    const I: SimdShuffleIdx<2> = SimdShuffleIdx([4, 4]);
     unsafe {
         let _: u8x2 = simd_shuffle(v, v, I);
-        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
     }
 
     // also check insert/extract
     unsafe {
-        simd_insert(v, 2, 0); //~ ERROR invalid monomorphization of `simd_insert` intrinsic
-        let _val: u8 = simd_extract(v, 2); //~ ERROR invalid monomorphization of `simd_extract` intrinsic
+        simd_insert(v, 2, 0u8); //~ ERROR invalid monomorphization of `simd_insert` intrinsic: SIMD index #1 is out of bounds
+        let _val: u8 = simd_extract(v, 2); //~ ERROR invalid monomorphization of `simd_extract` intrinsic: SIMD index #1 is out of bounds
     }
 }
diff --git a/tests/ui/simd/not-out-of-bounds.stderr b/tests/ui/simd/not-out-of-bounds.stderr
index 5682935c1f1..4b6bda93e45 100644
--- a/tests/ui/simd/not-out-of-bounds.stderr
+++ b/tests/ui/simd/not-out-of-bounds.stderr
@@ -1,7 +1,7 @@
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4)
-  --> $DIR/not-out-of-bounds.rs:49:21
+  --> $DIR/not-out-of-bounds.rs:52:21
    |
-LL |                     $y(vec1, vec2, ARR)
+LL |                     $y(vec1, vec2, IDX)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     test_shuffle_lanes!(2, u8x2, simd_shuffle);
@@ -10,9 +10,9 @@ LL |     test_shuffle_lanes!(2, u8x2, simd_shuffle);
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 8)
-  --> $DIR/not-out-of-bounds.rs:49:21
+  --> $DIR/not-out-of-bounds.rs:52:21
    |
-LL |                     $y(vec1, vec2, ARR)
+LL |                     $y(vec1, vec2, IDX)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     test_shuffle_lanes!(4, u8x4, simd_shuffle);
@@ -21,9 +21,9 @@ LL |     test_shuffle_lanes!(4, u8x4, simd_shuffle);
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 16)
-  --> $DIR/not-out-of-bounds.rs:49:21
+  --> $DIR/not-out-of-bounds.rs:52:21
    |
-LL |                     $y(vec1, vec2, ARR)
+LL |                     $y(vec1, vec2, IDX)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     test_shuffle_lanes!(8, u8x8, simd_shuffle);
@@ -32,9 +32,9 @@ LL |     test_shuffle_lanes!(8, u8x8, simd_shuffle);
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 32)
-  --> $DIR/not-out-of-bounds.rs:49:21
+  --> $DIR/not-out-of-bounds.rs:52:21
    |
-LL |                     $y(vec1, vec2, ARR)
+LL |                     $y(vec1, vec2, IDX)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     test_shuffle_lanes!(16, u8x16, simd_shuffle);
@@ -43,9 +43,9 @@ LL |     test_shuffle_lanes!(16, u8x16, simd_shuffle);
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 64)
-  --> $DIR/not-out-of-bounds.rs:49:21
+  --> $DIR/not-out-of-bounds.rs:52:21
    |
-LL |                     $y(vec1, vec2, ARR)
+LL |                     $y(vec1, vec2, IDX)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     test_shuffle_lanes!(32, u8x32, simd_shuffle);
@@ -54,9 +54,9 @@ LL |     test_shuffle_lanes!(32, u8x32, simd_shuffle);
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 128)
-  --> $DIR/not-out-of-bounds.rs:49:21
+  --> $DIR/not-out-of-bounds.rs:52:21
    |
-LL |                     $y(vec1, vec2, ARR)
+LL |                     $y(vec1, vec2, IDX)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     test_shuffle_lanes!(64, u8x64, simd_shuffle);
@@ -65,19 +65,19 @@ LL |     test_shuffle_lanes!(64, u8x64, simd_shuffle);
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4)
-  --> $DIR/not-out-of-bounds.rs:74:23
+  --> $DIR/not-out-of-bounds.rs:77:23
    |
 LL |         let _: u8x2 = simd_shuffle(v, v, I);
    |                       ^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `u8` (element of input `u8x2`), found `i32`
-  --> $DIR/not-out-of-bounds.rs:80:9
+error[E0511]: invalid monomorphization of `simd_insert` intrinsic: SIMD index #1 is out of bounds (limit 2)
+  --> $DIR/not-out-of-bounds.rs:83:9
    |
-LL |         simd_insert(v, 2, 0);
-   |         ^^^^^^^^^^^^^^^^^^^^
+LL |         simd_insert(v, 2, 0u8);
+   |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_extract` intrinsic: SIMD index #1 is out of bounds (limit 2)
-  --> $DIR/not-out-of-bounds.rs:81:24
+  --> $DIR/not-out-of-bounds.rs:84:24
    |
 LL |         let _val: u8 = simd_extract(v, 2);
    |                        ^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/shuffle.rs b/tests/ui/simd/shuffle.rs
index dc0d688284e..96c0ed2118f 100644
--- a/tests/ui/simd/shuffle.rs
+++ b/tests/ui/simd/shuffle.rs
@@ -16,16 +16,13 @@ extern "rust-intrinsic" {
 #[repr(simd)]
 struct Simd<T, const N: usize>([T; N]);
 
-unsafe fn __shuffle_vector16<const IDX: [u32; 16], T, U>(x: T, y: T) -> U {
-    simd_shuffle(x, y, IDX)
-}
-unsafe fn __shuffle_vector16_v2<const IDX: Simd<u32, 16>, T, U>(x: T, y: T) -> U {
+unsafe fn __shuffle_vector16<const IDX: Simd<u32, 16>, T, U>(x: T, y: T) -> U {
     simd_shuffle(x, y, IDX)
 }
 
 fn main() {
-    const I1: [u32; 4] = [0, 2, 4, 6];
-    const I2: [u32; 2] = [1, 5];
+    const I1: Simd<u32, 4> = Simd([0, 2, 4, 6]);
+    const I2: Simd<u32, 2> = Simd([1, 5]);
     let a = Simd::<u8, 4>([0, 1, 2, 3]);
     let b = Simd::<u8, 4>([4, 5, 6, 7]);
     unsafe {
@@ -35,16 +32,6 @@ fn main() {
         let y: Simd<u8, 2> = simd_shuffle(a, b, I2);
         assert_eq!(y.0, [1, 5]);
     }
-    // Test that we can also use a SIMD vector instead of a normal array for the shuffle.
-    const I1_SIMD: Simd<u32, 4> = Simd([0, 2, 4, 6]);
-    const I2_SIMD: Simd<u32, 2> = Simd([1, 5]);
-    unsafe {
-        let x: Simd<u8, 4> = simd_shuffle(a, b, I1_SIMD);
-        assert_eq!(x.0, [0, 2, 4, 6]);
-
-        let y: Simd<u8, 2> = simd_shuffle(a, b, I2_SIMD);
-        assert_eq!(y.0, [1, 5]);
-    }
 
     // Test that an indirection (via an unnamed constant)
     // through a const generic parameter also works.
@@ -53,13 +40,6 @@ fn main() {
     let b = Simd::<u8, 16>([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]);
     unsafe {
         __shuffle_vector16::<
-            { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] },
-            Simd<u8, 16>,
-            Simd<u8, 16>,
-        >(a, b);
-    }
-    unsafe {
-        __shuffle_vector16_v2::<
             { Simd([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) },
             Simd<u8, 16>,
             Simd<u8, 16>,