diff options
| author | bors <bors@rust-lang.org> | 2024-06-02 13:28:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-06-02 13:28:04 +0000 |
| commit | 5e6c2b6092d63705368cfb96c91188f77b722eaf (patch) | |
| tree | e5ed0703ee3b946d777e1598a3760833b02d7fd1 /compiler/rustc_codegen_llvm/src | |
| parent | 8bec878b73c7a65a4cb6adabcf36bc0510c6cd1e (diff) | |
| parent | 30dc2bafc878eec948cdc4c8bf992708719f1d16 (diff) | |
| download | rust-5e6c2b6092d63705368cfb96c91188f77b722eaf.tar.gz rust-5e6c2b6092d63705368cfb96c91188f77b722eaf.zip | |
Auto merge of #125892 - workingjubilee:rollup-gytt1q7, r=workingjubilee
Rollup of 3 pull requests Successful merges: - #125311 (Make repr(packed) vectors work with SIMD intrinsics) - #125849 (Migrate `run-make/emit-named-files` to `rmake.rs`) - #125851 (Add some more specific checks to the MIR validator) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/intrinsic.rs | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 3d2ce550b23..39bbf87bea7 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -482,8 +482,60 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { } _ if name.as_str().starts_with("simd_") => { + // Unpack non-power-of-2 #[repr(packed, simd)] arguments. + // This gives them the expected layout of a regular #[repr(simd)] vector. + let mut loaded_args = Vec::new(); + for (ty, arg) in arg_tys.iter().zip(args) { + loaded_args.push( + // #[repr(packed, simd)] vectors are passed like arrays (as references, + // with reduced alignment and no padding) rather than as immediates. + // We can use a vector load to fix the layout and turn the argument + // into an immediate. + if ty.is_simd() + && let OperandValue::Ref(place) = arg.val + { + let (size, elem_ty) = ty.simd_size_and_type(self.tcx()); + let elem_ll_ty = match elem_ty.kind() { + ty::Float(f) => self.type_float_from_ty(*f), + ty::Int(i) => self.type_int_from_ty(*i), + ty::Uint(u) => self.type_uint_from_ty(*u), + ty::RawPtr(_, _) => self.type_ptr(), + _ => unreachable!(), + }; + let loaded = + self.load_from_place(self.type_vector(elem_ll_ty, size), place); + OperandRef::from_immediate_or_packed_pair(self, loaded, arg.layout) + } else { + *arg + }, + ); + } + + let llret_ty = if ret_ty.is_simd() + && let abi::Abi::Aggregate { .. } = self.layout_of(ret_ty).layout.abi + { + let (size, elem_ty) = ret_ty.simd_size_and_type(self.tcx()); + let elem_ll_ty = match elem_ty.kind() { + ty::Float(f) => self.type_float_from_ty(*f), + ty::Int(i) => self.type_int_from_ty(*i), + ty::Uint(u) => self.type_uint_from_ty(*u), + ty::RawPtr(_, _) => self.type_ptr(), + _ => unreachable!(), + }; + self.type_vector(elem_ll_ty, size) + } else { + llret_ty + }; + match generic_simd_intrinsic( - self, name, callee_ty, fn_args, args, ret_ty, llret_ty, span, + self, + name, + callee_ty, + fn_args, + &loaded_args, + ret_ty, + llret_ty, + span, ) { Ok(llval) => llval, Err(()) => return Ok(()), |
