rustc: Add an unstable simd_select_bitmask intrinsic
This is going to be required for binding a number of AVX-512 intrinsics in the `stdsimd` repository, and this intrinsic is the same as `simd_select` except that it takes a bitmask as the first argument instead of a SIMD vector. This bitmask is then transmuted into a `<NN x i8>` argument, depending on how many bits it is. cc rust-lang-nursery/stdsimd#310
This commit is contained in:
@@ -1171,6 +1171,27 @@ fn generic_simd_intrinsic(
|
||||
);
|
||||
let arg_tys = sig.inputs();
|
||||
|
||||
if name == "simd_select_bitmask" {
|
||||
let in_ty = arg_tys[0];
|
||||
let m_len = match in_ty.sty {
|
||||
// Note that this `.unwrap()` crashes for isize/usize, that's sort
|
||||
// of intentional as there's not currently a use case for that.
|
||||
ty::Int(i) => i.bit_width().unwrap(),
|
||||
ty::Uint(i) => i.bit_width().unwrap(),
|
||||
_ => return_error!("`{}` is not an integral type", in_ty),
|
||||
};
|
||||
require_simd!(arg_tys[1], "argument");
|
||||
let v_len = arg_tys[1].simd_size(tcx);
|
||||
require!(m_len == v_len,
|
||||
"mismatched lengths: mask length `{}` != other vector length `{}`",
|
||||
m_len, v_len
|
||||
);
|
||||
let i1 = bx.type_i1();
|
||||
let i1xn = bx.type_vector(i1, m_len as u64);
|
||||
let m_i1s = bx.bitcast(args[0].immediate(), i1xn);
|
||||
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
|
||||
}
|
||||
|
||||
// every intrinsic takes a SIMD vector as its first argument
|
||||
require_simd!(arg_tys[0], "input");
|
||||
let in_ty = arg_tys[0];
|
||||
|
||||
Reference in New Issue
Block a user