From 60ee1b7ac6e1c18679573d4a752e6fc02790d892 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 12 Sep 2024 11:33:13 +0200 Subject: [PATCH] simd_shuffle: require index argument to be a vector --- .../src/intrinsics/simd.rs | 40 +++------- compiler/rustc_codegen_gcc/src/builder.rs | 39 +++------ .../rustc_codegen_gcc/src/intrinsic/simd.rs | 25 ++---- compiler/rustc_codegen_llvm/src/intrinsic.rs | 80 +++++++------------ compiler/rustc_codegen_ssa/messages.ftl | 2 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 28 +------ .../rustc_codegen_ssa/src/mir/constant.rs | 35 +++----- library/core/src/intrinsics/simd.rs | 2 +- .../crates/core_simd/src/swizzle.rs | 16 +++- src/tools/miri/src/intrinsics/simd.rs | 8 +- .../tests/pass/intrinsics/portable-simd.rs | 5 -- tests/incremental/issue-61530.rs | 5 +- .../simd/intrinsic/generic-elements-pass.rs | 48 +++++++---- tests/ui/simd/intrinsic/generic-elements.rs | 9 ++- .../ui/simd/intrinsic/generic-elements.stderr | 42 +++++----- tests/ui/simd/intrinsic/generic-shuffle.rs | 7 +- .../ui/simd/intrinsic/generic-shuffle.stderr | 16 ++-- .../simd/intrinsic/inlining-issue67557-ice.rs | 5 +- .../ui/simd/intrinsic/inlining-issue67557.rs | 7 +- .../monomorphize-shuffle-index.generic.stderr | 4 +- tests/ui/simd/monomorphize-shuffle-index.rs | 10 +-- tests/ui/simd/not-out-of-bounds.rs | 29 ++++--- tests/ui/simd/not-out-of-bounds.stderr | 36 ++++----- tests/ui/simd/shuffle.rs | 26 +----- 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 604a88393fd95..a5621aec2444f 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 6ba678e2e7c65..31d778823e076 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 96a833ccaf2b6..2eabc1430db5e 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 05fb77a193af3..9705dd506b97b 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> = (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 8a6a2acd87d44..9091602d75b71 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 817e2ca72ec12..8f96c46224098 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 0aa85b8203825..8254fb3d8661e 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 5982819809937..5ddca9c4dce88 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 2f4f777b20e29..d62642fb9061b 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 { LaneCount: SupportedLaneCount, LaneCount: 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 { output[i] = index as u32; i += 1; } - output + + // The index list needs to be returned as a vector. + #[repr(simd)] + struct SimdShuffleIdx([u32; LEN]); + SimdShuffleIdx(output) }, ) } @@ -121,7 +125,7 @@ pub trait Swizzle { LaneCount: SupportedLaneCount, LaneCount: 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 { output[i] = index as u32; i += 1; } - output + + // The index list needs to be returned as a vector. + #[repr(simd)] + struct SimdShuffleIdx([u32; LEN]); + SimdShuffleIdx(output) }, ) } diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index aa91b89d0ec6b..e22306ca82fcf 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 daf75fee8fe13..4c0d6f52425cd 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, @@ -628,10 +627,6 @@ fn simd_intrinsics() { simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b), 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 b4914dda11ae1..71ac39d0e039e 100644 --- a/tests/incremental/issue-61530.rs +++ b/tests/incremental/issue-61530.rs @@ -9,9 +9,12 @@ extern "rust-intrinsic" { fn simd_shuffle(x: T, y: T, idx: I) -> U; } +#[repr(simd)] +struct SimdShuffleIdx([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 b159387ab62cc..7b1bda4fbcd5f 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(x: T, y: T, idx: I) -> U; } +#[repr(simd)] +struct SimdShuffleIdx([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 4848fd1b803af..5d784a25eab4a 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(x: T, y: T) -> U; } +#[repr(simd)] +struct SimdShuffleIdx([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::(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::(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::(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 0788a7c17f994..fd726d7532600 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::(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::(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::(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::(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::(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::(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 c0888f6778414..2752718d99d6b 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 = Simd([0; 2]); + const I2: Simd = Simd([0.; 2]); let v = Simd::([0; 4]); unsafe { let _: Simd = simd_shuffle(v, v, I); + let _: Simd = simd_shuffle(v, v, const { [0u32; 2] }); + //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic + let _: Simd = 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 81e641612ce00..7e6d51a5f6555 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` 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 = simd_shuffle(v, v, const { [0u32; 2] }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd` with length 4 + --> $DIR/generic-shuffle.rs:27:31 + | LL | let _: Simd = simd_shuffle(v, v, I); | ^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd`), found `Simd` with element type `f32` - --> $DIR/generic-shuffle.rs:27:31 + --> $DIR/generic-shuffle.rs:30:31 | LL | let _: Simd = 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` + --> $DIR/generic-shuffle.rs:33:31 | LL | let _: Simd = 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 a64a7c0b48a1e..d9239ef5801ae 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([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 cb80d65d46838..23dd5075f96b6 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([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 c4cfca7be1d5e..2d1fa1f8da225 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 30c345cb90471..140cf6fbe96a9 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; N]); trait Shuffle { - const I: [u32; N]; - const J: &'static [u32] = &Self::I; + const I: Simd; + const J: &'static [u32] = &Self::I.0; unsafe fn shuffle(&self, a: Simd, b: Simd) -> Simd where @@ -26,7 +26,7 @@ trait Shuffle { #[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; fn main() { struct I1; impl Shuffle<4> for I1 { - const I: [u32; 4] = [0, 2, 4, 6]; + const I: Simd = Simd([0, 2, 4, 6]); } struct I2; impl Shuffle<2> for I2 { - const I: [u32; 2] = [1, 5]; + const I: Simd = Simd([1, 5]); } let a = Simd::([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 36d7a5865bc54..4bd2a69edbf5e 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([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 5682935c1f1ae..4b6bda93e4561 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 dc0d688284e3c..96c0ed2118f9e 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; N]); -unsafe fn __shuffle_vector16(x: T, y: T) -> U { - simd_shuffle(x, y, IDX) -} -unsafe fn __shuffle_vector16_v2, T, U>(x: T, y: T) -> U { +unsafe fn __shuffle_vector16, 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 = Simd([0, 2, 4, 6]); + const I2: Simd = Simd([1, 5]); let a = Simd::([0, 1, 2, 3]); let b = Simd::([4, 5, 6, 7]); unsafe { @@ -35,16 +32,6 @@ fn main() { let y: Simd = 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 = Simd([0, 2, 4, 6]); - const I2_SIMD: Simd = Simd([1, 5]); - unsafe { - let x: Simd = simd_shuffle(a, b, I1_SIMD); - assert_eq!(x.0, [0, 2, 4, 6]); - - let y: Simd = 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::([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, - Simd, - >(a, b); - } - unsafe { - __shuffle_vector16_v2::< { Simd([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) }, Simd, Simd,