simd_shuffle: require index argument to be a vector
This commit is contained in:
parent
0307e401c2
commit
60ee1b7ac6
@ -180,34 +180,20 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure this is actually an array, since typeck only checks the length-suffixed
|
// Make sure this is actually a SIMD vector.
|
||||||
// version of this intrinsic.
|
|
||||||
let idx_ty = fx.monomorphize(idx.node.ty(fx.mir, fx.tcx));
|
let idx_ty = fx.monomorphize(idx.node.ty(fx.mir, fx.tcx));
|
||||||
let n: u16 = match idx_ty.kind() {
|
let n: u16 = if idx_ty.is_simd()
|
||||||
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => len
|
&& matches!(idx_ty.simd_size_and_type(fx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
|
||||||
.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
|
{
|
||||||
.unwrap_or_else(|| {
|
idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap()
|
||||||
span_bug!(span, "could not evaluate shuffle index array length")
|
} else {
|
||||||
})
|
fx.tcx.dcx().span_err(
|
||||||
.try_into()
|
span,
|
||||||
.unwrap(),
|
format!("simd_shuffle index must be a SIMD vector of `u32`, got `{}`", idx_ty),
|
||||||
_ if idx_ty.is_simd()
|
);
|
||||||
&& matches!(
|
// Prevent verifier error
|
||||||
idx_ty.simd_size_and_type(fx.tcx).1.kind(),
|
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
|
||||||
ty::Uint(ty::UintTy::U32)
|
return;
|
||||||
) =>
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(x.layout(), y.layout());
|
assert_eq!(x.layout(), y.layout());
|
||||||
|
@ -1939,33 +1939,18 @@ pub fn shuffle_vector(
|
|||||||
self.int_type
|
self.int_type
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() {
|
let vector_type =
|
||||||
let mask_num_units = vector_type.get_num_units();
|
mask.get_type().dyncast_vector().expect("simd_shuffle mask should be of vector type");
|
||||||
let mut mask_elements = vec![];
|
let mask_num_units = vector_type.get_num_units();
|
||||||
for i in 0..mask_num_units {
|
let mut mask_elements = vec![];
|
||||||
let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
|
for i in 0..mask_num_units {
|
||||||
mask_elements.push(self.context.new_cast(
|
let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
|
||||||
self.location,
|
mask_elements.push(self.context.new_cast(
|
||||||
self.extract_element(mask, index).to_rvalue(),
|
self.location,
|
||||||
mask_element_type,
|
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();
|
|
||||||
|
|
||||||
// NOTE: the mask needs to be the same length as the input vectors, so add the missing
|
// NOTE: the mask needs to be the same length as the input vectors, so add the missing
|
||||||
// elements in the mask if needed.
|
// elements in the mask if needed.
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#[cfg(feature = "master")]
|
#[cfg(feature = "master")]
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::mir::BinOp;
|
use rustc_middle::mir::BinOp;
|
||||||
use rustc_middle::span_bug;
|
|
||||||
use rustc_middle::ty::layout::HasTyCtxt;
|
use rustc_middle::ty::layout::HasTyCtxt;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::{sym, Span, Symbol};
|
use rustc_span::{sym, Span, Symbol};
|
||||||
@ -353,24 +352,14 @@ macro_rules! require_simd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if name == sym::simd_shuffle {
|
if name == sym::simd_shuffle {
|
||||||
// Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
|
// Make sure this is actually a SIMD vector.
|
||||||
// version of this intrinsic.
|
|
||||||
let idx_ty = args[2].layout.ty;
|
let idx_ty = args[2].layout.ty;
|
||||||
let n: u64 = match idx_ty.kind() {
|
let n: u64 = if idx_ty.is_simd()
|
||||||
ty::Array(ty, len) if matches!(*ty.kind(), ty::Uint(ty::UintTy::U32)) => {
|
&& matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.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"),
|
idx_ty.simd_size_and_type(bx.cx.tcx).0
|
||||||
)
|
} else {
|
||||||
}
|
return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty })
|
||||||
_ 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 }),
|
|
||||||
};
|
};
|
||||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||||
|
|
||||||
|
@ -573,6 +573,8 @@ fn codegen_intrinsic_call(
|
|||||||
span,
|
span,
|
||||||
) {
|
) {
|
||||||
Ok(llval) => llval,
|
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(()),
|
Err(()) => return Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1290,24 +1292,14 @@ macro_rules! require_simd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if name == sym::simd_shuffle {
|
if name == sym::simd_shuffle {
|
||||||
// Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
|
// Make sure this is actually a SIMD vector.
|
||||||
// version of this intrinsic.
|
|
||||||
let idx_ty = args[2].layout.ty;
|
let idx_ty = args[2].layout.ty;
|
||||||
let n: u64 = match idx_ty.kind() {
|
let n: u64 = if idx_ty.is_simd()
|
||||||
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
|
&& matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.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"),
|
idx_ty.simd_size_and_type(bx.cx.tcx).0
|
||||||
)
|
} else {
|
||||||
}
|
return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty })
|
||||||
_ 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 (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
|
let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
|
||||||
@ -1322,38 +1314,24 @@ macro_rules! require_simd {
|
|||||||
|
|
||||||
let total_len = u128::from(in_len) * 2;
|
let total_len = u128::from(in_len) * 2;
|
||||||
|
|
||||||
let vector = args[2].immediate();
|
// 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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let indices: Option<Vec<_>> = (0..n)
|
return Ok(bx.shuffle_vector(args[0].immediate(), args[1].immediate(), indices));
|
||||||
.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));
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok(bx.shuffle_vector(
|
|
||||||
args[0].immediate(),
|
|
||||||
args[1].immediate(),
|
|
||||||
bx.const_vector(&indices),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if name == sym::simd_insert {
|
if name == sym::simd_insert {
|
||||||
@ -1371,13 +1349,12 @@ macro_rules! require_simd {
|
|||||||
.const_to_opt_u128(args[1].immediate(), false)
|
.const_to_opt_u128(args[1].immediate(), false)
|
||||||
.expect("typeck should have ensure that this is a const");
|
.expect("typeck should have ensure that this is a const");
|
||||||
if idx >= in_len.into() {
|
if idx >= in_len.into() {
|
||||||
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
|
return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
arg_idx: 1,
|
arg_idx: 1,
|
||||||
total_len: in_len.into(),
|
total_len: in_len.into(),
|
||||||
});
|
});
|
||||||
return Ok(bx.const_null(llret_ty));
|
|
||||||
}
|
}
|
||||||
return Ok(bx.insert_element(
|
return Ok(bx.insert_element(
|
||||||
args[0].immediate(),
|
args[0].immediate(),
|
||||||
@ -1394,13 +1371,12 @@ macro_rules! require_simd {
|
|||||||
.const_to_opt_u128(args[1].immediate(), false)
|
.const_to_opt_u128(args[1].immediate(), false)
|
||||||
.expect("typeck should have ensure that this is a const");
|
.expect("typeck should have ensure that this is a const");
|
||||||
if idx >= in_len.into() {
|
if idx >= in_len.into() {
|
||||||
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
|
return_error!(InvalidMonomorphization::SimdIndexOutOfBounds {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
arg_idx: 1,
|
arg_idx: 1,
|
||||||
total_len: in_len.into(),
|
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)));
|
return Ok(bx.extract_element(args[0].immediate(), bx.const_i32(idx as i32)));
|
||||||
}
|
}
|
||||||
|
@ -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_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}`
|
codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`
|
||||||
|
|
||||||
|
@ -915,32 +915,8 @@ fn codegen_call_terminator(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let args: Vec<_> = args
|
let args: Vec<_> =
|
||||||
.iter()
|
args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect();
|
||||||
.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();
|
|
||||||
|
|
||||||
if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) {
|
if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) {
|
||||||
let location = self
|
let location = self
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::ty::layout::HasTyCtxt;
|
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_middle::{bug, mir, span_bug};
|
||||||
use rustc_target::abi::Abi;
|
use rustc_target::abi::Abi;
|
||||||
|
|
||||||
@ -66,15 +66,8 @@ pub fn immediate_const_vector(
|
|||||||
constant: &mir::ConstOperand<'tcx>,
|
constant: &mir::ConstOperand<'tcx>,
|
||||||
) -> (Bx::Value, Ty<'tcx>) {
|
) -> (Bx::Value, Ty<'tcx>) {
|
||||||
let ty = self.monomorphize(constant.ty());
|
let ty = self.monomorphize(constant.ty());
|
||||||
let ty_is_simd = ty.is_simd();
|
assert!(ty.is_simd());
|
||||||
// FIXME: ideally we'd assert that this is a SIMD type, but simd_shuffle
|
let field_ty = ty.simd_size_and_type(bx.tcx()).1;
|
||||||
// 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()
|
|
||||||
};
|
|
||||||
|
|
||||||
let val = self
|
let val = self
|
||||||
.eval_unevaluated_mir_constant_to_valtree(constant)
|
.eval_unevaluated_mir_constant_to_valtree(constant)
|
||||||
@ -82,19 +75,13 @@ pub fn immediate_const_vector(
|
|||||||
.map(|x| x.ok())
|
.map(|x| x.ok())
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|val| {
|
.map(|val| {
|
||||||
// Depending on whether this is a SIMD type with an array field
|
// A SIMD type has a single field, which is an array.
|
||||||
// or a type with many fields (one for each elements), the valtree
|
let fields = val.unwrap_branch();
|
||||||
// is either a single branch with N children, or a root node
|
assert_eq!(fields.len(), 1);
|
||||||
// with exactly one child which then in turn has many children.
|
let array = fields[0].unwrap_branch();
|
||||||
// So we look at the first child to determine whether it is a
|
// Iterate over the array elements to obtain the values in the vector.
|
||||||
// leaf or whether we have to go one more layer down.
|
let values: Vec<_> = array
|
||||||
let branch_or_leaf = val.unwrap_branch();
|
.iter()
|
||||||
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
|
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
if let Some(prim) = field.try_to_scalar() {
|
if let Some(prim) = field.try_to_scalar() {
|
||||||
let layout = bx.layout_of(field_ty);
|
let layout = bx.layout_of(field_ty);
|
||||||
@ -107,7 +94,7 @@ pub fn immediate_const_vector(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
if ty_is_simd { bx.const_vector(&values) } else { bx.const_struct(&values, false) }
|
bx.const_vector(&values)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });
|
bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });
|
||||||
|
@ -232,7 +232,7 @@
|
|||||||
///
|
///
|
||||||
/// `T` must be a vector.
|
/// `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 { ... }`).
|
/// 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`.
|
/// `V` must be a vector with the same element type as `T` and the same length as `U`.
|
||||||
|
@ -85,7 +85,7 @@ fn swizzle<T, const M: usize>(vector: Simd<T, M>) -> Simd<T, N>
|
|||||||
LaneCount<N>: SupportedLaneCount,
|
LaneCount<N>: SupportedLaneCount,
|
||||||
LaneCount<M>: 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 {
|
unsafe {
|
||||||
core::intrinsics::simd::simd_shuffle(
|
core::intrinsics::simd::simd_shuffle(
|
||||||
vector,
|
vector,
|
||||||
@ -103,7 +103,11 @@ fn swizzle<T, const M: usize>(vector: Simd<T, M>) -> Simd<T, N>
|
|||||||
output[i] = index as u32;
|
output[i] = index as u32;
|
||||||
i += 1;
|
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 @@ fn concat_swizzle<T, const M: usize>(first: Simd<T, M>, second: Simd<T, M>) -> S
|
|||||||
LaneCount<N>: SupportedLaneCount,
|
LaneCount<N>: SupportedLaneCount,
|
||||||
LaneCount<M>: 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 {
|
unsafe {
|
||||||
core::intrinsics::simd::simd_shuffle(
|
core::intrinsics::simd::simd_shuffle(
|
||||||
first,
|
first,
|
||||||
@ -139,7 +143,11 @@ fn concat_swizzle<T, const M: usize>(first: Simd<T, M>, second: Simd<T, M>) -> S
|
|||||||
output[i] = index as u32;
|
output[i] = index as u32;
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
output
|
|
||||||
|
// The index list needs to be returned as a vector.
|
||||||
|
#[repr(simd)]
|
||||||
|
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
|
||||||
|
SimdShuffleIdx(output)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -664,15 +664,9 @@ enum Op {
|
|||||||
let [left, right, index] = check_arg_count(args)?;
|
let [left, right, index] = check_arg_count(args)?;
|
||||||
let (left, left_len) = this.project_to_simd(left)?;
|
let (left, left_len) = this.project_to_simd(left)?;
|
||||||
let (right, right_len) = this.project_to_simd(right)?;
|
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)?;
|
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!(left_len, right_len);
|
||||||
assert_eq!(index_len, dest_len);
|
assert_eq!(index_len, dest_len);
|
||||||
|
|
||||||
|
@ -619,7 +619,6 @@ fn simd_intrinsics() {
|
|||||||
i32x4::from_array([10, 2, 10, 10])
|
i32x4::from_array([10, 2, 10, 10])
|
||||||
);
|
);
|
||||||
assert_eq!(simd_shuffle_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,);
|
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!(
|
assert_eq!(
|
||||||
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([3u32, 1, 0, 2]) }),
|
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([3u32, 1, 0, 2]) }),
|
||||||
a,
|
a,
|
||||||
@ -628,10 +627,6 @@ fn simd_intrinsics() {
|
|||||||
simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b),
|
simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b),
|
||||||
i32x4::from_array([4, 2, 1, 10]),
|
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!(
|
assert_eq!(
|
||||||
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([7u32, 5, 4, 6]) }),
|
simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([7u32, 5, 4, 6]) }),
|
||||||
i32x4::from_array([4, 2, 1, 10]),
|
i32x4::from_array([4, 2, 1, 10]),
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
|
fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(simd)]
|
||||||
|
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
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);
|
||||||
let _: I32x2 = simd_shuffle(I32x2([1, 2]), I32x2([3, 4]), IDX);
|
let _: I32x2 = simd_shuffle(I32x2([1, 2]), I32x2([3, 4]), IDX);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
|
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 {
|
macro_rules! all_eq {
|
||||||
($a: expr, $b: expr) => {{
|
($a: expr, $b: expr) => {{
|
||||||
let a = $a;
|
let a = $a;
|
||||||
@ -30,9 +33,8 @@ macro_rules! all_eq {
|
|||||||
// type inference works better with the concrete type on the
|
// type inference works better with the concrete type on the
|
||||||
// left, but humans work better with the expected on the
|
// left, but humans work better with the expected on the
|
||||||
// right.
|
// right.
|
||||||
assert!(b == a,
|
assert!(b == a, "{:?} != {:?}", a, b);
|
||||||
"{:?} != {:?}", a, b);
|
}};
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -79,20 +81,34 @@ fn main() {
|
|||||||
let y4 = i32x4([140, 141, 142, 143]);
|
let y4 = i32x4([140, 141, 142, 143]);
|
||||||
let y8 = i32x8([180, 181, 182, 183, 184, 185, 186, 187]);
|
let y8 = i32x8([180, 181, 182, 183, 184, 185, 186, 187]);
|
||||||
unsafe {
|
unsafe {
|
||||||
all_eq!(simd_shuffle(x2, y2, const { [3u32, 0] }), i32x2([121, 20]));
|
all_eq!(simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0]) }), i32x2([121, 20]));
|
||||||
all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2] }), i32x4([121, 20, 21, 120]));
|
all_eq!(
|
||||||
all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2, 1, 2, 3, 0] }),
|
simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0, 1, 2]) }),
|
||||||
i32x8([121, 20, 21, 120, 21, 120, 121, 20]));
|
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 { SimdShuffleIdx([7u32, 2]) }), i32x2([143, 42]));
|
||||||
all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0] }), i32x4([143, 42, 141, 40]));
|
all_eq!(
|
||||||
all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0, 3, 6, 4, 1] }),
|
simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2, 5, 0]) }),
|
||||||
i32x8([143, 42, 141, 40, 43, 142, 140, 41]));
|
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 { SimdShuffleIdx([11u32, 5]) }), i32x2([183, 85]));
|
||||||
all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0] }), i32x4([183, 85, 187, 80]));
|
all_eq!(
|
||||||
all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0, 3, 8, 12, 1] }),
|
simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5, 15, 0]) }),
|
||||||
i32x8([183, 85, 187, 80, 83, 180, 184, 81]));
|
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])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,9 @@
|
|||||||
fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
|
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() {
|
fn main() {
|
||||||
let x = i32x4([0, 0, 0, 0]);
|
let x = i32x4([0, 0, 0, 0]);
|
||||||
|
|
||||||
@ -48,13 +51,13 @@ fn main() {
|
|||||||
simd_extract::<_, f32>(x, 0);
|
simd_extract::<_, f32>(x, 0);
|
||||||
//~^ ERROR expected return type `i32` (element of input `i32x4`), found `f32`
|
//~^ 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);
|
simd_shuffle::<i32, _, i32>(0, 0, IDX2);
|
||||||
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
|
//~^ 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);
|
simd_shuffle::<i32, _, i32>(0, 0, IDX4);
|
||||||
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
|
//~^ 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);
|
simd_shuffle::<i32, _, i32>(0, 0, IDX8);
|
||||||
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
|
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
|
||||||
|
|
||||||
|
@ -1,125 +1,125 @@
|
|||||||
error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32`
|
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);
|
LL | simd_insert(0, 0, 0);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64`
|
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);
|
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`
|
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);
|
LL | simd_extract::<_, f32>(x, 0);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
|
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);
|
LL | simd_shuffle::<i32, _, i32>(0, 0, IDX2);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
|
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);
|
LL | simd_shuffle::<i32, _, i32>(0, 0, IDX4);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
|
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);
|
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`
|
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);
|
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`
|
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);
|
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`
|
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);
|
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
|
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);
|
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
|
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);
|
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
|
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);
|
LL | simd_shuffle::<_, _, i32x2>(x, x, IDX8);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
|
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);
|
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`
|
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);
|
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`
|
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);
|
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`
|
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);
|
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`
|
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);
|
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`
|
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);
|
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
|
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);
|
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
|
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);
|
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
|
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);
|
LL | simd_shuffle_generic::<_, i32x2, I8>(x, x);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -14,13 +14,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
const I: [u32; 2] = [0; 2];
|
const I: Simd<u32, 2> = Simd([0; 2]);
|
||||||
const I2: [f32; 2] = [0.; 2];
|
const I2: Simd<f32, 2> = Simd([0.; 2]);
|
||||||
let v = Simd::<u32, 4>([0; 4]);
|
let v = Simd::<u32, 4>([0; 4]);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let _: Simd<u32, 2> = simd_shuffle(v, v, I);
|
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);
|
let _: Simd<u32, 4> = simd_shuffle(v, v, I);
|
||||||
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
|
//~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
|
||||||
|
|
||||||
|
@ -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
|
--> $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);
|
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`
|
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);
|
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]`
|
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:30:31
|
--> $DIR/generic-shuffle.rs:33:31
|
||||||
|
|
|
|
||||||
LL | let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
|
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`.
|
For more information about this error, try `rustc --explain E0511`.
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct Simd2([u8; 2]);
|
struct Simd2([u8; 2]);
|
||||||
|
|
||||||
|
#[repr(simd)]
|
||||||
|
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _: Simd2 = inline_me();
|
let _: Simd2 = inline_me();
|
||||||
@ -21,6 +24,6 @@ fn main() {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn inline_me() -> Simd2 {
|
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)
|
simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX)
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,12 @@
|
|||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct Simd2([u8; 2]);
|
struct Simd2([u8; 2]);
|
||||||
|
|
||||||
|
#[repr(simd)]
|
||||||
|
struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
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 p_res: Simd2 = simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX);
|
||||||
let a_res: Simd2 = inline_me();
|
let a_res: Simd2 = inline_me();
|
||||||
|
|
||||||
@ -37,6 +40,6 @@ fn assert_10_13(x: Simd2) {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn inline_me() -> Simd2 {
|
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)
|
simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX)
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: overly complex generic constant
|
error: overly complex generic constant
|
||||||
--> $DIR/monomorphize-shuffle-index.rs:29:45
|
--> $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
|
| pointer casts are not allowed in generic constants
|
||||||
|
|
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
struct Simd<T, const N: usize>([T; N]);
|
struct Simd<T, const N: usize>([T; N]);
|
||||||
|
|
||||||
trait Shuffle<const N: usize> {
|
trait Shuffle<const N: usize> {
|
||||||
const I: [u32; N];
|
const I: Simd<u32, N>;
|
||||||
const J: &'static [u32] = &Self::I;
|
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>
|
unsafe fn shuffle<T, const M: usize>(&self, a: Simd<T, M>, b: Simd<T, M>) -> Simd<T, N>
|
||||||
where
|
where
|
||||||
@ -26,7 +26,7 @@ unsafe fn shuffle<T, const M: usize>(&self, a: Simd<T, M>, b: Simd<T, M>) -> Sim
|
|||||||
#[cfg(old)]
|
#[cfg(old)]
|
||||||
return simd_shuffle(a, b, Self::I);
|
return simd_shuffle(a, b, Self::I);
|
||||||
#[cfg(generic)]
|
#[cfg(generic)]
|
||||||
return simd_shuffle_generic::<_, _, { &Self::I }>(a, b);
|
return simd_shuffle_generic::<_, _, { &Self::I.0 }>(a, b);
|
||||||
//[generic]~^ overly complex generic constant
|
//[generic]~^ overly complex generic constant
|
||||||
#[cfg(generic_with_fn)]
|
#[cfg(generic_with_fn)]
|
||||||
return simd_shuffle_generic::<_, _, { Self::J }>(a, b);
|
return simd_shuffle_generic::<_, _, { Self::J }>(a, b);
|
||||||
@ -38,12 +38,12 @@ unsafe fn shuffle<T, const M: usize>(&self, a: Simd<T, M>, b: Simd<T, M>) -> Sim
|
|||||||
fn main() {
|
fn main() {
|
||||||
struct I1;
|
struct I1;
|
||||||
impl Shuffle<4> for 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;
|
struct I2;
|
||||||
impl Shuffle<2> for 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]);
|
let a = Simd::<u8, 4>([0, 1, 2, 3]);
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
use std::intrinsics::simd::*;
|
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
|
// 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,
|
// 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.
|
// 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) => {
|
($n:literal, $x:ident, $y:ident) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
let shuffle: $x = {
|
let shuffle: $x = {
|
||||||
const ARR: [u32; $n] = {
|
const IDX: SimdShuffleIdx<$n> = SimdShuffleIdx({
|
||||||
let mut arr = [0; $n];
|
let mut arr = [0; $n];
|
||||||
arr[0] = $n * 2;
|
arr[0] = $n * 2;
|
||||||
arr
|
arr
|
||||||
};
|
});
|
||||||
let mut n: u8 = $n;
|
let mut n: u8 = $n;
|
||||||
let vals = [0; $n].map(|_| { n = n - 1; n });
|
let vals = [0; $n].map(|_| { n = n - 1; n });
|
||||||
let vec1 = $x(vals);
|
let vec1 = $x(vals);
|
||||||
let vec2 = $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: SIMD index #0 is out of bounds
|
||||||
//~| 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
|
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
|
||||||
//~| 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
|
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds
|
||||||
//~| ERROR: invalid monomorphization of `simd_shuffle` intrinsic
|
//~| 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.
|
// 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!
|
// 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);
|
test_shuffle_lanes!(64, u8x64, simd_shuffle);
|
||||||
|
|
||||||
let v = u8x2([0, 0]);
|
let v = u8x2([0, 0]);
|
||||||
const I: [u32; 2] = [4, 4];
|
const I: SimdShuffleIdx<2> = SimdShuffleIdx([4, 4]);
|
||||||
unsafe {
|
unsafe {
|
||||||
let _: u8x2 = simd_shuffle(v, v, I);
|
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
|
// also check insert/extract
|
||||||
unsafe {
|
unsafe {
|
||||||
simd_insert(v, 2, 0); //~ ERROR invalid monomorphization of `simd_insert` 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
|
let _val: u8 = simd_extract(v, 2); //~ ERROR invalid monomorphization of `simd_extract` intrinsic: SIMD index #1 is out of bounds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4)
|
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);
|
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)
|
= 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)
|
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);
|
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)
|
= 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)
|
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);
|
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)
|
= 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)
|
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);
|
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)
|
= 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)
|
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);
|
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)
|
= 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)
|
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);
|
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)
|
= 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)
|
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);
|
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`
|
error[E0511]: invalid monomorphization of `simd_insert` intrinsic: SIMD index #1 is out of bounds (limit 2)
|
||||||
--> $DIR/not-out-of-bounds.rs:80:9
|
--> $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)
|
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);
|
LL | let _val: u8 = simd_extract(v, 2);
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -16,16 +16,13 @@
|
|||||||
#[repr(simd)]
|
#[repr(simd)]
|
||||||
struct Simd<T, const N: usize>([T; N]);
|
struct Simd<T, const N: usize>([T; N]);
|
||||||
|
|
||||||
unsafe fn __shuffle_vector16<const IDX: [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)
|
|
||||||
}
|
|
||||||
unsafe fn __shuffle_vector16_v2<const IDX: Simd<u32, 16>, T, U>(x: T, y: T) -> U {
|
|
||||||
simd_shuffle(x, y, IDX)
|
simd_shuffle(x, y, IDX)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
const I1: [u32; 4] = [0, 2, 4, 6];
|
const I1: Simd<u32, 4> = Simd([0, 2, 4, 6]);
|
||||||
const I2: [u32; 2] = [1, 5];
|
const I2: Simd<u32, 2> = Simd([1, 5]);
|
||||||
let a = Simd::<u8, 4>([0, 1, 2, 3]);
|
let a = Simd::<u8, 4>([0, 1, 2, 3]);
|
||||||
let b = Simd::<u8, 4>([4, 5, 6, 7]);
|
let b = Simd::<u8, 4>([4, 5, 6, 7]);
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -35,16 +32,6 @@ fn main() {
|
|||||||
let y: Simd<u8, 2> = simd_shuffle(a, b, I2);
|
let y: Simd<u8, 2> = simd_shuffle(a, b, I2);
|
||||||
assert_eq!(y.0, [1, 5]);
|
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)
|
// Test that an indirection (via an unnamed constant)
|
||||||
// through a const generic parameter also works.
|
// 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]);
|
let b = Simd::<u8, 16>([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]);
|
||||||
unsafe {
|
unsafe {
|
||||||
__shuffle_vector16::<
|
__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([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) },
|
||||||
Simd<u8, 16>,
|
Simd<u8, 16>,
|
||||||
Simd<u8, 16>,
|
Simd<u8, 16>,
|
||||||
|
Loading…
Reference in New Issue
Block a user