diff options
| author | Caleb Zulawski <caleb.zulawski@gmail.com> | 2021-09-11 14:47:28 +0000 |
|---|---|---|
| committer | Caleb Zulawski <caleb.zulawski@gmail.com> | 2021-09-11 14:55:14 +0000 |
| commit | 1b3fe755ea3d39a1875f627fab5def4eae03e912 (patch) | |
| tree | a2fc1b6f1ffd29360478062716f30da422eb7945 /compiler/rustc_codegen_llvm/src | |
| parent | b69fe57261086e70aea9d5b58819a1794bf7c121 (diff) | |
| download | rust-1b3fe755ea3d39a1875f627fab5def4eae03e912.tar.gz rust-1b3fe755ea3d39a1875f627fab5def4eae03e912.zip | |
Allow simd_shuffle to accept vectors of any length
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/intrinsic.rs | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 1aa52d975e9..f6219b06d2d 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -918,12 +918,29 @@ fn generic_simd_intrinsic( } if let Some(stripped) = name_str.strip_prefix("simd_shuffle") { - let n: u64 = stripped.parse().unwrap_or_else(|_| { - span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") - }); + // If this intrinsic is the older "simd_shuffleN" form, simply parse the integer. + // If there is no suffix, use the index array length. + let n: u64 = if stripped.is_empty() { + // Make sure this is actually an array, since typeck only checks the length-suffixed + // version of this intrinsic. + match args[2].layout.ty.kind() { + ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { + len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| { + span_bug!(span, "could not evaluate shuffle index array length") + }) + } + _ => return_error!( + "simd_shuffle index must be an array of `u32`, got `{}`", + args[2].layout.ty + ), + } + } else { + stripped.parse().unwrap_or_else(|_| { + span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") + }) + }; require_simd!(ret_ty, "return"); - let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( out_len == n, |
