@@ -480,8 +480,55 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
480480 }
481481
482482 _ if name. as_str ( ) . starts_with ( "simd_" ) => {
483+ // Unpack non-power-of-2 #[repr(packed)]
484+ let mut loaded_args = Vec :: new ( ) ;
485+ for ( ty, arg) in arg_tys. iter ( ) . zip ( args) {
486+ loaded_args. push (
487+ if ty. is_simd ( )
488+ && let OperandValue :: Ref ( place) = arg. val
489+ {
490+ let ( size, elem_ty) = ty. simd_size_and_type ( self . tcx ( ) ) ;
491+ let elem_ll_ty = match elem_ty. kind ( ) {
492+ ty:: Float ( f) => self . type_float_from_ty ( * f) ,
493+ ty:: Int ( i) => self . type_int_from_ty ( * i) ,
494+ ty:: Uint ( u) => self . type_uint_from_ty ( * u) ,
495+ ty:: RawPtr ( _, _) => self . type_ptr ( ) ,
496+ _ => unreachable ! ( ) ,
497+ } ;
498+ let loaded =
499+ self . load_from_place ( self . type_vector ( elem_ll_ty, size) , place) ;
500+ OperandRef :: from_immediate_or_packed_pair ( self , loaded, arg. layout )
501+ } else {
502+ * arg
503+ } ,
504+ ) ;
505+ }
506+
507+ let llret_ty = if ret_ty. is_simd ( )
508+ && let abi:: Abi :: Aggregate { .. } = self . layout_of ( ret_ty) . layout . abi
509+ {
510+ let ( size, elem_ty) = ret_ty. simd_size_and_type ( self . tcx ( ) ) ;
511+ let elem_ll_ty = match elem_ty. kind ( ) {
512+ ty:: Float ( f) => self . type_float_from_ty ( * f) ,
513+ ty:: Int ( i) => self . type_int_from_ty ( * i) ,
514+ ty:: Uint ( u) => self . type_uint_from_ty ( * u) ,
515+ ty:: RawPtr ( _, _) => self . type_ptr ( ) ,
516+ _ => unreachable ! ( ) ,
517+ } ;
518+ self . type_vector ( elem_ll_ty, size)
519+ } else {
520+ llret_ty
521+ } ;
522+
483523 match generic_simd_intrinsic (
484- self , name, callee_ty, fn_args, args, ret_ty, llret_ty, span,
524+ self ,
525+ name,
526+ callee_ty,
527+ fn_args,
528+ & loaded_args,
529+ ret_ty,
530+ llret_ty,
531+ span,
485532 ) {
486533 Ok ( llval) => llval,
487534 Err ( ( ) ) => return Ok ( ( ) ) ,
0 commit comments